From 214aea7e3be5fba465f6e1d4a75d82baf75dbb7e Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 24 Feb 2009 03:42:59 -0800 Subject: [PATCH] --- yaml --- r: 131938 b: refs/heads/master c: 044fad0dbb4e814c061916fe5a36851af2fd1135 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/.mailmap | 4 +- trunk/CREDITS | 1 + trunk/Documentation/ABI/testing/sysfs-bus-pci | 43 - .../ABI/testing/sysfs-firmware-memmap | 2 +- trunk/Documentation/DocBook/Makefile | 2 +- .../Documentation/DocBook/device-drivers.tmpl | 418 -- trunk/Documentation/DocBook/kernel-api.tmpl | 377 ++ trunk/Documentation/PCI/PCIEBUS-HOWTO.txt | 2 +- trunk/Documentation/cgroups/cgroups.txt | 6 +- trunk/Documentation/cgroups/cpusets.txt | 65 +- trunk/Documentation/cpu-freq/user-guide.txt | 16 + trunk/Documentation/driver-model/device.txt | 8 +- trunk/Documentation/dvb/README.flexcop | 205 + trunk/Documentation/dvb/technisat.txt | 34 +- trunk/Documentation/filesystems/sysfs-pci.txt | 13 +- trunk/Documentation/filesystems/sysfs.txt | 50 +- trunk/Documentation/filesystems/ubifs.txt | 7 + trunk/Documentation/hwmon/hpfall.c | 101 - trunk/Documentation/hwmon/lis3lv02d | 8 - trunk/Documentation/kernel-doc-nano-HOWTO.txt | 7 +- trunk/Documentation/kernel-parameters.txt | 14 +- trunk/Documentation/scsi/cxgb3i.txt | 11 +- trunk/Documentation/tracers/mmiotrace.txt | 6 +- trunk/MAINTAINERS | 56 +- trunk/Makefile | 4 +- trunk/README | 2 +- trunk/arch/alpha/include/asm/bug.h | 4 +- trunk/arch/alpha/kernel/process.c | 8 +- trunk/arch/alpha/kernel/smp.c | 12 +- .../arch/arm/configs/at91sam9260ek_defconfig | 2 +- .../arch/arm/configs/at91sam9261ek_defconfig | 2 +- .../arch/arm/configs/at91sam9263ek_defconfig | 2 +- trunk/arch/arm/configs/at91sam9rlek_defconfig | 2 +- trunk/arch/arm/configs/qil-a9260_defconfig | 2 +- trunk/arch/arm/kernel/elf.c | 4 +- trunk/arch/arm/kernel/entry-armv.S | 1 - trunk/arch/arm/kernel/entry-common.S | 2 +- trunk/arch/arm/kernel/irq.c | 2 +- trunk/arch/arm/kernel/machine_kexec.c | 4 +- trunk/arch/arm/mach-at91/at91cap9_devices.c | 2 +- .../arch/arm/mach-at91/at91sam9260_devices.c | 2 +- .../arch/arm/mach-at91/at91sam9261_devices.c | 2 +- .../arch/arm/mach-at91/at91sam9263_devices.c | 2 +- trunk/arch/arm/mach-at91/at91sam9rl_devices.c | 2 +- trunk/arch/arm/mach-at91/gpio.c | 15 +- trunk/arch/arm/mach-at91/include/mach/board.h | 1 - trunk/arch/arm/mach-davinci/board-evm.c | 6 +- trunk/arch/arm/mach-davinci/clock.c | 5 - trunk/arch/arm/mach-davinci/usb.c | 1 - .../arm/mach-ep93xx/include/mach/gesbc9312.h | 3 + .../arm/mach-ep93xx/include/mach/hardware.h | 1 + trunk/arch/arm/mach-kirkwood/irq.c | 2 +- trunk/arch/arm/mach-msm/board-halibut.c | 1 - trunk/arch/arm/mach-mv78xx0/irq.c | 2 +- trunk/arch/arm/mach-omap1/devices.c | 2 +- trunk/arch/arm/mach-omap1/mcbsp.c | 98 +- trunk/arch/arm/mach-omap2/clock.c | 16 +- trunk/arch/arm/mach-omap2/devices.c | 11 +- trunk/arch/arm/mach-omap2/id.c | 6 +- trunk/arch/arm/mach-omap2/irq.c | 1 - trunk/arch/arm/mach-omap2/mcbsp.c | 145 +- trunk/arch/arm/mach-omap2/sleep24xx.S | 3 +- trunk/arch/arm/mach-omap2/timer-gp.c | 3 +- trunk/arch/arm/mach-orion5x/irq.c | 2 +- trunk/arch/arm/mach-pxa/dma.c | 18 +- .../arm/mach-pxa/include/mach/regs-ac97.h | 2 - .../arch/arm/mach-pxa/include/mach/regs-ssp.h | 3 - trunk/arch/arm/mach-pxa/pxa300.c | 4 +- trunk/arch/arm/mach-pxa/pxa320.c | 2 +- trunk/arch/arm/mach-rpc/riscpc.c | 6 - trunk/arch/arm/mach-sa1100/generic.c | 2 +- trunk/arch/arm/mm/fault-armv.c | 5 +- trunk/arch/arm/mm/mmu.c | 3 +- trunk/arch/arm/plat-omap/devices.c | 7 +- trunk/arch/arm/plat-omap/dma.c | 5 +- trunk/arch/arm/plat-omap/include/mach/cpu.h | 1 - trunk/arch/arm/plat-omap/include/mach/mcbsp.h | 6 +- trunk/arch/arm/plat-omap/include/mach/mmc.h | 10 +- trunk/arch/arm/plat-omap/mcbsp.c | 52 +- trunk/arch/arm/plat-orion/gpio.c | 73 +- trunk/arch/arm/plat-orion/include/plat/gpio.h | 3 +- .../avr32/mach-at32ap/include/mach/board.h | 1 - trunk/arch/blackfin/Kconfig | 52 +- trunk/arch/blackfin/Makefile | 106 +- .../blackfin/configs/BF518F-EZBRD_defconfig | 9 +- .../blackfin/configs/BF526-EZBRD_defconfig | 2 +- .../blackfin/configs/BF527-EZKIT_defconfig | 2 +- .../blackfin/configs/BF533-EZKIT_defconfig | 2 +- .../blackfin/configs/BF533-STAMP_defconfig | 2 +- .../blackfin/configs/BF537-STAMP_defconfig | 2 +- .../blackfin/configs/BF538-EZKIT_defconfig | 2 +- .../blackfin/configs/BF548-EZKIT_defconfig | 2 +- .../blackfin/configs/BF561-EZKIT_defconfig | 2 +- .../arch/blackfin/configs/CM-BF527_defconfig | 445 +- trunk/arch/blackfin/include/asm/checksum.h | 34 +- trunk/arch/blackfin/include/asm/delay.h | 35 +- trunk/arch/blackfin/include/asm/gpio.h | 58 + trunk/arch/blackfin/include/asm/kgdb.h | 53 +- trunk/arch/blackfin/include/asm/mem_init.h | 2 +- trunk/arch/blackfin/include/asm/pda.h | 1 - trunk/arch/blackfin/include/asm/reboot.h | 2 +- trunk/arch/blackfin/kernel/Makefile | 2 - trunk/arch/blackfin/kernel/bfin_dma_5xx.c | 7 - trunk/arch/blackfin/kernel/bfin_gpio.c | 578 +- .../arch/blackfin/kernel/cplb-mpu/cplbinit.c | 4 +- .../arch/blackfin/kernel/cplb-nompu/cplbmgr.c | 12 +- trunk/arch/blackfin/kernel/irqchip.c | 8 +- trunk/arch/blackfin/kernel/reboot.c | 30 +- trunk/arch/blackfin/kernel/setup.c | 12 +- trunk/arch/blackfin/kernel/traps.c | 39 +- trunk/arch/blackfin/mach-bf518/boards/ezbrd.c | 59 +- .../mach-bf518/include/mach/portmux.h | 2 - .../blackfin/mach-bf527/boards/cm_bf527.c | 18 +- trunk/arch/blackfin/mach-bf527/boards/ezbrd.c | 18 +- trunk/arch/blackfin/mach-bf527/boards/ezkit.c | 18 +- .../mach-bf527/include/mach/portmux.h | 2 - .../blackfin/mach-bf533/boards/blackstamp.c | 4 + trunk/arch/blackfin/mach-bf533/boards/stamp.c | 4 + .../mach-bf533/include/mach/portmux.h | 5 +- .../blackfin/mach-bf537/boards/cm_bf537.c | 6 - .../mach-bf537/boards/generic_board.c | 12 +- .../blackfin/mach-bf537/boards/minotaur.c | 8 +- .../arch/blackfin/mach-bf537/boards/pnav10.c | 10 +- trunk/arch/blackfin/mach-bf537/boards/stamp.c | 14 +- .../blackfin/mach-bf537/boards/tcm_bf537.c | 10 +- .../mach-bf537/include/mach/portmux.h | 1 - .../mach-bf538/include/mach/portmux.h | 1 - trunk/arch/blackfin/mach-bf548/boards/ezkit.c | 4 + .../mach-bf548/include/mach/anomaly.h | 1 - .../blackfin/mach-bf548/include/mach/bf548.h | 12 - .../blackfin/mach-bf548/include/mach/gpio.h | 12 +- .../mach-bf548/include/mach/portmux.h | 1 - .../mach-bf561/include/mach/defBF561.h | 2 - .../mach-bf561/include/mach/portmux.h | 1 - trunk/arch/blackfin/mach-common/clocks-init.c | 3 +- trunk/arch/blackfin/mach-common/entry.S | 9 +- trunk/arch/blackfin/mach-common/head.S | 84 +- trunk/arch/blackfin/mach-common/interrupt.S | 2 +- .../arch/blackfin/mach-common/ints-priority.c | 11 +- trunk/arch/blackfin/mach-common/pm.c | 11 +- trunk/arch/frv/mm/dma-alloc.c | 2 +- trunk/arch/ia64/Kconfig | 18 +- trunk/arch/ia64/configs/xen_domu_defconfig | 1601 ------ trunk/arch/ia64/include/asm/kvm.h | 4 - trunk/arch/ia64/include/asm/mmzone.h | 4 + trunk/arch/ia64/include/asm/sn/bte.h | 2 +- trunk/arch/ia64/kernel/iosapic.c | 2 +- trunk/arch/ia64/kernel/smpboot.c | 5 +- trunk/arch/ia64/kernel/unwind.c | 2 +- trunk/arch/ia64/kvm/kvm-ia64.c | 4 - trunk/arch/ia64/kvm/process.c | 17 +- trunk/arch/ia64/mm/numa.c | 4 +- trunk/arch/ia64/sn/kernel/bte.c | 7 +- trunk/arch/ia64/sn/kernel/io_acpi_init.c | 2 +- trunk/arch/ia64/sn/kernel/io_init.c | 2 +- trunk/arch/ia64/xen/Kconfig | 3 +- trunk/arch/ia64/xen/xen_pv_ops.c | 4 +- trunk/arch/m68k/atari/ataints.c | 16 +- trunk/arch/m68k/atari/atakeyb.c | 4 +- trunk/arch/m68k/atari/config.c | 2 +- trunk/arch/m68k/atari/debug.c | 22 +- trunk/arch/m68k/atari/time.c | 8 +- trunk/arch/m68k/include/asm/atarihw.h | 4 +- trunk/arch/m68k/include/asm/atariints.h | 6 +- trunk/arch/mips/Kconfig | 9 +- trunk/arch/mips/alchemy/common/time.c | 6 +- trunk/arch/mips/include/asm/seccomp.h | 1 + trunk/arch/mips/include/asm/spinlock.h | 1 - trunk/arch/mips/kernel/irq.c | 1 + trunk/arch/mips/kernel/linux32.c | 69 +- trunk/arch/mips/kernel/scall32-o32.S | 4 +- trunk/arch/mips/kernel/scall64-64.S | 2 +- trunk/arch/mips/kernel/scall64-n32.S | 28 +- trunk/arch/mips/kernel/scall64-o32.S | 40 +- trunk/arch/mips/kernel/signal.c | 5 +- trunk/arch/mips/kernel/signal32.c | 28 +- trunk/arch/mips/kernel/syscall.c | 26 +- trunk/arch/mips/mm/cache.c | 5 +- trunk/arch/mn10300/Kconfig | 1 - trunk/arch/mn10300/unit-asb2305/pci.c | 2 +- trunk/arch/powerpc/boot/dts/mpc8313erdb.dts | 11 +- .../configs/83xx/mpc8313_rdb_defconfig | 2 +- trunk/arch/powerpc/include/asm/compat.h | 5 - trunk/arch/powerpc/include/asm/pgtable-4k.h | 2 +- trunk/arch/powerpc/include/asm/pgtable-64k.h | 2 +- .../arch/powerpc/include/asm/pgtable-ppc32.h | 3 +- trunk/arch/powerpc/include/asm/seccomp.h | 4 + trunk/arch/powerpc/kernel/align.c | 36 +- trunk/arch/powerpc/kernel/ftrace.c | 5 +- trunk/arch/powerpc/kernel/pci-common.c | 17 +- trunk/arch/powerpc/kvm/powerpc.c | 4 - trunk/arch/powerpc/lib/copyuser_64.S | 38 +- trunk/arch/powerpc/lib/memcpy_64.S | 26 +- trunk/arch/powerpc/lib/sstep.c | 2 - trunk/arch/powerpc/mm/fsl_booke_mmu.c | 4 +- trunk/arch/powerpc/mm/hash_low_32.S | 2 +- trunk/arch/powerpc/mm/numa.c | 5 +- trunk/arch/powerpc/mm/pgtable_32.c | 4 +- .../arch/powerpc/oprofile/cell/spu_profiler.c | 1 - .../powerpc/platforms/82xx/pq2ads-pci-pic.c | 2 +- trunk/arch/powerpc/platforms/ps3/mm.c | 2 +- .../platforms/pseries/hotplug-memory.c | 1 - trunk/arch/powerpc/sysdev/cpm2_pic.c | 2 +- trunk/arch/powerpc/sysdev/ipic.c | 2 +- trunk/arch/powerpc/sysdev/ppc4xx_pci.c | 17 - trunk/arch/s390/defconfig | 87 +- trunk/arch/s390/include/asm/cputime.h | 2 +- trunk/arch/s390/include/asm/lowcore.h | 4 +- trunk/arch/s390/include/asm/setup.h | 2 - trunk/arch/s390/kernel/irq.c | 2 - trunk/arch/s390/kernel/setup.c | 9 +- trunk/arch/s390/kvm/kvm-s390.c | 4 - trunk/arch/sh/boards/board-ap325rxa.c | 10 +- trunk/arch/sh/configs/ap325rxa_defconfig | 27 +- trunk/arch/sh/configs/migor_defconfig | 42 +- trunk/arch/sh/include/asm/mutex-llsc.h | 21 +- trunk/arch/sh/include/asm/syscall_32.h | 22 +- trunk/arch/sh/include/asm/syscall_64.h | 22 +- trunk/arch/sh/kernel/cpu/sh2a/clock-sh7201.c | 4 +- trunk/arch/sh/kernel/cpu/sh4/fpu.c | 2 +- trunk/arch/sh/kernel/setup.c | 8 +- trunk/arch/sh/kernel/signal_32.c | 4 +- trunk/arch/sh/kernel/signal_64.c | 4 +- trunk/arch/sh/lib/checksum.S | 69 +- trunk/arch/sparc/include/asm/compat.h | 5 - trunk/arch/sparc/include/asm/cpudata_64.h | 2 +- trunk/arch/sparc/include/asm/irq_64.h | 4 +- trunk/arch/sparc/include/asm/kdebug_64.h | 2 - trunk/arch/sparc/include/asm/nmi.h | 10 - trunk/arch/sparc/include/asm/pcr.h | 46 - trunk/arch/sparc/include/asm/pil.h | 1 - trunk/arch/sparc/include/asm/seccomp.h | 6 + trunk/arch/sparc/kernel/Makefile | 2 - trunk/arch/sparc/kernel/chmc.c | 1 - trunk/arch/sparc/kernel/cpu.c | 33 +- trunk/arch/sparc/kernel/head_64.S | 31 +- trunk/arch/sparc/kernel/irq_64.c | 68 +- trunk/arch/sparc/kernel/kernel.h | 1 - trunk/arch/sparc/kernel/nmi.c | 225 - trunk/arch/sparc/kernel/pcr.c | 158 - trunk/arch/sparc/kernel/process_64.c | 5 +- trunk/arch/sparc/kernel/setup_64.c | 2 - trunk/arch/sparc/kernel/ttable.S | 3 +- trunk/arch/sparc/lib/GENbzero.S | 6 +- trunk/arch/sparc/lib/GENcopy_from_user.S | 8 +- trunk/arch/sparc/lib/GENcopy_to_user.S | 8 +- trunk/arch/sparc/lib/NG2copy_from_user.S | 9 +- trunk/arch/sparc/lib/NG2copy_to_user.S | 9 +- trunk/arch/sparc/lib/NGbzero.S | 6 +- trunk/arch/sparc/lib/NGcopy_from_user.S | 9 +- trunk/arch/sparc/lib/NGcopy_to_user.S | 9 +- trunk/arch/sparc/lib/U1copy_from_user.S | 8 +- trunk/arch/sparc/lib/U1copy_to_user.S | 8 +- trunk/arch/sparc/lib/U3copy_from_user.S | 6 +- trunk/arch/sparc/lib/U3copy_to_user.S | 8 +- trunk/arch/sparc/lib/bzero.S | 6 +- trunk/arch/sparc/lib/copy_in_user.S | 61 +- trunk/arch/sparc/mm/fault_64.c | 44 +- trunk/arch/sparc/oprofile/init.c | 232 +- trunk/arch/um/drivers/vde_user.c | 6 +- trunk/arch/x86/Kconfig | 11 - trunk/arch/x86/Kconfig.cpu | 28 +- trunk/arch/x86/Kconfig.debug | 24 +- trunk/arch/x86/ia32/ia32entry.S | 8 +- trunk/arch/x86/include/asm/a.out-core.h | 4 +- trunk/arch/x86/include/asm/cpufeature.h | 1 - trunk/arch/x86/include/asm/iomap.h | 3 - trunk/arch/x86/include/asm/kvm.h | 7 - trunk/arch/x86/include/asm/math_emu.h | 29 +- trunk/arch/x86/include/asm/mmzone_32.h | 2 + trunk/arch/x86/include/asm/mmzone_64.h | 2 + trunk/arch/x86/include/asm/mpspec.h | 6 - trunk/arch/x86/include/asm/page.h | 1 + trunk/arch/x86/include/asm/paravirt.h | 18 +- trunk/arch/x86/include/asm/pgtable.h | 26 +- trunk/arch/x86/include/asm/processor.h | 2 +- trunk/arch/x86/include/asm/seccomp_32.h | 6 + trunk/arch/x86/include/asm/seccomp_64.h | 8 + trunk/arch/x86/include/asm/spinlock.h | 1 - trunk/arch/x86/include/asm/traps.h | 4 +- trunk/arch/x86/include/asm/xen/page.h | 2 +- trunk/arch/x86/kernel/acpi/boot.c | 23 - trunk/arch/x86/kernel/acpi/sleep.c | 4 +- trunk/arch/x86/kernel/acpi/wakeup_64.S | 30 +- trunk/arch/x86/kernel/apic.c | 4 +- trunk/arch/x86/kernel/apm_32.c | 4 - trunk/arch/x86/kernel/cpu/cpufreq/Kconfig | 11 + .../arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 40 +- trunk/arch/x86/kernel/cpu/intel.c | 3 - trunk/arch/x86/kernel/cpu/intel_cacheinfo.c | 15 - trunk/arch/x86/kernel/cpu/mcheck/mce_64.c | 7 +- trunk/arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 2 +- .../arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 4 +- trunk/arch/x86/kernel/entry_64.S | 1 - trunk/arch/x86/kernel/ftrace.c | 17 +- trunk/arch/x86/kernel/hpet.c | 14 +- trunk/arch/x86/kernel/i8237.c | 17 +- trunk/arch/x86/kernel/io_apic.c | 25 +- trunk/arch/x86/kernel/irqinit_32.c | 12 + trunk/arch/x86/kernel/olpc.c | 2 +- trunk/arch/x86/kernel/paravirt.c | 26 - trunk/arch/x86/kernel/process.c | 6 - trunk/arch/x86/kernel/process_32.c | 3 + trunk/arch/x86/kernel/process_64.c | 9 +- trunk/arch/x86/kernel/ptrace.c | 18 +- trunk/arch/x86/kernel/setup.c | 2 +- trunk/arch/x86/kernel/time_64.c | 2 +- trunk/arch/x86/kernel/traps.c | 25 +- trunk/arch/x86/kernel/vmi_32.c | 11 - trunk/arch/x86/kernel/vmiclock_32.c | 7 +- trunk/arch/x86/kvm/i8254.c | 2 +- trunk/arch/x86/kvm/irq.c | 7 + trunk/arch/x86/kvm/irq.h | 1 + trunk/arch/x86/kvm/lapic.c | 66 +- trunk/arch/x86/kvm/lapic.h | 2 + trunk/arch/x86/kvm/mmu.c | 9 +- trunk/arch/x86/kvm/svm.c | 1 + trunk/arch/x86/kvm/vmx.c | 5 +- trunk/arch/x86/kvm/x86.c | 10 +- trunk/arch/x86/mach-default/setup.c | 14 +- trunk/arch/x86/mach-voyager/setup.c | 14 +- trunk/arch/x86/mach-voyager/voyager_smp.c | 47 +- trunk/arch/x86/math-emu/fpu_entry.c | 6 +- trunk/arch/x86/math-emu/fpu_proto.h | 4 +- trunk/arch/x86/math-emu/fpu_system.h | 16 +- trunk/arch/x86/math-emu/get_address.c | 69 +- trunk/arch/x86/mm/fault.c | 8 +- trunk/arch/x86/mm/iomap_32.c | 18 - trunk/arch/x86/mm/ioremap.c | 19 + trunk/arch/x86/mm/numa_64.c | 2 +- trunk/arch/x86/mm/pageattr.c | 30 +- trunk/arch/x86/mm/pat.c | 83 +- trunk/arch/x86/xen/enlighten.c | 3 - trunk/arch/x86/xen/multicalls.h | 4 +- trunk/block/blk-merge.c | 94 +- trunk/block/blk-timeout.c | 9 +- trunk/block/blktrace.c | 2 +- trunk/block/bsg.c | 17 +- trunk/block/genhd.c | 24 - trunk/crypto/ahash.c | 2 +- trunk/crypto/algapi.c | 6 +- trunk/crypto/api.c | 20 +- trunk/crypto/lrw.c | 8 +- trunk/crypto/scatterwalk.c | 3 +- trunk/crypto/shash.c | 7 +- trunk/drivers/acpi/Kconfig | 10 +- trunk/drivers/acpi/Makefile | 2 +- trunk/drivers/acpi/acpica/tbutils.c | 7 +- trunk/drivers/acpi/acpica/uteval.c | 21 +- trunk/drivers/acpi/battery.c | 25 +- trunk/drivers/acpi/container.c | 5 +- trunk/drivers/acpi/dock.c | 14 +- trunk/drivers/acpi/ec.c | 11 +- trunk/drivers/acpi/glue.c | 8 +- trunk/drivers/acpi/osl.c | 54 +- trunk/drivers/acpi/pci_link.c | 2 +- trunk/drivers/acpi/processor_idle.c | 667 ++- trunk/drivers/acpi/processor_perflib.c | 105 + trunk/drivers/acpi/sleep.c | 53 +- trunk/drivers/acpi/tables.c | 7 +- trunk/drivers/acpi/video.c | 16 +- trunk/drivers/ata/ahci.c | 9 +- trunk/drivers/ata/libata-core.c | 96 +- trunk/drivers/ata/libata-eh.c | 87 +- trunk/drivers/ata/libata-pmp.c | 2 +- trunk/drivers/ata/libata-scsi.c | 1 - trunk/drivers/ata/libata-sff.c | 28 +- trunk/drivers/ata/libata.h | 4 +- trunk/drivers/ata/pata_amd.c | 76 +- trunk/drivers/ata/pata_it821x.c | 3 - trunk/drivers/ata/pata_legacy.c | 7 +- trunk/drivers/ata/pata_qdi.c | 2 +- trunk/drivers/ata/pata_via.c | 4 +- trunk/drivers/ata/sata_mv.c | 24 +- trunk/drivers/ata/sata_nv.c | 21 +- trunk/drivers/ata/sata_sil.c | 2 +- trunk/drivers/base/base.h | 2 + trunk/drivers/base/dd.c | 17 - trunk/drivers/base/power/main.c | 3 + trunk/drivers/base/sys.c | 7 +- trunk/drivers/block/aoe/aoe.h | 1 - trunk/drivers/block/aoe/aoenet.c | 2 - trunk/drivers/block/ataflop.c | 4 +- trunk/drivers/block/cciss.c | 219 - trunk/drivers/block/floppy.c | 79 +- trunk/drivers/block/nbd.c | 9 - trunk/drivers/block/paride/pg.c | 2 +- trunk/drivers/block/xen-blkfront.c | 30 +- trunk/drivers/char/Kconfig | 2 +- trunk/drivers/char/scc.h | 2 +- trunk/drivers/char/sx.c | 13 +- trunk/drivers/char/tpm/tpm_infineon.c | 4 +- trunk/drivers/cpufreq/cpufreq_ondemand.c | 47 +- trunk/drivers/dma/dmaengine.c | 2 - trunk/drivers/dma/dw_dmac.c | 5 +- trunk/drivers/dma/dw_dmac_regs.h | 2 + trunk/drivers/firewire/fw-card.c | 9 +- trunk/drivers/firmware/memmap.c | 2 +- trunk/drivers/gpu/drm/Kconfig | 15 +- trunk/drivers/gpu/drm/drm_crtc.c | 3 +- trunk/drivers/gpu/drm/drm_crtc_helper.c | 97 +- trunk/drivers/gpu/drm/drm_edid.c | 6 +- trunk/drivers/gpu/drm/drm_fops.c | 3 - trunk/drivers/gpu/drm/drm_gem.c | 79 +- trunk/drivers/gpu/drm/drm_irq.c | 15 +- trunk/drivers/gpu/drm/drm_memory.c | 7 +- trunk/drivers/gpu/drm/i915/i915_dma.c | 60 +- trunk/drivers/gpu/drm/i915/i915_drv.c | 30 +- trunk/drivers/gpu/drm/i915/i915_drv.h | 11 - trunk/drivers/gpu/drm/i915/i915_gem.c | 270 +- trunk/drivers/gpu/drm/i915/i915_gem_tiling.c | 97 +- trunk/drivers/gpu/drm/i915/i915_irq.c | 13 - trunk/drivers/gpu/drm/i915/i915_reg.h | 10 +- trunk/drivers/gpu/drm/i915/intel_bios.c | 14 - trunk/drivers/gpu/drm/i915/intel_display.c | 181 +- trunk/drivers/gpu/drm/i915/intel_drv.h | 1 - trunk/drivers/gpu/drm/i915/intel_fb.c | 8 +- trunk/drivers/gpu/drm/i915/intel_lvds.c | 51 +- trunk/drivers/gpu/drm/i915/intel_sdvo.c | 872 +-- trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h | 404 +- trunk/drivers/gpu/drm/i915/intel_tv.c | 2 +- trunk/drivers/gpu/drm/radeon/radeon_cp.c | 27 +- trunk/drivers/hid/hid-core.c | 13 +- trunk/drivers/hid/hid-ids.h | 3 - trunk/drivers/hid/hidraw.c | 14 +- trunk/drivers/hwmon/f71882fg.c | 4 +- trunk/drivers/hwmon/hp_accel.c | 94 +- trunk/drivers/hwmon/lis3lv02d.c | 195 +- trunk/drivers/hwmon/lis3lv02d.h | 21 +- trunk/drivers/hwmon/vt1211.c | 2 +- trunk/drivers/hwmon/w83627ehf.c | 2 +- trunk/drivers/i2c/busses/i2c-acorn.c | 5 +- trunk/drivers/i2c/busses/i2c-amd8111.c | 4 +- trunk/drivers/i2c/busses/i2c-ixp2000.c | 2 +- trunk/drivers/i2c/busses/i2c-pxa.c | 2 +- trunk/drivers/i2c/busses/scx200_i2c.c | 2 +- trunk/drivers/i2c/i2c-core.c | 3 +- trunk/drivers/i2c/i2c-dev.c | 6 +- trunk/drivers/ide/Kconfig | 2 +- trunk/drivers/ide/amd74xx.c | 2 +- trunk/drivers/ide/atiixp.c | 4 +- trunk/drivers/ide/ide-cd.c | 35 +- trunk/drivers/ide/ide-cd.h | 2 +- trunk/drivers/ide/ide-gd.c | 26 +- trunk/drivers/ide/ide-gd.h | 2 +- trunk/drivers/ide/ide-tape.c | 29 +- trunk/drivers/ide/ide.c | 11 +- trunk/drivers/ide/it821x.c | 5 +- trunk/drivers/ide/qd65xx.c | 2 +- trunk/drivers/ide/qd65xx.h | 2 +- trunk/drivers/ieee1394/dma.h | 1 - trunk/drivers/ieee1394/dv1394.c | 8 +- trunk/drivers/ieee1394/ieee1394_core.c | 3 +- .../drivers/ieee1394/ieee1394_transactions.c | 31 +- .../drivers/ieee1394/ieee1394_transactions.h | 2 - trunk/drivers/ieee1394/iso.h | 1 - trunk/drivers/ieee1394/nodemgr.c | 10 +- trunk/drivers/ieee1394/nodemgr.h | 18 - trunk/drivers/input/keyboard/atkbd.c | 4 +- trunk/drivers/input/keyboard/bf54x-keys.c | 4 +- trunk/drivers/input/keyboard/corgikbd.c | 8 +- trunk/drivers/input/keyboard/omap-keypad.c | 8 +- trunk/drivers/input/keyboard/spitzkbd.c | 8 +- trunk/drivers/input/mouse/Kconfig | 2 +- trunk/drivers/input/mouse/elantech.c | 32 +- trunk/drivers/input/mouse/pxa930_trkball.c | 2 +- trunk/drivers/input/mouse/synaptics.c | 9 +- trunk/drivers/input/serio/ambakmi.c | 6 +- trunk/drivers/input/serio/gscps2.c | 2 +- trunk/drivers/input/serio/sa1111ps2.c | 4 +- .../drivers/input/touchscreen/atmel_tsadcc.c | 2 +- trunk/drivers/input/touchscreen/corgi_ts.c | 9 +- trunk/drivers/input/touchscreen/tsc2007.c | 3 +- .../input/touchscreen/usbtouchscreen.c | 20 +- trunk/drivers/md/dm-io.c | 2 +- trunk/drivers/md/dm-kcopyd.c | 2 +- trunk/drivers/md/linear.c | 6 +- trunk/drivers/md/md.c | 28 +- trunk/drivers/md/raid1.c | 6 +- trunk/drivers/md/raid10.c | 19 +- .../media/common/tuners/tuner-simple.c | 10 +- trunk/drivers/media/dvb/Kconfig | 4 - trunk/drivers/media/dvb/Makefile | 2 - .../media/dvb/b2c2/flexcop-hw-filter.c | 1 - trunk/drivers/media/dvb/b2c2/flexcop-pci.c | 65 +- trunk/drivers/media/dvb/b2c2/flexcop.c | 3 +- trunk/drivers/media/dvb/dvb-core/dmxdev.c | 16 +- trunk/drivers/media/dvb/dvb-core/dvb_demux.c | 16 +- trunk/drivers/media/dvb/firewire/Kconfig | 22 - trunk/drivers/media/dvb/firewire/Makefile | 8 - .../drivers/media/dvb/firewire/firedtv-1394.c | 285 - .../drivers/media/dvb/firewire/firedtv-avc.c | 1315 ----- trunk/drivers/media/dvb/firewire/firedtv-ci.c | 260 - .../drivers/media/dvb/firewire/firedtv-dvb.c | 364 -- trunk/drivers/media/dvb/firewire/firedtv-fe.c | 247 - trunk/drivers/media/dvb/firewire/firedtv-rc.c | 190 - trunk/drivers/media/dvb/firewire/firedtv.h | 182 - trunk/drivers/media/radio/radio-si470x.c | 55 +- .../drivers/media/video/em28xx/em28xx-audio.c | 2 - trunk/drivers/media/video/gspca/gspca.c | 5 - trunk/drivers/media/video/ivtv/ivtv-ioctl.c | 26 +- trunk/drivers/media/video/pxa_camera.c | 26 +- .../media/video/sh_mobile_ceu_camera.c | 13 +- trunk/drivers/media/video/uvc/uvc_status.c | 10 +- trunk/drivers/message/fusion/mptbase.c | 4 +- trunk/drivers/mfd/htc-egpio.c | 4 +- trunk/drivers/mfd/pcf50633-core.c | 2 +- trunk/drivers/mfd/sm501.c | 26 +- trunk/drivers/mfd/twl4030-core.c | 2 +- trunk/drivers/mfd/wm8350-core.c | 48 +- trunk/drivers/mfd/wm8350-regmap.c | 2 +- trunk/drivers/misc/Kconfig | 1 - trunk/drivers/misc/atmel-ssc.c | 2 +- trunk/drivers/misc/hpilo.c | 9 +- trunk/drivers/misc/hpilo.h | 2 - trunk/drivers/misc/sgi-xp/xpc.h | 5 +- trunk/drivers/misc/sgi-xp/xpc_uv.c | 11 +- trunk/drivers/mmc/card/block.c | 2 +- trunk/drivers/mmc/card/mmc_test.c | 2 +- trunk/drivers/mmc/host/atmel-mci.c | 5 +- trunk/drivers/mmc/host/omap_hsmmc.c | 98 +- trunk/drivers/mmc/host/s3cmci.c | 2 +- trunk/drivers/mmc/host/sdhci-pci.c | 3 +- trunk/drivers/mmc/host/sdhci.c | 7 +- trunk/drivers/mmc/host/sdhci.h | 3 +- trunk/drivers/mtd/chips/map_rom.c | 8 - trunk/drivers/mtd/devices/slram.c | 14 +- trunk/drivers/mtd/lpddr/Kconfig | 1 - trunk/drivers/mtd/maps/Kconfig | 2 +- trunk/drivers/mtd/maps/bfin-async-flash.c | 6 +- trunk/drivers/mtd/maps/ck804xrom.c | 2 +- trunk/drivers/mtd/maps/physmap.c | 38 +- trunk/drivers/mtd/maps/sa1100-flash.c | 4 +- trunk/drivers/mtd/nand/atmel_nand.c | 3 +- trunk/drivers/net/arm/etherh.c | 2 +- trunk/drivers/net/netxen/netxen_nic_main.c | 9 +- trunk/drivers/net/wireless/iwlwifi/iwl-tx.c | 8 +- trunk/drivers/parport/parport_atari.c | 6 +- trunk/drivers/parport/parport_serial.c | 5 - trunk/drivers/pci/dmar.c | 73 +- trunk/drivers/pci/hotplug/pciehp.h | 2 - trunk/drivers/pci/hotplug/pciehp_core.c | 7 - trunk/drivers/pci/hotplug/pciehp_hpc.c | 15 +- trunk/drivers/pci/intel-iommu.c | 30 +- trunk/drivers/pci/intr_remapping.c | 21 +- trunk/drivers/pci/msi.c | 10 +- trunk/drivers/pci/pci-driver.c | 164 +- trunk/drivers/pci/pci-sysfs.c | 4 +- trunk/drivers/pci/pci.c | 17 +- trunk/drivers/pci/pci.h | 20 +- trunk/drivers/pci/pcie/aer/aerdrv_core.c | 48 +- trunk/drivers/pci/pcie/aspm.c | 4 +- trunk/drivers/pci/pcie/portdrv_pci.c | 18 +- trunk/drivers/pci/quirks.c | 122 +- trunk/drivers/pci/rom.c | 9 +- trunk/drivers/platform/x86/Kconfig | 3 - trunk/drivers/platform/x86/asus-laptop.c | 176 +- trunk/drivers/platform/x86/asus_acpi.c | 16 +- trunk/drivers/platform/x86/eeepc-laptop.c | 164 +- trunk/drivers/platform/x86/fujitsu-laptop.c | 25 +- trunk/drivers/platform/x86/hp-wmi.c | 6 +- trunk/drivers/platform/x86/panasonic-laptop.c | 2 +- trunk/drivers/power/pcf50633-charger.c | 3 +- trunk/drivers/rtc/Kconfig | 6 - trunk/drivers/rtc/Makefile | 1 - trunk/drivers/rtc/rtc-au1xxx.c | 2 +- trunk/drivers/rtc/rtc-dm355evm.c | 175 - trunk/drivers/rtc/rtc-ds1390.c | 1 + trunk/drivers/rtc/rtc-pxa.c | 2 +- trunk/drivers/s390/block/dasd.c | 46 +- trunk/drivers/s390/block/dasd_devmap.c | 2 +- trunk/drivers/s390/char/sclp.c | 5 +- trunk/drivers/s390/char/sclp_cmd.c | 5 - trunk/drivers/scsi/cxgb3i/cxgb3i.h | 21 - trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.c | 19 +- trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.h | 5 +- trunk/drivers/scsi/cxgb3i/cxgb3i_init.c | 4 +- trunk/drivers/scsi/cxgb3i/cxgb3i_iscsi.c | 22 +- trunk/drivers/scsi/cxgb3i/cxgb3i_offload.c | 146 +- trunk/drivers/scsi/cxgb3i/cxgb3i_offload.h | 29 +- trunk/drivers/scsi/cxgb3i/cxgb3i_pdu.c | 275 +- trunk/drivers/scsi/cxgb3i/cxgb3i_pdu.h | 2 +- trunk/drivers/scsi/hptiop.c | 1 - trunk/drivers/scsi/ibmvscsi/ibmvfc.c | 15 +- trunk/drivers/scsi/ibmvscsi/ibmvfc.h | 2 +- trunk/drivers/scsi/ibmvscsi/ibmvscsi.c | 1 - trunk/drivers/scsi/libiscsi.c | 3 +- trunk/drivers/scsi/lpfc/lpfc_els.c | 1 - trunk/drivers/scsi/qla2xxx/qla_attr.c | 13 +- trunk/drivers/scsi/qla2xxx/qla_def.h | 5 - trunk/drivers/scsi/qla2xxx/qla_devtbl.h | 2 +- trunk/drivers/scsi/qla2xxx/qla_fw.h | 2 - trunk/drivers/scsi/qla2xxx/qla_gbl.h | 9 +- trunk/drivers/scsi/qla2xxx/qla_init.c | 7 +- trunk/drivers/scsi/qla2xxx/qla_isr.c | 58 +- trunk/drivers/scsi/qla2xxx/qla_mbx.c | 40 +- trunk/drivers/scsi/qla2xxx/qla_mid.c | 12 +- trunk/drivers/scsi/qla2xxx/qla_os.c | 16 - trunk/drivers/scsi/qla2xxx/qla_sup.c | 2 +- trunk/drivers/scsi/qla2xxx/qla_version.h | 2 +- trunk/drivers/scsi/scsi_lib.c | 5 +- trunk/drivers/scsi/scsi_scan.c | 1 - trunk/drivers/scsi/sd.c | 7 - trunk/drivers/scsi/sg.c | 2 +- trunk/drivers/serial/8250.c | 15 - trunk/drivers/serial/8250_pci.c | 36 - trunk/drivers/serial/atmel_serial.c | 4 - trunk/drivers/serial/jsm/jsm_driver.c | 3 - trunk/drivers/serial/sh-sci.h | 2 +- trunk/drivers/spi/spi_gpio.c | 2 +- trunk/drivers/staging/android/Kconfig | 1 - trunk/drivers/staging/android/ram_console.c | 14 - trunk/drivers/staging/android/timed_gpio.c | 2 +- trunk/drivers/staging/at76_usb/Kconfig | 2 +- trunk/drivers/staging/at76_usb/at76_usb.c | 4754 ++++------------- trunk/drivers/staging/at76_usb/at76_usb.h | 227 +- trunk/drivers/staging/panel/panel.c | 33 +- trunk/drivers/staging/rtl8187se/Kconfig | 1 - .../rtl8187se/ieee80211/ieee80211_crypt.c | 19 +- trunk/drivers/staging/rtl8187se/r8180_core.c | 2 +- trunk/drivers/staging/winbond/wbusb.c | 20 +- trunk/drivers/usb/Makefile | 1 - trunk/drivers/usb/class/cdc-acm.c | 12 +- trunk/drivers/usb/core/hcd-pci.c | 15 +- trunk/drivers/usb/core/hcd.h | 1 + trunk/drivers/usb/core/message.c | 11 +- trunk/drivers/usb/gadget/Kconfig | 1 - trunk/drivers/usb/gadget/f_obex.c | 4 +- trunk/drivers/usb/gadget/file_storage.c | 6 +- trunk/drivers/usb/gadget/fsl_qe_udc.c | 46 +- trunk/drivers/usb/gadget/fsl_usb2_udc.c | 3 - trunk/drivers/usb/gadget/pxa25x_udc.c | 4 +- trunk/drivers/usb/host/ehci-hcd.c | 2 - trunk/drivers/usb/host/ehci-mem.c | 1 - trunk/drivers/usb/host/ehci-pci.c | 1 + trunk/drivers/usb/host/ehci-sched.c | 56 +- trunk/drivers/usb/host/ehci.h | 6 - trunk/drivers/usb/host/ohci-pci.c | 1 + trunk/drivers/usb/host/uhci-hcd.c | 1 + trunk/drivers/usb/host/whci/asl.c | 4 +- trunk/drivers/usb/host/whci/pzl.c | 4 +- trunk/drivers/usb/musb/davinci.c | 15 +- trunk/drivers/usb/musb/musb_core.c | 13 +- trunk/drivers/usb/musb/musb_gadget.c | 4 +- trunk/drivers/usb/musb/musb_host.c | 93 +- trunk/drivers/usb/serial/aircable.c | 4 +- trunk/drivers/usb/serial/ftdi_sio.c | 5 +- trunk/drivers/usb/serial/ftdi_sio.h | 3 - trunk/drivers/usb/serial/option.c | 102 +- trunk/drivers/usb/serial/ti_usb_3410_5052.c | 10 +- trunk/drivers/usb/serial/ti_usb_3410_5052.h | 2 - trunk/drivers/usb/storage/scsiglue.c | 2 - trunk/drivers/usb/storage/transport.c | 36 +- trunk/drivers/usb/storage/unusual_devs.h | 21 +- trunk/drivers/video/Kconfig | 8 +- trunk/drivers/video/atafb.c | 22 +- trunk/drivers/video/aty/aty128fb.c | 34 +- trunk/drivers/video/aty/atyfb_base.c | 42 +- trunk/drivers/video/aty/radeon_base.c | 10 +- trunk/drivers/video/aty/radeon_pm.c | 103 +- trunk/drivers/video/aty/radeonfb.h | 2 + trunk/drivers/video/backlight/Makefile | 2 +- .../video/backlight/{da903x_bl.c => da903x.c} | 0 trunk/drivers/video/bfin-t350mcqb-fb.c | 2 +- trunk/drivers/video/fbcmap.c | 20 +- trunk/drivers/video/fbmem.c | 135 +- trunk/drivers/video/geode/gx1fb_core.c | 17 +- trunk/drivers/video/geode/gxfb_core.c | 17 +- trunk/drivers/video/geode/lxfb_core.c | 17 +- trunk/drivers/w1/slaves/Kconfig | 6 - trunk/drivers/w1/slaves/Makefile | 1 - trunk/drivers/w1/slaves/w1_ds2433.c | 7 +- trunk/drivers/w1/slaves/w1_therm.c | 2 +- trunk/drivers/watchdog/Kconfig | 2 +- trunk/drivers/watchdog/at91rm9200_wdt.c | 4 +- trunk/drivers/watchdog/at91sam9_wdt.c | 1 - trunk/drivers/watchdog/iTCO_vendor_support.c | 32 +- trunk/drivers/watchdog/iTCO_wdt.c | 35 +- trunk/drivers/xen/manage.c | 8 - trunk/fs/Makefile | 6 +- trunk/fs/binfmt_elf.c | 14 +- trunk/fs/bio.c | 5 +- trunk/fs/btrfs/Kconfig | 13 - trunk/fs/btrfs/async-thread.c | 61 +- trunk/fs/btrfs/btrfs_inode.h | 8 - trunk/fs/btrfs/compression.c | 1 + trunk/fs/btrfs/ctree.c | 315 +- trunk/fs/btrfs/ctree.h | 77 +- trunk/fs/btrfs/disk-io.c | 166 +- trunk/fs/btrfs/disk-io.h | 12 - trunk/fs/btrfs/extent-tree.c | 771 +-- trunk/fs/btrfs/extent_io.c | 134 +- trunk/fs/btrfs/extent_io.h | 18 +- trunk/fs/btrfs/extent_map.c | 1 + trunk/fs/btrfs/file.c | 29 +- trunk/fs/btrfs/inode-map.c | 1 + trunk/fs/btrfs/inode.c | 142 +- trunk/fs/btrfs/ioctl.c | 7 +- trunk/fs/btrfs/locking.c | 207 +- trunk/fs/btrfs/locking.h | 6 +- trunk/fs/btrfs/ordered-data.c | 4 +- trunk/fs/btrfs/ref-cache.c | 1 - trunk/fs/btrfs/ref-cache.h | 1 + trunk/fs/btrfs/super.c | 11 +- trunk/fs/btrfs/transaction.c | 6 +- trunk/fs/btrfs/tree-defrag.c | 1 - trunk/fs/btrfs/tree-log.c | 356 +- trunk/fs/btrfs/volumes.c | 55 +- trunk/fs/btrfs/xattr.c | 48 +- trunk/fs/btrfs/xattr.h | 2 - trunk/fs/buffer.c | 5 +- trunk/fs/cifs/CHANGES | 15 +- trunk/fs/cifs/cifsfs.h | 2 +- trunk/fs/cifs/cifsglob.h | 6 +- trunk/fs/cifs/cifsproto.h | 4 - trunk/fs/cifs/cifssmb.c | 7 +- trunk/fs/cifs/connect.c | 51 +- trunk/fs/cifs/dir.c | 307 +- trunk/fs/cifs/inode.c | 104 +- trunk/fs/cifs/readdir.c | 58 +- trunk/fs/cifs/sess.c | 91 +- trunk/fs/compat.c | 2 +- trunk/fs/compat_ioctl.c | 7 +- trunk/fs/dcache.c | 2 +- trunk/fs/ecryptfs/crypto.c | 4 +- trunk/fs/exec.c | 28 +- trunk/fs/ext2/super.c | 9 +- trunk/fs/ext3/super.c | 11 +- trunk/fs/ext4/balloc.c | 4 +- trunk/fs/ext4/ext4.h | 2 +- trunk/fs/ext4/ialloc.c | 7 - trunk/fs/ext4/inode.c | 38 +- trunk/fs/ext4/mballoc.c | 32 +- trunk/fs/ext4/migrate.c | 8 +- trunk/fs/ext4/super.c | 12 +- trunk/fs/hugetlbfs/inode.c | 8 +- trunk/fs/internal.h | 2 +- trunk/fs/jbd/journal.c | 17 +- trunk/fs/jbd2/journal.c | 17 +- trunk/fs/jbd2/transaction.c | 42 +- trunk/fs/jffs2/background.c | 18 +- trunk/fs/jffs2/readinode.c | 42 +- trunk/fs/lockd/svclock.c | 6 +- trunk/fs/namespace.c | 6 +- trunk/fs/notify/inotify/inotify.c | 2 +- trunk/fs/ocfs2/alloc.c | 30 +- trunk/fs/ocfs2/dcache.c | 42 +- trunk/fs/ocfs2/dcache.h | 9 +- trunk/fs/ocfs2/dlm/dlmmaster.c | 12 +- trunk/fs/ocfs2/dlm/dlmthread.c | 3 +- trunk/fs/ocfs2/dlm/dlmunlock.c | 4 +- trunk/fs/ocfs2/dlmglue.c | 15 +- trunk/fs/ocfs2/journal.h | 6 +- trunk/fs/ocfs2/ocfs2.h | 9 - trunk/fs/ocfs2/quota_global.c | 4 +- trunk/fs/ocfs2/super.c | 11 - trunk/fs/ocfs2/xattr.c | 44 +- trunk/fs/proc/inode.c | 4 +- trunk/fs/proc/page.c | 2 +- trunk/fs/seq_file.c | 151 +- trunk/fs/super.c | 21 +- trunk/fs/timerfd.c | 12 +- trunk/fs/ubifs/budget.c | 35 +- trunk/fs/ubifs/debug.c | 122 +- trunk/fs/ubifs/debug.h | 36 +- trunk/fs/ubifs/dir.c | 96 +- trunk/fs/ubifs/file.c | 9 +- trunk/fs/ubifs/gc.c | 28 +- trunk/fs/ubifs/io.c | 22 +- trunk/fs/ubifs/journal.c | 2 +- trunk/fs/ubifs/lprops.c | 12 +- trunk/fs/ubifs/lpt_commit.c | 44 +- trunk/fs/ubifs/master.c | 2 +- trunk/fs/ubifs/orphan.c | 38 +- trunk/fs/ubifs/super.c | 195 +- trunk/fs/ubifs/tnc.c | 12 +- trunk/fs/ubifs/ubifs.h | 26 +- trunk/fs/xfs/linux-2.6/xfs_buf.c | 79 +- trunk/fs/xfs/linux-2.6/xfs_sync.c | 6 +- trunk/fs/xfs/xfs_dfrag.c | 10 +- trunk/fs/xfs/xfs_log_recover.c | 31 +- trunk/include/acpi/pdc_intel.h | 2 - trunk/include/asm-frv/pgtable.h | 2 +- trunk/include/crypto/hash.h | 2 +- trunk/include/drm/drmP.h | 2 - trunk/include/drm/drm_crtc.h | 2 +- trunk/include/drm/drm_crtc_helper.h | 11 +- trunk/include/drm/drm_edid.h | 4 +- trunk/include/drm/i915_drm.h | 2 - trunk/include/linux/async.h | 8 +- trunk/include/linux/ata.h | 15 +- trunk/include/linux/bio.h | 2 + trunk/include/linux/blkdev.h | 2 - trunk/include/linux/blktrace_api.h | 1 - trunk/include/linux/cgroup.h | 1 - trunk/include/linux/crypto.h | 7 +- trunk/include/linux/device.h | 2 - trunk/include/linux/dmaengine.h | 2 - trunk/include/linux/fb.h | 15 - trunk/include/linux/firmware-map.h | 2 +- trunk/include/linux/fs.h | 24 +- trunk/include/linux/hugetlb.h | 11 +- trunk/include/linux/i2c-dev.h | 2 +- trunk/include/linux/i2c.h | 2 +- trunk/include/linux/ide.h | 2 +- trunk/include/linux/init_task.h | 11 +- trunk/include/linux/intel-iommu.h | 3 +- trunk/include/linux/io-mapping.h | 46 +- trunk/include/linux/jbd2.h | 3 +- trunk/include/linux/kernel.h | 3 +- trunk/include/linux/kvm.h | 10 +- trunk/include/linux/kvm_host.h | 1 - trunk/include/linux/libata.h | 19 +- trunk/include/linux/mm.h | 24 +- trunk/include/linux/mmzone.h | 2 +- trunk/include/linux/module.h | 1 + trunk/include/linux/pci.h | 2 +- trunk/include/linux/pci_ids.h | 5 - trunk/include/linux/pm.h | 2 - trunk/include/linux/sched.h | 63 +- trunk/include/linux/seq_file.h | 1 - trunk/include/linux/serial_core.h | 1 - trunk/include/linux/slab.h | 1 - trunk/include/linux/soundcard.h | 74 +- trunk/include/linux/spi/spi_bitbang.h | 7 - trunk/include/linux/spinlock.h | 5 - trunk/include/linux/syscalls.h | 28 +- trunk/include/linux/timerfd.h | 16 +- trunk/include/linux/user_namespace.h | 1 - trunk/include/linux/vmalloc.h | 4 - trunk/include/linux/wait.h | 11 +- trunk/include/video/aty128.h | 4 +- trunk/include/video/mach64.h | 24 +- trunk/include/video/radeon.h | 18 +- trunk/init/do_mounts.c | 13 +- trunk/init/do_mounts_md.c | 5 +- trunk/ipc/shm.c | 12 +- trunk/kernel/Makefile | 1 - trunk/kernel/async.c | 94 +- trunk/kernel/cgroup.c | 5 +- trunk/kernel/exit.c | 3 - trunk/kernel/fork.c | 6 +- trunk/kernel/futex.c | 53 +- trunk/kernel/irq/numa_migrate.c | 7 +- trunk/kernel/itimer.c | 4 +- trunk/kernel/kexec.c | 7 - trunk/kernel/posix-cpu-timers.c | 123 +- trunk/kernel/power/Makefile | 2 +- trunk/kernel/power/console.c | 6 - trunk/kernel/power/disk.c | 22 - trunk/kernel/power/main.c | 34 +- trunk/kernel/power/swap.c | 5 +- trunk/kernel/power/user.c | 8 +- trunk/kernel/printk.c | 15 +- trunk/kernel/profile.c | 3 - trunk/kernel/sched.c | 46 +- trunk/kernel/sched_fair.c | 11 +- trunk/kernel/sched_stats.h | 45 +- trunk/kernel/seccomp.c | 7 +- trunk/kernel/signal.c | 8 +- trunk/kernel/sys.c | 16 +- trunk/kernel/sysctl.c | 5 +- trunk/kernel/trace/Kconfig | 25 - trunk/kernel/trace/ftrace.c | 11 +- trunk/kernel/trace/trace_mmiotrace.c | 14 +- trunk/kernel/trace/trace_selftest.c | 19 - trunk/kernel/user.c | 3 +- trunk/kernel/user_namespace.c | 21 +- trunk/kernel/wait.c | 59 +- trunk/lib/Kconfig.debug | 2 +- trunk/mm/fremap.c | 2 +- trunk/mm/hugetlb.c | 28 +- trunk/mm/memory.c | 2 +- trunk/mm/migrate.c | 2 +- trunk/mm/mlock.c | 12 +- trunk/mm/mmap.c | 48 +- trunk/mm/mprotect.c | 5 +- trunk/mm/page-writeback.c | 35 +- trunk/mm/page_alloc.c | 27 +- trunk/mm/page_cgroup.c | 3 +- trunk/mm/page_io.c | 2 +- trunk/mm/rmap.c | 3 +- trunk/mm/shmem.c | 43 +- trunk/mm/slab.c | 1 - trunk/mm/slob.c | 1 - trunk/mm/slub.c | 1 - trunk/mm/swapfile.c | 4 +- trunk/mm/util.c | 20 - trunk/mm/vmalloc.c | 20 +- trunk/mm/vmscan.c | 28 +- trunk/net/ipv4/cipso_ipv4.c | 9 +- trunk/scripts/bootgraph.pl | 4 +- trunk/scripts/checkpatch.pl | 26 +- trunk/scripts/kernel-doc | 40 +- trunk/scripts/markup_oops.pl | 161 +- trunk/scripts/mod/file2alias.c | 1 - trunk/scripts/package/mkspec | 8 - trunk/scripts/setlocalversion | 9 +- trunk/scripts/tags.sh | 12 +- trunk/security/selinux/netlabel.c | 9 +- trunk/sound/arm/aaci.c | 6 +- trunk/sound/core/jack.c | 2 +- trunk/sound/core/oss/pcm_oss.c | 2 +- trunk/sound/core/oss/rate.c | 2 +- trunk/sound/drivers/mtpav.c | 3 +- trunk/sound/oss/dmasound/dmasound_atari.c | 16 +- trunk/sound/pci/aw2/aw2-alsa.c | 2 +- trunk/sound/pci/emu10k1/emu10k1_main.c | 1 - trunk/sound/pci/hda/hda_codec.c | 19 +- trunk/sound/pci/hda/hda_codec.h | 1 - trunk/sound/pci/hda/hda_hwdep.c | 17 +- trunk/sound/pci/hda/hda_intel.c | 8 +- trunk/sound/pci/hda/hda_local.h | 2 - trunk/sound/pci/hda/hda_proc.c | 3 +- trunk/sound/pci/hda/patch_analog.c | 15 +- trunk/sound/pci/hda/patch_intelhdmi.c | 61 +- trunk/sound/pci/hda/patch_realtek.c | 9 - trunk/sound/pci/hda/patch_sigmatel.c | 15 +- trunk/sound/pci/intel8x0.c | 2 +- trunk/sound/pci/oxygen/virtuoso.c | 17 +- trunk/sound/pci/pcxhr/pcxhr.h | 12 +- trunk/sound/soc/atmel/atmel_ssc_dai.c | 2 +- trunk/sound/soc/atmel/atmel_ssc_dai.h | 2 +- trunk/sound/soc/codecs/tlv320aic3x.c | 11 +- trunk/sound/soc/codecs/wm8350.c | 2 +- trunk/sound/soc/codecs/wm8990.c | 7 +- trunk/sound/soc/omap/omap-pcm.c | 5 +- trunk/sound/soc/omap/sdp3430.c | 4 +- trunk/sound/soc/soc-core.c | 5 +- trunk/sound/usb/usbaudio.c | 21 +- trunk/sound/usb/usbmidi.c | 1 - trunk/virt/kvm/iommu.c | 6 +- trunk/virt/kvm/kvm_main.c | 43 +- 934 files changed, 9013 insertions(+), 22813 deletions(-) delete mode 100644 trunk/Documentation/DocBook/device-drivers.tmpl create mode 100644 trunk/Documentation/dvb/README.flexcop delete mode 100644 trunk/Documentation/hwmon/hpfall.c create mode 100644 trunk/arch/arm/mach-ep93xx/include/mach/gesbc9312.h delete mode 100644 trunk/arch/ia64/configs/xen_domu_defconfig delete mode 100644 trunk/arch/sparc/include/asm/nmi.h delete mode 100644 trunk/arch/sparc/include/asm/pcr.h delete mode 100644 trunk/arch/sparc/kernel/nmi.c delete mode 100644 trunk/arch/sparc/kernel/pcr.c delete mode 100644 trunk/drivers/media/dvb/firewire/Kconfig delete mode 100644 trunk/drivers/media/dvb/firewire/Makefile delete mode 100644 trunk/drivers/media/dvb/firewire/firedtv-1394.c delete mode 100644 trunk/drivers/media/dvb/firewire/firedtv-avc.c delete mode 100644 trunk/drivers/media/dvb/firewire/firedtv-ci.c delete mode 100644 trunk/drivers/media/dvb/firewire/firedtv-dvb.c delete mode 100644 trunk/drivers/media/dvb/firewire/firedtv-fe.c delete mode 100644 trunk/drivers/media/dvb/firewire/firedtv-rc.c delete mode 100644 trunk/drivers/media/dvb/firewire/firedtv.h delete mode 100644 trunk/drivers/rtc/rtc-dm355evm.c rename trunk/drivers/video/backlight/{da903x_bl.c => da903x.c} (100%) diff --git a/[refs] b/[refs] index 77d98ffc1e3e..0a1a86a0b0b4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c742b4bf7a180619831783dcdad6aec062587e54 +refs/heads/master: 044fad0dbb4e814c061916fe5a36851af2fd1135 diff --git a/trunk/.mailmap b/trunk/.mailmap index a62e6a84fd1e..4e83e7b52d15 100644 --- a/trunk/.mailmap +++ b/trunk/.mailmap @@ -92,7 +92,6 @@ Rudolf Marek Rui Saraiva Sachin P Sant Sam Ravnborg -Sascha Hauer S.Çağlar Onur Simon Kelley Stéphane Witzmann @@ -101,7 +100,6 @@ Tejun Heo Thomas Graf Tony Luck Tsuneo Yoshioka -Uwe Kleine-König -Uwe Kleine-König Uwe Kleine-König +Uwe Kleine-König Valdis Kletnieks diff --git a/trunk/CREDITS b/trunk/CREDITS index 5e0736722afd..2b39168c06aa 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -2166,6 +2166,7 @@ D: Initial implementation of VC's, pty's and select() N: Pavel Machek E: pavel@ucw.cz +E: pavel@suse.cz D: Softcursor for vga, hypertech cdrom support, vcsa bugfix, nbd D: sun4/330 port, capabilities for elf, speedup for rm on ext2, USB, D: work on suspend-to-ram/disk, killing duplicates from ioctl32 diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-pci b/trunk/Documentation/ABI/testing/sysfs-bus-pci index e638e15a8895..ceddcff4082a 100644 --- a/trunk/Documentation/ABI/testing/sysfs-bus-pci +++ b/trunk/Documentation/ABI/testing/sysfs-bus-pci @@ -1,46 +1,3 @@ -What: /sys/bus/pci/drivers/.../bind -Date: December 2003 -Contact: linux-pci@vger.kernel.org -Description: - Writing a device location to this file will cause - the driver to attempt to bind to the device found at - this location. This is useful for overriding default - bindings. The format for the location is: DDDD:BB:DD.F. - That is Domain:Bus:Device.Function and is the same as - found in /sys/bus/pci/devices/. For example: - # echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/bind - (Note: kernels before 2.6.28 may require echo -n). - -What: /sys/bus/pci/drivers/.../unbind -Date: December 2003 -Contact: linux-pci@vger.kernel.org -Description: - Writing a device location to this file will cause the - driver to attempt to unbind from the device found at - this location. This may be useful when overriding default - bindings. The format for the location is: DDDD:BB:DD.F. - That is Domain:Bus:Device.Function and is the same as - found in /sys/bus/pci/devices/. For example: - # echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/unbind - (Note: kernels before 2.6.28 may require echo -n). - -What: /sys/bus/pci/drivers/.../new_id -Date: December 2003 -Contact: linux-pci@vger.kernel.org -Description: - Writing a device ID to this file will attempt to - dynamically add a new device ID to a PCI device driver. - This may allow the driver to support more hardware than - was included in the driver's static device ID support - table at compile time. The format for the device ID is: - VVVV DDDD SVVV SDDD CCCC MMMM PPPP. That is Vendor ID, - Device ID, Subsystem Vendor ID, Subsystem Device ID, - Class, Class Mask, and Private Driver Data. The Vendor ID - and Device ID fields are required, the rest are optional. - Upon successfully adding an ID, the driver will probe - for the device and attempt to bind to it. For example: - # echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id - What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings diff --git a/trunk/Documentation/ABI/testing/sysfs-firmware-memmap b/trunk/Documentation/ABI/testing/sysfs-firmware-memmap index eca0d65087dc..0d99ee6ae02e 100644 --- a/trunk/Documentation/ABI/testing/sysfs-firmware-memmap +++ b/trunk/Documentation/ABI/testing/sysfs-firmware-memmap @@ -1,6 +1,6 @@ What: /sys/firmware/memmap/ Date: June 2008 -Contact: Bernhard Walle +Contact: Bernhard Walle Description: On all platforms, the firmware provides a memory map which the kernel reads. The resources from that memory map are registered diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile index 1462ed86d40a..dc3154e49279 100644 --- a/trunk/Documentation/DocBook/Makefile +++ b/trunk/Documentation/DocBook/Makefile @@ -6,7 +6,7 @@ # To add a new book the only step required is to add the book to the # list of DOCBOOKS. -DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \ +DOCBOOKS := z8530book.xml mcabook.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ procfs-guide.xml writing_usb_driver.xml networking.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ diff --git a/trunk/Documentation/DocBook/device-drivers.tmpl b/trunk/Documentation/DocBook/device-drivers.tmpl deleted file mode 100644 index 94a20fe8fedf..000000000000 --- a/trunk/Documentation/DocBook/device-drivers.tmpl +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - Linux Device Drivers - - - - This documentation 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 - - - - For more details see the file COPYING in the source - distribution of Linux. - - - - - - - - Driver Basics - Driver Entry and Exit points -!Iinclude/linux/init.h - - - Atomic and pointer manipulation -!Iarch/x86/include/asm/atomic_32.h -!Iarch/x86/include/asm/unaligned.h - - - Delaying, scheduling, and timer routines -!Iinclude/linux/sched.h -!Ekernel/sched.c -!Ekernel/timer.c - - High-resolution timers -!Iinclude/linux/ktime.h -!Iinclude/linux/hrtimer.h -!Ekernel/hrtimer.c - - Workqueues and Kevents -!Ekernel/workqueue.c - - Internal Functions -!Ikernel/exit.c -!Ikernel/signal.c -!Iinclude/linux/kthread.h -!Ekernel/kthread.c - - - Kernel objects manipulation - -!Elib/kobject.c - - - Kernel utility functions -!Iinclude/linux/kernel.h -!Ekernel/printk.c -!Ekernel/panic.c -!Ekernel/sys.c -!Ekernel/rcupdate.c - - - Device Resource Management -!Edrivers/base/devres.c - - - - - - Device drivers infrastructure - Device Drivers Base - -!Edrivers/base/driver.c -!Edrivers/base/core.c -!Edrivers/base/class.c -!Edrivers/base/firmware_class.c -!Edrivers/base/transport_class.c - -!Edrivers/base/sys.c - -!Edrivers/base/platform.c -!Edrivers/base/bus.c - - Device Drivers Power Management -!Edrivers/base/power/main.c - - Device Drivers ACPI Support - -!Edrivers/acpi/scan.c -!Idrivers/acpi/scan.c - - - Device drivers PnP support -!Idrivers/pnp/core.c - -!Edrivers/pnp/card.c -!Idrivers/pnp/driver.c -!Edrivers/pnp/manager.c -!Edrivers/pnp/support.c - - Userspace IO devices -!Edrivers/uio/uio.c -!Iinclude/linux/uio_driver.h - - - - - Parallel Port Devices -!Iinclude/linux/parport.h -!Edrivers/parport/ieee1284.c -!Edrivers/parport/share.c -!Idrivers/parport/daisy.c - - - - Message-based devices - Fusion message devices -!Edrivers/message/fusion/mptbase.c -!Idrivers/message/fusion/mptbase.c -!Edrivers/message/fusion/mptscsih.c -!Idrivers/message/fusion/mptscsih.c -!Idrivers/message/fusion/mptctl.c -!Idrivers/message/fusion/mptspi.c -!Idrivers/message/fusion/mptfc.c -!Idrivers/message/fusion/mptlan.c - - I2O message devices -!Iinclude/linux/i2o.h -!Idrivers/message/i2o/core.h -!Edrivers/message/i2o/iop.c -!Idrivers/message/i2o/iop.c -!Idrivers/message/i2o/config-osm.c -!Edrivers/message/i2o/exec-osm.c -!Idrivers/message/i2o/exec-osm.c -!Idrivers/message/i2o/bus-osm.c -!Edrivers/message/i2o/device.c -!Idrivers/message/i2o/device.c -!Idrivers/message/i2o/driver.c -!Idrivers/message/i2o/pci.c -!Idrivers/message/i2o/i2o_block.c -!Idrivers/message/i2o/i2o_scsi.c -!Idrivers/message/i2o/i2o_proc.c - - - - - Sound Devices -!Iinclude/sound/core.h -!Esound/sound_core.c -!Iinclude/sound/pcm.h -!Esound/core/pcm.c -!Esound/core/device.c -!Esound/core/info.c -!Esound/core/rawmidi.c -!Esound/core/sound.c -!Esound/core/memory.c -!Esound/core/pcm_memory.c -!Esound/core/init.c -!Esound/core/isadma.c -!Esound/core/control.c -!Esound/core/pcm_lib.c -!Esound/core/hwdep.c -!Esound/core/pcm_native.c -!Esound/core/memalloc.c - - - - - 16x50 UART Driver -!Iinclude/linux/serial_core.h -!Edrivers/serial/serial_core.c -!Edrivers/serial/8250.c - - - - Frame Buffer Library - - - The frame buffer drivers depend heavily on four data structures. - These structures are declared in include/linux/fb.h. They are - fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs. - The last three can be made available to and from userland. - - - - fb_info defines the current state of a particular video card. - Inside fb_info, there exists a fb_ops structure which is a - collection of needed functions to make fbdev and fbcon work. - fb_info is only visible to the kernel. - - - - fb_var_screeninfo is used to describe the features of a video card - that are user defined. With fb_var_screeninfo, things such as - depth and the resolution may be defined. - - - - The next structure is fb_fix_screeninfo. This defines the - properties of a card that are created when a mode is set and can't - be changed otherwise. A good example of this is the start of the - frame buffer memory. This "locks" the address of the frame buffer - memory, so that it cannot be changed or moved. - - - - The last structure is fb_monospecs. In the old API, there was - little importance for fb_monospecs. This allowed for forbidden things - such as setting a mode of 800x600 on a fix frequency monitor. With - the new API, fb_monospecs prevents such things, and if used - correctly, can prevent a monitor from being cooked. fb_monospecs - will not be useful until kernels 2.5.x. - - - Frame Buffer Memory -!Edrivers/video/fbmem.c - - - Frame Buffer Colormap -!Edrivers/video/fbcmap.c - - - Frame Buffer Video Mode Database -!Idrivers/video/modedb.c -!Edrivers/video/modedb.c - - Frame Buffer Macintosh Video Mode Database -!Edrivers/video/macmodes.c - - Frame Buffer Fonts - - Refer to the file drivers/video/console/fonts.c for more information. - - - - - - - Input Subsystem -!Iinclude/linux/input.h -!Edrivers/input/input.c -!Edrivers/input/ff-core.c -!Edrivers/input/ff-memless.c - - - - Serial Peripheral Interface (SPI) - - SPI is the "Serial Peripheral Interface", widely used with - embedded systems because it is a simple and efficient - interface: basically a multiplexed shift register. - Its three signal wires hold a clock (SCK, often in the range - of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and - a "Master In, Slave Out" (MISO) data line. - SPI is a full duplex protocol; for each bit shifted out the - MOSI line (one per clock) another is shifted in on the MISO line. - Those bits are assembled into words of various sizes on the - way to and from system memory. - An additional chipselect line is usually active-low (nCS); - four signals are normally used for each peripheral, plus - sometimes an interrupt. - - - The SPI bus facilities listed here provide a generalized - interface to declare SPI busses and devices, manage them - according to the standard Linux driver model, and perform - input/output operations. - At this time, only "master" side interfaces are supported, - where Linux talks to SPI peripherals and does not implement - such a peripheral itself. - (Interfaces to support implementing SPI slaves would - necessarily look different.) - - - The programming interface is structured around two kinds of driver, - and two kinds of device. - A "Controller Driver" abstracts the controller hardware, which may - be as simple as a set of GPIO pins or as complex as a pair of FIFOs - connected to dual DMA engines on the other side of the SPI shift - register (maximizing throughput). Such drivers bridge between - whatever bus they sit on (often the platform bus) and SPI, and - expose the SPI side of their device as a - struct spi_master. - SPI devices are children of that master, represented as a - struct spi_device and manufactured from - struct spi_board_info descriptors which - are usually provided by board-specific initialization code. - A struct spi_driver is called a - "Protocol Driver", and is bound to a spi_device using normal - driver model calls. - - - The I/O model is a set of queued messages. Protocol drivers - submit one or more struct spi_message - objects, which are processed and completed asynchronously. - (There are synchronous wrappers, however.) Messages are - built from one or more struct spi_transfer - objects, each of which wraps a full duplex SPI transfer. - A variety of protocol tweaking options are needed, because - different chips adopt very different policies for how they - use the bits transferred with SPI. - -!Iinclude/linux/spi/spi.h -!Fdrivers/spi/spi.c spi_register_board_info -!Edrivers/spi/spi.c - - - - I<superscript>2</superscript>C and SMBus Subsystem - - - I2C (or without fancy typography, "I2C") - is an acronym for the "Inter-IC" bus, a simple bus protocol which is - widely used where low data rate communications suffice. - Since it's also a licensed trademark, some vendors use another - name (such as "Two-Wire Interface", TWI) for the same bus. - I2C only needs two signals (SCL for clock, SDA for data), conserving - board real estate and minimizing signal quality issues. - Most I2C devices use seven bit addresses, and bus speeds of up - to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet - found wide use. - I2C is a multi-master bus; open drain signaling is used to - arbitrate between masters, as well as to handshake and to - synchronize clocks from slower clients. - - - - The Linux I2C programming interfaces support only the master - side of bus interactions, not the slave side. - The programming interface is structured around two kinds of driver, - and two kinds of device. - An I2C "Adapter Driver" abstracts the controller hardware; it binds - to a physical device (perhaps a PCI device or platform_device) and - exposes a struct i2c_adapter representing - each I2C bus segment it manages. - On each I2C bus segment will be I2C devices represented by a - struct i2c_client. Those devices will - be bound to a struct i2c_driver, - which should follow the standard Linux driver model. - (At this writing, a legacy model is more widely used.) - There are functions to perform various I2C protocol operations; at - this writing all such functions are usable only from task context. - - - - The System Management Bus (SMBus) is a sibling protocol. Most SMBus - systems are also I2C conformant. The electrical constraints are - tighter for SMBus, and it standardizes particular protocol messages - and idioms. Controllers that support I2C can also support most - SMBus operations, but SMBus controllers don't support all the protocol - options that an I2C controller will. - There are functions to perform various SMBus protocol operations, - either using I2C primitives or by issuing SMBus commands to - i2c_adapter devices which don't support those I2C operations. - - -!Iinclude/linux/i2c.h -!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info -!Edrivers/i2c/i2c-core.c - - - diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index bc962cda6504..5818ff75786a 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -38,6 +38,58 @@ + + Driver Basics + Driver Entry and Exit points +!Iinclude/linux/init.h + + + Atomic and pointer manipulation +!Iarch/x86/include/asm/atomic_32.h +!Iarch/x86/include/asm/unaligned.h + + + Delaying, scheduling, and timer routines +!Iinclude/linux/sched.h +!Ekernel/sched.c +!Ekernel/timer.c + + High-resolution timers +!Iinclude/linux/ktime.h +!Iinclude/linux/hrtimer.h +!Ekernel/hrtimer.c + + Workqueues and Kevents +!Ekernel/workqueue.c + + Internal Functions +!Ikernel/exit.c +!Ikernel/signal.c +!Iinclude/linux/kthread.h +!Ekernel/kthread.c + + + Kernel objects manipulation + +!Elib/kobject.c + + + Kernel utility functions +!Iinclude/linux/kernel.h +!Ekernel/printk.c +!Ekernel/panic.c +!Ekernel/sys.c +!Ekernel/rcupdate.c + + + Device Resource Management +!Edrivers/base/devres.c + + + + Data Types Doubly Linked Lists @@ -246,6 +298,62 @@ X!Earch/x86/kernel/mca_32.c !Ikernel/acct.c + + Device drivers infrastructure + Device Drivers Base + +!Edrivers/base/driver.c +!Edrivers/base/core.c +!Edrivers/base/class.c +!Edrivers/base/firmware_class.c +!Edrivers/base/transport_class.c + +!Edrivers/base/sys.c + +!Edrivers/base/platform.c +!Edrivers/base/bus.c + + Device Drivers Power Management +!Edrivers/base/power/main.c + + Device Drivers ACPI Support + +!Edrivers/acpi/scan.c +!Idrivers/acpi/scan.c + + + Device drivers PnP support +!Idrivers/pnp/core.c + +!Edrivers/pnp/card.c +!Idrivers/pnp/driver.c +!Edrivers/pnp/manager.c +!Edrivers/pnp/support.c + + Userspace IO devices +!Edrivers/uio/uio.c +!Iinclude/linux/uio_driver.h + + + Block Devices !Eblock/blk-core.c @@ -273,6 +381,275 @@ X!Earch/x86/kernel/mca_32.c !Edrivers/char/misc.c + + Parallel Port Devices +!Iinclude/linux/parport.h +!Edrivers/parport/ieee1284.c +!Edrivers/parport/share.c +!Idrivers/parport/daisy.c + + + + Message-based devices + Fusion message devices +!Edrivers/message/fusion/mptbase.c +!Idrivers/message/fusion/mptbase.c +!Edrivers/message/fusion/mptscsih.c +!Idrivers/message/fusion/mptscsih.c +!Idrivers/message/fusion/mptctl.c +!Idrivers/message/fusion/mptspi.c +!Idrivers/message/fusion/mptfc.c +!Idrivers/message/fusion/mptlan.c + + I2O message devices +!Iinclude/linux/i2o.h +!Idrivers/message/i2o/core.h +!Edrivers/message/i2o/iop.c +!Idrivers/message/i2o/iop.c +!Idrivers/message/i2o/config-osm.c +!Edrivers/message/i2o/exec-osm.c +!Idrivers/message/i2o/exec-osm.c +!Idrivers/message/i2o/bus-osm.c +!Edrivers/message/i2o/device.c +!Idrivers/message/i2o/device.c +!Idrivers/message/i2o/driver.c +!Idrivers/message/i2o/pci.c +!Idrivers/message/i2o/i2o_block.c +!Idrivers/message/i2o/i2o_scsi.c +!Idrivers/message/i2o/i2o_proc.c + + + + + Sound Devices +!Iinclude/sound/core.h +!Esound/sound_core.c +!Iinclude/sound/pcm.h +!Esound/core/pcm.c +!Esound/core/device.c +!Esound/core/info.c +!Esound/core/rawmidi.c +!Esound/core/sound.c +!Esound/core/memory.c +!Esound/core/pcm_memory.c +!Esound/core/init.c +!Esound/core/isadma.c +!Esound/core/control.c +!Esound/core/pcm_lib.c +!Esound/core/hwdep.c +!Esound/core/pcm_native.c +!Esound/core/memalloc.c + + + + + 16x50 UART Driver +!Iinclude/linux/serial_core.h +!Edrivers/serial/serial_core.c +!Edrivers/serial/8250.c + + + + Frame Buffer Library + + + The frame buffer drivers depend heavily on four data structures. + These structures are declared in include/linux/fb.h. They are + fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs. + The last three can be made available to and from userland. + + + + fb_info defines the current state of a particular video card. + Inside fb_info, there exists a fb_ops structure which is a + collection of needed functions to make fbdev and fbcon work. + fb_info is only visible to the kernel. + + + + fb_var_screeninfo is used to describe the features of a video card + that are user defined. With fb_var_screeninfo, things such as + depth and the resolution may be defined. + + + + The next structure is fb_fix_screeninfo. This defines the + properties of a card that are created when a mode is set and can't + be changed otherwise. A good example of this is the start of the + frame buffer memory. This "locks" the address of the frame buffer + memory, so that it cannot be changed or moved. + + + + The last structure is fb_monospecs. In the old API, there was + little importance for fb_monospecs. This allowed for forbidden things + such as setting a mode of 800x600 on a fix frequency monitor. With + the new API, fb_monospecs prevents such things, and if used + correctly, can prevent a monitor from being cooked. fb_monospecs + will not be useful until kernels 2.5.x. + + + Frame Buffer Memory +!Edrivers/video/fbmem.c + + + Frame Buffer Colormap +!Edrivers/video/fbcmap.c + + + Frame Buffer Video Mode Database +!Idrivers/video/modedb.c +!Edrivers/video/modedb.c + + Frame Buffer Macintosh Video Mode Database +!Edrivers/video/macmodes.c + + Frame Buffer Fonts + + Refer to the file drivers/video/console/fonts.c for more information. + + + + + + + Input Subsystem +!Iinclude/linux/input.h +!Edrivers/input/input.c +!Edrivers/input/ff-core.c +!Edrivers/input/ff-memless.c + + + + Serial Peripheral Interface (SPI) + + SPI is the "Serial Peripheral Interface", widely used with + embedded systems because it is a simple and efficient + interface: basically a multiplexed shift register. + Its three signal wires hold a clock (SCK, often in the range + of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and + a "Master In, Slave Out" (MISO) data line. + SPI is a full duplex protocol; for each bit shifted out the + MOSI line (one per clock) another is shifted in on the MISO line. + Those bits are assembled into words of various sizes on the + way to and from system memory. + An additional chipselect line is usually active-low (nCS); + four signals are normally used for each peripheral, plus + sometimes an interrupt. + + + The SPI bus facilities listed here provide a generalized + interface to declare SPI busses and devices, manage them + according to the standard Linux driver model, and perform + input/output operations. + At this time, only "master" side interfaces are supported, + where Linux talks to SPI peripherals and does not implement + such a peripheral itself. + (Interfaces to support implementing SPI slaves would + necessarily look different.) + + + The programming interface is structured around two kinds of driver, + and two kinds of device. + A "Controller Driver" abstracts the controller hardware, which may + be as simple as a set of GPIO pins or as complex as a pair of FIFOs + connected to dual DMA engines on the other side of the SPI shift + register (maximizing throughput). Such drivers bridge between + whatever bus they sit on (often the platform bus) and SPI, and + expose the SPI side of their device as a + struct spi_master. + SPI devices are children of that master, represented as a + struct spi_device and manufactured from + struct spi_board_info descriptors which + are usually provided by board-specific initialization code. + A struct spi_driver is called a + "Protocol Driver", and is bound to a spi_device using normal + driver model calls. + + + The I/O model is a set of queued messages. Protocol drivers + submit one or more struct spi_message + objects, which are processed and completed asynchronously. + (There are synchronous wrappers, however.) Messages are + built from one or more struct spi_transfer + objects, each of which wraps a full duplex SPI transfer. + A variety of protocol tweaking options are needed, because + different chips adopt very different policies for how they + use the bits transferred with SPI. + +!Iinclude/linux/spi/spi.h +!Fdrivers/spi/spi.c spi_register_board_info +!Edrivers/spi/spi.c + + + + I<superscript>2</superscript>C and SMBus Subsystem + + + I2C (or without fancy typography, "I2C") + is an acronym for the "Inter-IC" bus, a simple bus protocol which is + widely used where low data rate communications suffice. + Since it's also a licensed trademark, some vendors use another + name (such as "Two-Wire Interface", TWI) for the same bus. + I2C only needs two signals (SCL for clock, SDA for data), conserving + board real estate and minimizing signal quality issues. + Most I2C devices use seven bit addresses, and bus speeds of up + to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet + found wide use. + I2C is a multi-master bus; open drain signaling is used to + arbitrate between masters, as well as to handshake and to + synchronize clocks from slower clients. + + + + The Linux I2C programming interfaces support only the master + side of bus interactions, not the slave side. + The programming interface is structured around two kinds of driver, + and two kinds of device. + An I2C "Adapter Driver" abstracts the controller hardware; it binds + to a physical device (perhaps a PCI device or platform_device) and + exposes a struct i2c_adapter representing + each I2C bus segment it manages. + On each I2C bus segment will be I2C devices represented by a + struct i2c_client. Those devices will + be bound to a struct i2c_driver, + which should follow the standard Linux driver model. + (At this writing, a legacy model is more widely used.) + There are functions to perform various I2C protocol operations; at + this writing all such functions are usable only from task context. + + + + The System Management Bus (SMBus) is a sibling protocol. Most SMBus + systems are also I2C conformant. The electrical constraints are + tighter for SMBus, and it standardizes particular protocol messages + and idioms. Controllers that support I2C can also support most + SMBus operations, but SMBus controllers don't support all the protocol + options that an I2C controller will. + There are functions to perform various SMBus protocol operations, + either using I2C primitives or by issuing SMBus commands to + i2c_adapter devices which don't support those I2C operations. + + +!Iinclude/linux/i2c.h +!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info +!Edrivers/i2c/i2c-core.c + + Clock Framework diff --git a/trunk/Documentation/PCI/PCIEBUS-HOWTO.txt b/trunk/Documentation/PCI/PCIEBUS-HOWTO.txt index 6bd5f372adec..9a07e38631b0 100644 --- a/trunk/Documentation/PCI/PCIEBUS-HOWTO.txt +++ b/trunk/Documentation/PCI/PCIEBUS-HOWTO.txt @@ -93,7 +93,7 @@ the PCI Express Port Bus driver from loading a service driver. int pcie_port_service_register(struct pcie_port_service_driver *new) -This API replaces the Linux Driver Model's pci_register_driver API. A +This API replaces the Linux Driver Model's pci_module_init API. A service driver should always calls pcie_port_service_register at module init. Note that after service driver being loaded, calls such as pci_enable_device(dev) and pci_set_master(dev) are no longer diff --git a/trunk/Documentation/cgroups/cgroups.txt b/trunk/Documentation/cgroups/cgroups.txt index 93feb8444489..d9e5d6f41b92 100644 --- a/trunk/Documentation/cgroups/cgroups.txt +++ b/trunk/Documentation/cgroups/cgroups.txt @@ -252,8 +252,10 @@ cgroup file system directories. When a task is moved from one cgroup to another, it gets a new css_set pointer - if there's an already existing css_set with the desired collection of cgroups then that group is reused, else a new -css_set is allocated. The appropriate existing css_set is located by -looking into a hash table. +css_set is allocated. Note that the current implementation uses a +linear search to locate an appropriate existing css_set, so isn't +very efficient. A future version will use a hash table for better +performance. To allow access from a cgroup to the css_sets (and hence tasks) that comprise it, a set of cg_cgroup_link objects form a lattice; diff --git a/trunk/Documentation/cgroups/cpusets.txt b/trunk/Documentation/cgroups/cpusets.txt index 0611e9528c7c..5c86c258c791 100644 --- a/trunk/Documentation/cgroups/cpusets.txt +++ b/trunk/Documentation/cgroups/cpusets.txt @@ -142,7 +142,7 @@ into the rest of the kernel, none in performance critical paths: - in fork and exit, to attach and detach a task from its cpuset. - in sched_setaffinity, to mask the requested CPUs by what's allowed in that tasks cpuset. - - in sched.c migrate_live_tasks(), to keep migrating tasks within + - in sched.c migrate_all_tasks(), to keep migrating tasks within the CPUs allowed by their cpuset, if possible. - in the mbind and set_mempolicy system calls, to mask the requested Memory Nodes by what's allowed in that tasks cpuset. @@ -175,10 +175,6 @@ files describing that cpuset: - mem_exclusive flag: is memory placement exclusive? - mem_hardwall flag: is memory allocation hardwalled - memory_pressure: measure of how much paging pressure in cpuset - - memory_spread_page flag: if set, spread page cache evenly on allowed nodes - - memory_spread_slab flag: if set, spread slab cache evenly on allowed nodes - - sched_load_balance flag: if set, load balance within CPUs on that cpuset - - sched_relax_domain_level: the searching range when migrating tasks In addition, the root cpuset only has the following file: - memory_pressure_enabled flag: compute memory_pressure? @@ -256,7 +252,7 @@ is causing. This is useful both on tightly managed systems running a wide mix of submitted jobs, which may choose to terminate or re-prioritize jobs that -are trying to use more memory than allowed on the nodes assigned to them, +are trying to use more memory than allowed on the nodes assigned them, and with tightly coupled, long running, massively parallel scientific computing jobs that will dramatically fail to meet required performance goals if they start to use more memory than allowed to them. @@ -382,7 +378,7 @@ as cpusets and sched_setaffinity. The algorithmic cost of load balancing and its impact on key shared kernel data structures such as the task list increases more than linearly with the number of CPUs being balanced. So the scheduler -has support to partition the systems CPUs into a number of sched +has support to partition the systems CPUs into a number of sched domains such that it only load balances within each sched domain. Each sched domain covers some subset of the CPUs in the system; no two sched domains overlap; some CPUs might not be in any sched @@ -489,22 +485,17 @@ of CPUs allowed to a cpuset having 'sched_load_balance' enabled. The internal kernel cpuset to scheduler interface passes from the cpuset code to the scheduler code a partition of the load balanced CPUs in the system. This partition is a set of subsets (represented -as an array of struct cpumask) of CPUs, pairwise disjoint, that cover -all the CPUs that must be load balanced. - -The cpuset code builds a new such partition and passes it to the -scheduler sched domain setup code, to have the sched domains rebuilt -as necessary, whenever: - - the 'sched_load_balance' flag of a cpuset with non-empty CPUs changes, - - or CPUs come or go from a cpuset with this flag enabled, - - or 'sched_relax_domain_level' value of a cpuset with non-empty CPUs - and with this flag enabled changes, - - or a cpuset with non-empty CPUs and with this flag enabled is removed, - - or a cpu is offlined/onlined. +as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all +the CPUs that must be load balanced. + +Whenever the 'sched_load_balance' flag changes, or CPUs come or go +from a cpuset with this flag enabled, or a cpuset with this flag +enabled is removed, the cpuset code builds a new such partition and +passes it to the scheduler sched domain setup code, to have the sched +domains rebuilt as necessary. This partition exactly defines what sched domains the scheduler should -setup - one sched domain for each element (struct cpumask) in the -partition. +setup - one sched domain for each element (cpumask_t) in the partition. The scheduler remembers the currently active sched domain partitions. When the scheduler routine partition_sched_domains() is invoked from @@ -568,7 +559,7 @@ domain, the largest value among those is used. Be careful, if one requests 0 and others are -1 then 0 is used. Note that modifying this file will have both good and bad effects, -and whether it is acceptable or not depends on your situation. +and whether it is acceptable or not will be depend on your situation. Don't modify this file if you are not sure. If your situation is: @@ -609,15 +600,19 @@ to allocate a page of memory for that task. If a cpuset has its 'cpus' modified, then each task in that cpuset will have its allowed CPU placement changed immediately. Similarly, -if a tasks pid is written to another cpusets 'tasks' file, then its -allowed CPU placement is changed immediately. If such a task had been -bound to some subset of its cpuset using the sched_setaffinity() call, -the task will be allowed to run on any CPU allowed in its new cpuset, -negating the effect of the prior sched_setaffinity() call. +if a tasks pid is written to a cpusets 'tasks' file, in either its +current cpuset or another cpuset, then its allowed CPU placement is +changed immediately. If such a task had been bound to some subset +of its cpuset using the sched_setaffinity() call, the task will be +allowed to run on any CPU allowed in its new cpuset, negating the +affect of the prior sched_setaffinity() call. In summary, the memory placement of a task whose cpuset is changed is updated by the kernel, on the next allocation of a page for that task, -and the processor placement is updated immediately. +but the processor placement is not updated, until that tasks pid is +rewritten to the 'tasks' file of its cpuset. This is done to avoid +impacting the scheduler code in the kernel with a check for changes +in a tasks processor placement. Normally, once a page is allocated (given a physical page of main memory) then that page stays on whatever node it @@ -686,14 +681,10 @@ and then start a subshell 'sh' in that cpuset: # The next line should display '/Charlie' cat /proc/self/cpuset -There are ways to query or modify cpusets: - - via the cpuset file system directly, using the various cd, mkdir, echo, - cat, rmdir commands from the shell, or their equivalent from C. - - via the C library libcpuset. - - via the C library libcgroup. - (http://sourceforge.net/proects/libcg/) - - via the python application cset. - (http://developer.novell.com/wiki/index.php/Cpuset) +In the future, a C library interface to cpusets will likely be +available. For now, the only way to query or modify cpusets is +via the cpuset file system, using the various cd, mkdir, echo, cat, +rmdir commands from the shell, or their equivalent from C. The sched_setaffinity calls can also be done at the shell prompt using SGI's runon or Robert Love's taskset. The mbind and set_mempolicy @@ -765,7 +756,7 @@ mount -t cpuset X /dev/cpuset is equivalent to -mount -t cgroup -ocpuset,noprefix X /dev/cpuset +mount -t cgroup -ocpuset X /dev/cpuset echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent 2.2 Adding/removing cpus diff --git a/trunk/Documentation/cpu-freq/user-guide.txt b/trunk/Documentation/cpu-freq/user-guide.txt index 917918f84fc7..e3443ddcfb89 100644 --- a/trunk/Documentation/cpu-freq/user-guide.txt +++ b/trunk/Documentation/cpu-freq/user-guide.txt @@ -195,3 +195,19 @@ scaling_setspeed. By "echoing" a new frequency into this you can change the speed of the CPU, but only within the limits of scaling_min_freq and scaling_max_freq. + + +3.2 Deprecated Interfaces +------------------------- + +Depending on your kernel configuration, you might find the following +cpufreq-related files: +/proc/cpufreq +/proc/sys/cpu/*/speed +/proc/sys/cpu/*/speed-min +/proc/sys/cpu/*/speed-max + +These are files for deprecated interfaces to cpufreq, which offer far +less functionality. Because of this, these interfaces aren't described +here. + diff --git a/trunk/Documentation/driver-model/device.txt b/trunk/Documentation/driver-model/device.txt index a7cbfff40d07..a05ec50f8004 100644 --- a/trunk/Documentation/driver-model/device.txt +++ b/trunk/Documentation/driver-model/device.txt @@ -127,11 +127,9 @@ void unlock_device(struct device * dev); Attributes ~~~~~~~~~~ struct device_attribute { - struct attribute attr; - ssize_t (*show)(struct device *dev, struct device_attribute *attr, - char *buf); - ssize_t (*store)(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count); + struct attribute attr; + ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off); + ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off); }; Attributes of devices can be exported via drivers using a simple diff --git a/trunk/Documentation/dvb/README.flexcop b/trunk/Documentation/dvb/README.flexcop new file mode 100644 index 000000000000..5515469de7cf --- /dev/null +++ b/trunk/Documentation/dvb/README.flexcop @@ -0,0 +1,205 @@ +This README escorted the skystar2-driver rewriting procedure. It describes the +state of the new flexcop-driver set and some internals are written down here +too. + +This document hopefully describes things about the flexcop and its +device-offsprings. Goal was to write an easy-to-write and easy-to-read set of +drivers based on the skystar2.c and other information. + +Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been +touched and rewritten. + +History & News +============== + 2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana) + + + + +General coding processing +========================= + +We should proceed as follows (as long as no one complains): + +0) Think before start writing code! + +1) rewriting the skystar2.c with the help of the flexcop register descriptions +and splitting up the files to a pci-bus-part and a flexcop-part. +The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the +device-specific part and b2c2-flexcop.ko for the common flexcop-functions. + +2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c +and other pci drivers) + +3) make some beautification (see 'Improvements when rewriting (refactoring) is +done') + +4) Testing the new driver and maybe substitute the skystar2.c with it, to reach +a wider tester audience. + +5) creating an usb-bus-part using the already written flexcop code for the pci +card. + +Idea: create a kernel-object for the flexcop and export all important +functions. This option saves kernel-memory, but maybe a lot of functions have +to be exported to kernel namespace. + + +Current situation +================= + +0) Done :) +1) Done (some minor issues left) +2) Done +3) Not ready yet, more information is necessary +4) next to be done (see the table below) +5) USB driver is working (yes, there are some minor issues) + +What seems to be ready? +----------------------- + +1) Rewriting +1a) i2c is cut off from the flexcop-pci.c and seems to work +1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c +1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c +1e) eeprom (reading MAC address) +1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me)) +1f) misc. register accesses for reading parameters (e.g. resetting, revision) +1g) pid/mac filter (flexcop-hw-filter.c) +1i) dvb-stuff initialization in flexcop.c (done) +1h) dma stuff (now just using the size-irq, instead of all-together, to be done) +1j) remove flexcop initialization from flexcop-pci.c completely (done) +1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO') +1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from +non-static where possible, moved code to proper places) + +2) Search for errors in the leftover of flexcop-pci.c (partially done) +5a) add MAC address reading +5c) feeding of ISOC data to the software demux (format of the isochronous data +and speed optimization, no real error) (thanks to Vadim Catana) + +What to do in the near future? +-------------------------------------- +(no special order here) + +5) USB driver +5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting) + +Testing changes +--------------- + +O = item is working +P = item is partially working +X = item is not working +N = item does not apply here + = item need to be examined + + | PCI | USB +item | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312 +-------+-------+---------+---------+-------+-------+---------+---------+------- +1a) | O | | | | N | N | N | N +1b) | O | | | | | | O | +1c) | N | N | | | N | N | O | +1d) | O | O +1e) | O | O +1f) | P +1g) | O +1h) | P | +1i) | O | N +1j) | O | N +1l) | O | N +2) | O | N +5a) | N | O +5b)* | N | +5c) | N | O + +* - not done yet + +Known bugs and problems and TODO +-------------------------------- + +1g/h/l) when pid filtering is enabled on the pci card + +DMA usage currently: + The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first + address and triggers an IRQ when it's full and starts writing to the second + address. When the second address is full, the IRQ is triggered again, and + the flexcop writes to first address again, and so on. + The buffersize of each address is currently 640*188 bytes. + + Problem is, when using hw-pid-filtering and doing some low-bandwidth + operation (like scanning) the buffers won't be filled enough to trigger + the IRQ. That's why: + + When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ + is triggered. Is the current write address of DMA1 different to the one + during the last IRQ, then the data is passed to the demuxer. + + There is an additional DMA-IRQ-method: packet count IRQ. This isn't + implemented correctly yet. + + The solution is to disable HW PID filtering, but I don't know how the DVB + API software demux behaves on slow systems with 45MBit/s TS. + +Solved bugs :) +-------------- +1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't +working) +SOLUTION: also index 0 was affected, because net_translation is done for +these indexes by default + +5b) isochronous transfer does only work in the first attempt (for the Sky2PC +USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really +woke up again (don't know if this need fixes, see +flexcop-fe-tuner.c:flexcop_sleep) + +NEWS: when the driver is loaded and unloaded and loaded again (w/o doing +anything in the while the driver is loaded the first time), no transfers take +place anymore. + +Improvements when rewriting (refactoring) is done +================================================= + +- split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control + (enable sleeping for other demods than dvb-s) +- add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA) + +Debugging +--------- +- add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it + with this flexcop, this is important, because i2c is now using the + flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for + that, please tell us so). + +Everything which is identical in the following table, can be put into a common +flexcop-module. + + PCI USB +------------------------------------------------------------------------------- +Different: +Register access: accessing IO memory USB control message +I2C bus: I2C bus of the FC USB control message +Data transfer: DMA isochronous transfer +EEPROM transfer: through i2c bus not clear yet + +Identical: +Streaming: accessing registers +PID Filtering: accessing registers +Sram destinations: accessing registers +Tuner/Demod: I2C bus +DVB-stuff: can be written for common use + +Acknowledgements (just for the rewriting part) +================ + +Bjarne Steinsbo thought a lot in the first place of the pci part for this code +sharing idea. + +Andreas Oberritter for providing a recent PCI initialization template +(pluto2.c). + +Boleslaw Ciesielski for pointing out a problem with firmware loader. + +Vadim Catana for correcting the USB transfer. + +comments, critics and ideas to linux-dvb@linuxtv.org. diff --git a/trunk/Documentation/dvb/technisat.txt b/trunk/Documentation/dvb/technisat.txt index 3f435ffb289c..cdf6ee4b2da1 100644 --- a/trunk/Documentation/dvb/technisat.txt +++ b/trunk/Documentation/dvb/technisat.txt @@ -1,5 +1,5 @@ -How to set up the Technisat/B2C2 Flexcop devices -================================================ +How to set up the Technisat devices +=================================== 1) Find out what device you have ================================ @@ -16,60 +16,54 @@ DVB: registering frontend 0 (Conexant CX24123/CX24109)... If the Technisat is the only TV device in your box get rid of unnecessary modules and check this one: "Multimedia devices" => "Customise analog and hybrid tuner modules to build" -In this directory uncheck every driver which is activated there (except "Simple tuner support" for case 9 only). +In this directory uncheck every driver which is activated there. Then please activate: 2a) Main module part: a.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" -b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card -OR +b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card OR c.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC USB" in case of an USB 1.1 adapter d.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Enable debug for the B2C2 FlexCop drivers" Notice: d.) is helpful for troubleshooting 2b) Frontend module part: -1.) SkyStar DVB-S Revision 2.3: +1.) Revision 2.3: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink VP310/MT312/ZL10313 based" -2.) SkyStar DVB-S Revision 2.6: +2.) Revision 2.6: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0299 based" -3.) SkyStar DVB-S Revision 2.7: +3.) Revision 2.7: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "Samsung S5H1420 based" c.)"Multimedia devices" => "Customise DVB frontends" => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS" d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller" -4.) SkyStar DVB-S Revision 2.8: +4.) Revision 2.8: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24113/CX24128 tuner for DVB-S/DSS" c.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24123 based" d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller" -5.) AirStar DVB-T card: +5.) DVB-T card: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink MT352 based" -6.) CableStar DVB-C card: +6.) DVB-C card: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0297 based" -7.) AirStar ATSC card 1st generation: +7.) ATSC card 1st generation: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "Broadcom BCM3510" -8.) AirStar ATSC card 2nd generation: +8.) ATSC card 2nd generation: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "NxtWave Communications NXT2002/NXT2004 based" -c.)"Multimedia devices" => "Customise DVB frontends" => "Generic I2C PLL based tuners" +c.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based" -9.) AirStar ATSC card 3rd generation: -a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" -b.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based" -c.)"Multimedia devices" => "Customise analog and hybrid tuner modules to build" => "Simple tuner support" - -Author: Uwe Bugla February 2009 +Author: Uwe Bugla December 2008 diff --git a/trunk/Documentation/filesystems/sysfs-pci.txt b/trunk/Documentation/filesystems/sysfs-pci.txt index 9f8740ca3f3b..68ef48839c04 100644 --- a/trunk/Documentation/filesystems/sysfs-pci.txt +++ b/trunk/Documentation/filesystems/sysfs-pci.txt @@ -9,7 +9,6 @@ that support it. For example, a given bus might look like this: | |-- class | |-- config | |-- device - | |-- enable | |-- irq | |-- local_cpus | |-- resource @@ -33,7 +32,6 @@ files, each with their own function. class PCI class (ascii, ro) config PCI config space (binary, rw) device PCI device (ascii, ro) - enable Whether the device is enabled (ascii, rw) irq IRQ number (ascii, ro) local_cpus nearby CPU mask (cpumask, ro) resource PCI resource host addresses (ascii, ro) @@ -59,19 +57,10 @@ used to do actual device programming from userspace. Note that some platforms don't support mmapping of certain resources, so be sure to check the return value from any attempted mmap. -The 'enable' file provides a counter that indicates how many times the device -has been enabled. If the 'enable' file currently returns '4', and a '1' is -echoed into it, it will then return '5'. Echoing a '0' into it will decrease -the count. Even when it returns to 0, though, some of the initialisation -may not be reversed. - The 'rom' file is special in that it provides read-only access to the device's ROM file, if available. It's disabled by default, however, so applications should write the string "1" to the file to enable it before attempting a read -call, and disable it following the access by writing "0" to the file. Note -that the device must be enabled for a rom read to return data succesfully. -In the event a driver is not bound to the device, it can be enabled using the -'enable' file, documented above. +call, and disable it following the access by writing "0" to the file. Accessing legacy resources through sysfs ---------------------------------------- diff --git a/trunk/Documentation/filesystems/sysfs.txt b/trunk/Documentation/filesystems/sysfs.txt index 7e81e37c0b1e..9e9c348275a9 100644 --- a/trunk/Documentation/filesystems/sysfs.txt +++ b/trunk/Documentation/filesystems/sysfs.txt @@ -2,10 +2,8 @@ sysfs - _The_ filesystem for exporting kernel objects. Patrick Mochel -Mike Murphy -Revised: 22 February 2009 -Original: 10 January 2003 +10 January 2003 What it is: @@ -66,13 +64,12 @@ An attribute definition is simply: struct attribute { char * name; - struct module *owner; mode_t mode; }; -int sysfs_create_file(struct kobject * kobj, const struct attribute * attr); -void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr); +int sysfs_create_file(struct kobject * kobj, struct attribute * attr); +void sysfs_remove_file(struct kobject * kobj, struct attribute * attr); A bare attribute contains no means to read or write the value of the @@ -83,11 +80,9 @@ a specific object type. For example, the driver model defines struct device_attribute like: struct device_attribute { - struct attribute attr; - ssize_t (*show)(struct device *dev, struct device_attribute *attr, - char *buf); - ssize_t (*store)(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count); + struct attribute attr; + ssize_t (*show)(struct device * dev, char * buf); + ssize_t (*store)(struct device * dev, const char * buf); }; int device_create_file(struct device *, struct device_attribute *); @@ -95,8 +90,12 @@ void device_remove_file(struct device *, struct device_attribute *); It also defines this helper for defining device attributes: -#define DEVICE_ATTR(_name, _mode, _show, _store) \ -struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) +#define DEVICE_ATTR(_name, _mode, _show, _store) \ +struct device_attribute dev_attr_##_name = { \ + .attr = {.name = __stringify(_name) , .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +}; For example, declaring @@ -108,9 +107,9 @@ static struct device_attribute dev_attr_foo = { .attr = { .name = "foo", .mode = S_IWUSR | S_IRUGO, - .show = show_foo, - .store = store_foo, }, + .show = show_foo, + .store = store_foo, }; @@ -162,12 +161,10 @@ To read or write attributes, show() or store() methods must be specified when declaring the attribute. The method types should be as simple as those defined for device attributes: -ssize_t (*show)(struct device * dev, struct device_attribute * attr, - char * buf); -ssize_t (*store)(struct device * dev, struct device_attribute * attr, - const char * buf); + ssize_t (*show)(struct device * dev, char * buf); + ssize_t (*store)(struct device * dev, const char * buf); -IOW, they should take only an object, an attribute, and a buffer as parameters. +IOW, they should take only an object and a buffer as parameters. sysfs allocates a buffer of size (PAGE_SIZE) and passes it to the @@ -302,16 +299,14 @@ The following interface layers currently exist in sysfs: Structure: struct device_attribute { - struct attribute attr; - ssize_t (*show)(struct device *dev, struct device_attribute *attr, - char *buf); - ssize_t (*store)(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count); + struct attribute attr; + ssize_t (*show)(struct device * dev, char * buf); + ssize_t (*store)(struct device * dev, const char * buf); }; Declaring: -DEVICE_ATTR(_name, _mode, _show, _store); +DEVICE_ATTR(_name, _str, _mode, _show, _store); Creation/Removal: @@ -347,8 +342,7 @@ Structure: struct driver_attribute { struct attribute attr; ssize_t (*show)(struct device_driver *, char * buf); - ssize_t (*store)(struct device_driver *, const char * buf, - size_t count); + ssize_t (*store)(struct device_driver *, const char * buf); }; Declaring: diff --git a/trunk/Documentation/filesystems/ubifs.txt b/trunk/Documentation/filesystems/ubifs.txt index 12fedb7834c6..84da2a4ba25a 100644 --- a/trunk/Documentation/filesystems/ubifs.txt +++ b/trunk/Documentation/filesystems/ubifs.txt @@ -79,6 +79,13 @@ Mount options (*) == default. +norm_unmount (*) commit on unmount; the journal is committed + when the file-system is unmounted so that the + next mount does not have to replay the journal + and it becomes very fast; +fast_unmount do not commit on unmount; this option makes + unmount faster, but the next mount slower + because of the need to replay the journal. bulk_read read more in one go to take advantage of flash media that read faster sequentially no_bulk_read (*) do not bulk-read diff --git a/trunk/Documentation/hwmon/hpfall.c b/trunk/Documentation/hwmon/hpfall.c deleted file mode 100644 index bbea1ccfd46a..000000000000 --- a/trunk/Documentation/hwmon/hpfall.c +++ /dev/null @@ -1,101 +0,0 @@ -/* Disk protection for HP machines. - * - * Copyright 2008 Eric Piel - * Copyright 2009 Pavel Machek - * - * GPLv2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void write_int(char *path, int i) -{ - char buf[1024]; - int fd = open(path, O_RDWR); - if (fd < 0) { - perror("open"); - exit(1); - } - sprintf(buf, "%d", i); - if (write(fd, buf, strlen(buf)) != strlen(buf)) { - perror("write"); - exit(1); - } - close(fd); -} - -void set_led(int on) -{ - write_int("/sys/class/leds/hp::hddprotect/brightness", on); -} - -void protect(int seconds) -{ - write_int("/sys/block/sda/device/unload_heads", seconds*1000); -} - -int on_ac(void) -{ -// /sys/class/power_supply/AC0/online -} - -int lid_open(void) -{ -// /proc/acpi/button/lid/LID/state -} - -void ignore_me(void) -{ - protect(0); - set_led(0); - -} - -int main(int argc, char* argv[]) -{ - int fd, ret; - - fd = open("/dev/freefall", O_RDONLY); - if (fd < 0) { - perror("open"); - return EXIT_FAILURE; - } - - signal(SIGALRM, ignore_me); - - for (;;) { - unsigned char count; - - ret = read(fd, &count, sizeof(count)); - alarm(0); - if ((ret == -1) && (errno == EINTR)) { - /* Alarm expired, time to unpark the heads */ - continue; - } - - if (ret != sizeof(count)) { - perror("read"); - break; - } - - protect(21); - set_led(1); - if (1 || on_ac() || lid_open()) { - alarm(2); - } else { - alarm(20); - } - } - - close(fd); - return EXIT_SUCCESS; -} diff --git a/trunk/Documentation/hwmon/lis3lv02d b/trunk/Documentation/hwmon/lis3lv02d index 287f8c902656..0fcfc4a7ccdc 100644 --- a/trunk/Documentation/hwmon/lis3lv02d +++ b/trunk/Documentation/hwmon/lis3lv02d @@ -33,14 +33,6 @@ rate - reports the sampling rate of the accelerometer device in HZ This driver also provides an absolute input class device, allowing the laptop to act as a pinball machine-esque joystick. -Another feature of the driver is misc device called "freefall" that -acts similar to /dev/rtc and reacts on free-fall interrupts received -from the device. It supports blocking operations, poll/select and -fasync operation modes. You must read 1 bytes from the device. The -result is number of free-fall interrupts since the last successful -read (or 255 if number of interrupts would not fit). - - Axes orientation ---------------- diff --git a/trunk/Documentation/kernel-doc-nano-HOWTO.txt b/trunk/Documentation/kernel-doc-nano-HOWTO.txt index 026ec7d57384..d73fbd2b2b45 100644 --- a/trunk/Documentation/kernel-doc-nano-HOWTO.txt +++ b/trunk/Documentation/kernel-doc-nano-HOWTO.txt @@ -43,8 +43,7 @@ Only comments so marked will be considered by the kernel-doc scripts, and any comment so marked must be in kernel-doc format. Do not use "/**" to be begin a comment block unless the comment block contains kernel-doc formatted comments. The closing comment marker for -kernel-doc comments can be either "*/" or "**/", but "*/" is -preferred in the Linux kernel tree. +kernel-doc comments can be either "*/" or "**/". Kernel-doc comments should be placed just before the function or data structure being described. @@ -64,7 +63,7 @@ Example kernel-doc function comment: * comment lines. * * The longer description can have multiple paragraphs. - */ + **/ The first line, with the short description, must be on a single line. @@ -86,7 +85,7 @@ Example kernel-doc data structure comment. * perhaps with more lines and words. * * Longer description of this structure. - */ + **/ The kernel-doc function comments describe each parameter to the function, in order, with the @name lines. diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 54f21a5c262b..d8362cf9909e 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -114,7 +114,7 @@ In addition, the following text indicates that the option: Parameters denoted with BOOT are actually interpreted by the boot loader, and have no meaning to the kernel directly. Do not modify the syntax of boot loader parameters without extreme -need or coordination with . +need or coordination with . There are also arch-specific kernel-parameters not documented here. See for example . @@ -134,7 +134,7 @@ and is between 256 and 4096 characters. It is defined in the file acpi= [HW,ACPI,X86-64,i386] Advanced Configuration and Power Interface - Format: { force | off | ht | strict | noirq | rsdt } + Format: { force | off | ht | strict | noirq } force -- enable ACPI if default was off off -- disable ACPI if default was on noirq -- do not use ACPI for IRQ routing @@ -868,10 +868,8 @@ and is between 256 and 4096 characters. It is defined in the file icn= [HW,ISDN] Format: [,[,[,]]] - ide-core.nodma= [HW] (E)IDE subsystem - Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc - .vlb_clock .pci_clock .noflush .noprobe .nowerr .cdrom - .chs .ignore_cable are additional options + ide= [HW] (E)IDE subsystem + Format: ide=nodma or ide=doubler See Documentation/ide/ide.txt. idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed @@ -939,8 +937,6 @@ and is between 256 and 4096 characters. It is defined in the file intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option - on - Enable intel iommu driver. off Disable intel iommu driver. igfx_off [Default Off] @@ -2451,7 +2447,7 @@ and is between 256 and 4096 characters. It is defined in the file See Documentation/fb/modedb.txt. vga= [BOOT,X86-32] Select a particular video mode - See Documentation/x86/boot.txt and + See Documentation/x86/i386/boot.txt and Documentation/svga.txt. Use vga=ask for menu. This is actually a boot loader parameter; the value is diff --git a/trunk/Documentation/scsi/cxgb3i.txt b/trunk/Documentation/scsi/cxgb3i.txt index 7ac8032ee9b2..8141fa01978e 100644 --- a/trunk/Documentation/scsi/cxgb3i.txt +++ b/trunk/Documentation/scsi/cxgb3i.txt @@ -4,7 +4,7 @@ Introduction ============ The Chelsio T3 ASIC based Adapters (S310, S320, S302, S304, Mezz cards, etc. -series of products) support iSCSI acceleration and iSCSI Direct Data Placement +series of products) supports iSCSI acceleration and iSCSI Direct Data Placement (DDP) where the hardware handles the expensive byte touching operations, such as CRC computation and verification, and direct DMA to the final host memory destination: @@ -31,9 +31,9 @@ destination: the TCP segments onto the wire. It handles TCP retransmission if needed. - On receiving, S3 h/w recovers the iSCSI PDU by reassembling TCP + On receving, S3 h/w recovers the iSCSI PDU by reassembling TCP segments, separating the header and data, calculating and verifying - the digests, then forwarding the header to the host. The payload data, + the digests, then forwards the header to the host. The payload data, if possible, will be directly placed into the pre-posted host DDP buffer. Otherwise, the payload data will be sent to the host too. @@ -68,8 +68,9 @@ The following steps need to be taken to accelerates the open-iscsi initiator: sure the ip address is unique in the network. 3. edit /etc/iscsi/iscsid.conf - The default setting for MaxRecvDataSegmentLength (131072) is too big; - replace with a value no bigger than 15360 (for example 8192): + The default setting for MaxRecvDataSegmentLength (131072) is too big, + replace "node.conn[0].iscsi.MaxRecvDataSegmentLength" to be a value no + bigger than 15360 (for example 8192): node.conn[0].iscsi.MaxRecvDataSegmentLength = 8192 diff --git a/trunk/Documentation/tracers/mmiotrace.txt b/trunk/Documentation/tracers/mmiotrace.txt index 5731c67abc55..cde23b4a12a1 100644 --- a/trunk/Documentation/tracers/mmiotrace.txt +++ b/trunk/Documentation/tracers/mmiotrace.txt @@ -78,10 +78,12 @@ to view your kernel log and look for "mmiotrace has lost events" warning. If events were lost, the trace is incomplete. You should enlarge the buffers and try again. Buffers are enlarged by first seeing how large the current buffers are: -$ cat /debug/tracing/buffer_size_kb +$ cat /debug/tracing/trace_entries gives you a number. Approximately double this number and write it back, for instance: -$ echo 128000 > /debug/tracing/buffer_size_kb +$ echo 0 > /debug/tracing/tracing_enabled +$ echo 128000 > /debug/tracing/trace_entries +$ echo 1 > /debug/tracing/tracing_enabled Then start again from the top. If you are doing a trace for a driver project, e.g. Nouveau, you should also diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 1c2ca1dc66f2..474ec0c53272 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -692,13 +692,6 @@ M: kernel@wantstofly.org L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) S: Maintained -ARM/NUVOTON W90X900 ARM ARCHITECTURE -P: Wan ZongShun -M: mcuos.com@gmail.com -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.mcuos.com -S: Maintained - ARPD SUPPORT P: Jonathan Layes L: netdev@vger.kernel.org @@ -918,7 +911,7 @@ S: Maintained BLACKFIN ARCHITECTURE P: Bryan Wu M: cooloney@kernel.org -L: uclinux-dist-devel@blackfin.uclinux.org +L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported @@ -1028,14 +1021,6 @@ M: mb@bu3sch.de W: http://bu3sch.de/btgpio.php S: Maintained -BTRFS FILE SYSTEM -P: Chris Mason -M: chris.mason@oracle.com -L: linux-btrfs@vger.kernel.org -W: http://btrfs.wiki.kernel.org/ -T: git kernel.org:/pub/scm/linux/kernel/git/mason/btrfs-unstable.git -S: Maintained - BTTV VIDEO4LINUX DRIVER P: Mauro Carvalho Chehab M: mchehab@infradead.org @@ -1209,8 +1194,6 @@ S: Supported CONTROL GROUPS (CGROUPS) P: Paul Menage M: menage@google.com -P: Li Zefan -M: lizf@cn.fujitsu.com L: containers@lists.linux-foundation.org S: Maintained @@ -1912,10 +1895,10 @@ W: http://gigaset307x.sourceforge.net/ S: Maintained HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER -P: Frank Seidel -M: frank@f-seidel.de -L: lm-sensors@lm-sensors.org -W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/ +P: Robert Love +M: rlove@rlove.org +M: linux-kernel@vger.kernel.org +W: http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/ S: Maintained GSPCA FINEPIX SUBDRIVER @@ -2008,7 +1991,7 @@ S: Maintained HIBERNATION (aka Software Suspend, aka swsusp) P: Pavel Machek -M: pavel@ucw.cz +M: pavel@suse.cz P: Rafael J. Wysocki M: rjw@sisk.pl L: linux-pm@lists.linux-foundation.org @@ -2229,7 +2212,7 @@ P: Sean Hefty M: sean.hefty@intel.com P: Hal Rosenstock M: hal.rosenstock@gmail.com -L: general@lists.openfabrics.org (moderated for non-subscribers) +L: general@lists.openfabrics.org W: http://www.openib.org/ T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git S: Supported @@ -2464,7 +2447,7 @@ S: Maintained ISDN SUBSYSTEM P: Karsten Keil -M: isdn@linux-pingi.de +M: kkeil@suse.de L: isdn4linux@listserv.isdn4linux.de (subscribers-only) W: http://www.isdn4linux.de T: git kernel.org:/pub/scm/linux/kernel/kkeil/isdn-2.6.git @@ -3334,8 +3317,8 @@ P: Jeremy Fitzhardinge M: jeremy@xensource.com P: Chris Wright M: chrisw@sous-sol.org -P: Alok Kataria -M: akataria@vmware.com +P: Zachary Amsden +M: zach@vmware.com P: Rusty Russell M: rusty@rustcorp.com.au L: virtualization@lists.osdl.org @@ -3546,12 +3529,6 @@ S: Maintained PXA MMCI DRIVER S: Orphan -PXA RTC DRIVER -P: Robert Jarzmik -M: robert.jarzmik@free.fr -L: rtc-linux@googlegroups.com -S: Maintained - QLOGIC QLA2XXX FC-SCSI DRIVER P: Andrew Vasquez M: linux-driver@qlogic.com @@ -4179,7 +4156,7 @@ SUSPEND TO RAM P: Len Brown M: len.brown@intel.com P: Pavel Machek -M: pavel@ucw.cz +M: pavel@suse.cz P: Rafael J. Wysocki M: rjw@sisk.pl L: linux-pm@lists.linux-foundation.org @@ -4300,8 +4277,8 @@ P: Rajiv Andrade M: srajiv@linux.vnet.ibm.com W: http://tpmdd.sourceforge.net P: Marcel Selhorst -M: m.selhorst@sirrix.com -W: http://www.sirrix.com +M: tpm@selhorst.net +W: http://www.prosec.rub.de/tpm/ L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained @@ -4864,7 +4841,6 @@ P: Ingo Molnar M: mingo@redhat.com P: H. Peter Anvin M: hpa@zytor.com -M: x86@kernel.org L: linux-kernel@vger.kernel.org T: git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git S: Maintained @@ -4931,11 +4907,11 @@ L: zd1211-devs@lists.sourceforge.net (subscribers-only) S: Maintained ZR36067 VIDEO FOR LINUX DRIVER +P: Ronald Bultje +M: rbultje@ronald.bitfreak.net L: mjpeg-users@lists.sourceforge.net -L: linux-media@vger.kernel.org W: http://mjpeg.sourceforge.net/driver-zoran/ -T: Mercurial http://linuxtv.org/hg/v4l-dvb -S: Odd Fixes +S: Maintained ZS DECSTATION Z85C30 SERIAL DRIVER P: Maciej W. Rozycki diff --git a/trunk/Makefile b/trunk/Makefile index df6ce3e80090..7715b2c14fb4 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 29 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc3 NAME = Erotic Pickled Herring # *DOCUMENTATION* @@ -389,7 +389,6 @@ PHONY += outputmakefile # output directory. outputmakefile: ifneq ($(KBUILD_SRC),) - $(Q)ln -fsn $(srctree) source $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) endif @@ -947,6 +946,7 @@ ifneq ($(KBUILD_SRC),) mkdir -p include2; \ ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \ fi + ln -fsn $(srctree) source endif # prepare2 creates a makefile if using a separate output directory diff --git a/trunk/README b/trunk/README index d6c6c742c1d7..90a07658ede1 100644 --- a/trunk/README +++ b/trunk/README @@ -188,7 +188,7 @@ CONFIGURING the kernel: values to random values. You can find more information on using the Linux kernel config tools - in Documentation/kbuild/kconfig.txt. + in Documentation/kbuild/make-configs.txt. NOTES on "make config": - having unnecessary drivers will make the kernel bigger, and can diff --git a/trunk/arch/alpha/include/asm/bug.h b/trunk/arch/alpha/include/asm/bug.h index 1720c8ad86fe..7b85b7c93709 100644 --- a/trunk/arch/alpha/include/asm/bug.h +++ b/trunk/arch/alpha/include/asm/bug.h @@ -8,12 +8,12 @@ /* ??? Would be nice to use .gprel32 here, but we can't be sure that the function loaded the GP, so this could fail in modules. */ -#define BUG() do { \ +#define BUG() { \ __asm__ __volatile__( \ "call_pal %0 # bugchk\n\t" \ ".long %1\n\t.8byte %2" \ : : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__)); \ - for ( ; ; ); } while (0) + for ( ; ; ); } #define HAVE_ARCH_BUG #endif diff --git a/trunk/arch/alpha/kernel/process.c b/trunk/arch/alpha/kernel/process.c index 8d0097f10208..f238370c907d 100644 --- a/trunk/arch/alpha/kernel/process.c +++ b/trunk/arch/alpha/kernel/process.c @@ -93,8 +93,8 @@ common_shutdown_1(void *generic_ptr) if (cpuid != boot_cpuid) { flags |= 0x00040000UL; /* "remain halted" */ *pflags = flags; - set_cpu_present(cpuid, false); - set_cpu_possible(cpuid, false); + cpu_clear(cpuid, cpu_present_map); + cpu_clear(cpuid, cpu_possible_map); halt(); } #endif @@ -120,8 +120,8 @@ common_shutdown_1(void *generic_ptr) #ifdef CONFIG_SMP /* Wait for the secondaries to halt. */ - set_cpu_present(boot_cpuid, false); - set_cpu_possible(boot_cpuid, false); + cpu_clear(boot_cpuid, cpu_present_map); + cpu_clear(boot_cpuid, cpu_possible_map); while (cpus_weight(cpu_present_map)) barrier(); #endif diff --git a/trunk/arch/alpha/kernel/smp.c b/trunk/arch/alpha/kernel/smp.c index b1fe5674c3a1..00f1dc3dfd5f 100644 --- a/trunk/arch/alpha/kernel/smp.c +++ b/trunk/arch/alpha/kernel/smp.c @@ -120,12 +120,12 @@ void __cpuinit smp_callin(void) { int cpuid = hard_smp_processor_id(); + cpumask_t mask = cpu_online_map; - if (cpu_online(cpuid)) { + if (cpu_test_and_set(cpuid, mask)) { printk("??, cpu 0x%x already present??\n", cpuid); BUG(); } - set_cpu_online(cpuid, true); /* Turn on machine checks. */ wrmces(7); @@ -436,8 +436,8 @@ setup_smp(void) ((char *)cpubase + i*hwrpb->processor_size); if ((cpu->flags & 0x1cc) == 0x1cc) { smp_num_probed++; - set_cpu_possible(i, true); - set_cpu_present(i, true); + cpu_set(i, cpu_possible_map); + cpu_set(i, cpu_present_map); cpu->pal_revision = boot_cpu_palrev; } @@ -470,8 +470,8 @@ smp_prepare_cpus(unsigned int max_cpus) /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { - init_cpu_possible(cpumask_of(boot_cpuid)); - init_cpu_present(cpumask_of(boot_cpuid)); + cpu_possible_map = cpumask_of_cpu(boot_cpuid); + cpu_present_map = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP mode deactivated.\n"); return; } diff --git a/trunk/arch/arm/configs/at91sam9260ek_defconfig b/trunk/arch/arm/configs/at91sam9260ek_defconfig index 98e2f3de4bc5..e0ee7060f9aa 100644 --- a/trunk/arch/arm/configs/at91sam9260ek_defconfig +++ b/trunk/arch/arm/configs/at91sam9260ek_defconfig @@ -608,7 +608,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91SAM9X_WATCHDOG=y +CONFIG_AT91SAM9_WATCHDOG=y # # USB-based Watchdog Cards diff --git a/trunk/arch/arm/configs/at91sam9261ek_defconfig b/trunk/arch/arm/configs/at91sam9261ek_defconfig index 149456142392..01d1ef97d8be 100644 --- a/trunk/arch/arm/configs/at91sam9261ek_defconfig +++ b/trunk/arch/arm/configs/at91sam9261ek_defconfig @@ -700,7 +700,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91SAM9X_WATCHDOG=y +CONFIG_AT91SAM9_WATCHDOG=y # # USB-based Watchdog Cards diff --git a/trunk/arch/arm/configs/at91sam9263ek_defconfig b/trunk/arch/arm/configs/at91sam9263ek_defconfig index 21599f3c6275..036a126725c1 100644 --- a/trunk/arch/arm/configs/at91sam9263ek_defconfig +++ b/trunk/arch/arm/configs/at91sam9263ek_defconfig @@ -710,7 +710,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91SAM9X_WATCHDOG=y +CONFIG_AT91SAM9_WATCHDOG=y # # USB-based Watchdog Cards diff --git a/trunk/arch/arm/configs/at91sam9rlek_defconfig b/trunk/arch/arm/configs/at91sam9rlek_defconfig index e2df81a3e804..237a2a6a8517 100644 --- a/trunk/arch/arm/configs/at91sam9rlek_defconfig +++ b/trunk/arch/arm/configs/at91sam9rlek_defconfig @@ -606,7 +606,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91SAM9X_WATCHDOG=y +CONFIG_AT91SAM9_WATCHDOG=y # # Sonics Silicon Backplane diff --git a/trunk/arch/arm/configs/qil-a9260_defconfig b/trunk/arch/arm/configs/qil-a9260_defconfig index 9b32d0eb89ba..cd1d717903ac 100644 --- a/trunk/arch/arm/configs/qil-a9260_defconfig +++ b/trunk/arch/arm/configs/qil-a9260_defconfig @@ -727,7 +727,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -# CONFIG_AT91SAM9X_WATCHDOG is not set +# CONFIG_AT91SAM9_WATCHDOG is not set # # USB-based Watchdog Cards diff --git a/trunk/arch/arm/kernel/elf.c b/trunk/arch/arm/kernel/elf.c index d4a0da1e48f4..84849098c8e8 100644 --- a/trunk/arch/arm/kernel/elf.c +++ b/trunk/arch/arm/kernel/elf.c @@ -74,9 +74,9 @@ EXPORT_SYMBOL(elf_set_personality); */ int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack) { - if (executable_stack != EXSTACK_DISABLE_X) + if (executable_stack != EXSTACK_ENABLE_X) return 1; - if (cpu_architecture() < CPU_ARCH_ARMv6) + if (cpu_architecture() <= CPU_ARCH_ARMv6) return 1; return 0; } diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 85040cfeb5e5..77b047475539 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -650,7 +650,6 @@ ENTRY(fp_enter) no_fp: mov pc, lr __und_usr_unknown: - enable_irq mov r0, sp adr lr, ret_from_exception b do_undefinstr diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index 49a6ba926c2b..06269ea375c5 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -136,7 +136,7 @@ ENTRY(mcount) ldmia sp!, {r0-r3, pc} trace: - ldr r1, [fp, #-4] @ lr of instrumented routine + ldr r1, [fp, #-4] mov r0, lr sub r0, r0, #MCOUNT_INSN_SIZE mov lr, pc diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index 363db186cb93..7141cee1fab7 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -101,7 +101,7 @@ int show_interrupts(struct seq_file *p, void *v) /* Handle bad interrupts */ static struct irq_desc bad_irq_desc = { .handle_irq = handle_bad_irq, - .lock = __SPIN_LOCK_UNLOCKED(bad_irq_desc.lock), + .lock = SPIN_LOCK_UNLOCKED }; /* diff --git a/trunk/arch/arm/kernel/machine_kexec.c b/trunk/arch/arm/kernel/machine_kexec.c index 598ca61e7bca..440dc62cdc3a 100644 --- a/trunk/arch/arm/kernel/machine_kexec.c +++ b/trunk/arch/arm/kernel/machine_kexec.c @@ -13,8 +13,8 @@ #include #include -extern const unsigned char relocate_new_kernel[]; -extern const unsigned int relocate_new_kernel_size; +const extern unsigned char relocate_new_kernel[]; +const extern unsigned int relocate_new_kernel_size; extern void setup_mm_for_reboot(char mode); diff --git a/trunk/arch/arm/mach-at91/at91cap9_devices.c b/trunk/arch/arm/mach-at91/at91cap9_devices.c index 412aa49ad2fb..9eca2209cde6 100644 --- a/trunk/arch/arm/mach-at91/at91cap9_devices.c +++ b/trunk/arch/arm/mach-at91/at91cap9_devices.c @@ -697,7 +697,7 @@ static void __init at91_add_device_rtt(void) * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) static struct platform_device at91cap9_wdt_device = { .name = "at91_wdt", .id = -1, diff --git a/trunk/arch/arm/mach-at91/at91sam9260_devices.c b/trunk/arch/arm/mach-at91/at91sam9260_devices.c index d74c9ac007e7..fdde1ea21b07 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9260_devices.c @@ -643,7 +643,7 @@ static void __init at91_add_device_rtt(void) * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) static struct platform_device at91sam9260_wdt_device = { .name = "at91_wdt", .id = -1, diff --git a/trunk/arch/arm/mach-at91/at91sam9261_devices.c b/trunk/arch/arm/mach-at91/at91sam9261_devices.c index 59fc48311fb0..17289756f80f 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9261_devices.c @@ -621,7 +621,7 @@ static void __init at91_add_device_rtt(void) * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) static struct platform_device at91sam9261_wdt_device = { .name = "at91_wdt", .id = -1, diff --git a/trunk/arch/arm/mach-at91/at91sam9263_devices.c b/trunk/arch/arm/mach-at91/at91sam9263_devices.c index 134af97ff340..b753cb879d8e 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9263_devices.c @@ -854,7 +854,7 @@ static void __init at91_add_device_rtt(void) * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) static struct platform_device at91sam9263_wdt_device = { .name = "at91_wdt", .id = -1, diff --git a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c index 728186515cdf..145324f4ec56 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c @@ -609,7 +609,7 @@ static void __init at91_add_device_rtt(void) * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) static struct platform_device at91sam9rl_wdt_device = { .name = "at91_wdt", .id = -1, diff --git a/trunk/arch/arm/mach-at91/gpio.c b/trunk/arch/arm/mach-at91/gpio.c index 2f7d4977dce9..9b0447c3d59b 100644 --- a/trunk/arch/arm/mach-at91/gpio.c +++ b/trunk/arch/arm/mach-at91/gpio.c @@ -490,8 +490,7 @@ postcore_initcall(at91_gpio_debugfs_init); /*--------------------------------------------------------------------------*/ -/* - * This lock class tells lockdep that GPIO irqs are in a different +/* This lock class tells lockdep that GPIO irqs are in a different * category than their parents, so it won't report false recursion. */ static struct lock_class_key gpio_lock_class; @@ -510,6 +509,9 @@ void __init at91_gpio_irq_setup(void) unsigned id = this->id; unsigned i; + /* enable PIO controller's clock */ + clk_enable(this->clock); + __raw_writel(~0, this->regbase + PIO_IDR); for (i = 0, pin = this->chipbase; i < 32; i++, pin++) { @@ -554,14 +556,7 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) data->chipbase = PIN_BASE + i * 32; data->regbase = data->offset + (void __iomem *)AT91_VA_BASE_SYS; - /* enable PIO controller's clock */ - clk_enable(data->clock); - - /* - * Some processors share peripheral ID between multiple GPIO banks. - * SAM9263 (PIOC, PIOD, PIOE) - * CAP9 (PIOA, PIOB, PIOC, PIOD) - */ + /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ if (last && last->id == data->id) last->next = data; } diff --git a/trunk/arch/arm/mach-at91/include/mach/board.h b/trunk/arch/arm/mach-at91/include/mach/board.h index 0b3ae21b4565..fb51f0e0a83f 100644 --- a/trunk/arch/arm/mach-at91/include/mach/board.h +++ b/trunk/arch/arm/mach-at91/include/mach/board.h @@ -93,7 +93,6 @@ struct atmel_nand_data { u8 enable_pin; /* chip enable */ u8 det_pin; /* card detect */ u8 rdy_pin; /* ready/busy */ - u8 rdy_pin_active_low; /* rdy_pin value is inverted */ u8 ale; /* address line number connected to ALE */ u8 cle; /* address line number connected to CLE */ u8 bus_width_16; /* buswidth is 16 bit */ diff --git a/trunk/arch/arm/mach-davinci/board-evm.c b/trunk/arch/arm/mach-davinci/board-evm.c index 38b6a9ce2a93..a957d239a683 100644 --- a/trunk/arch/arm/mach-davinci/board-evm.c +++ b/trunk/arch/arm/mach-davinci/board-evm.c @@ -311,9 +311,6 @@ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c) gpio_request(gpio + 7, "nCF_SEL"); gpio_direction_output(gpio + 7, 1); - /* irlml6401 sustains over 3A, switches 5V in under 8 msec */ - setup_usb(500, 8); - return 0; } @@ -420,6 +417,9 @@ static __init void davinci_evm_init(void) platform_add_devices(davinci_evm_devices, ARRAY_SIZE(davinci_evm_devices)); evm_init_i2c(); + + /* irlml6401 sustains over 3A, switches 5V in under 8 msec */ + setup_usb(500, 8); } static __init void davinci_evm_irq_init(void) diff --git a/trunk/arch/arm/mach-davinci/clock.c b/trunk/arch/arm/mach-davinci/clock.c index abb92b7eca0c..28f6dbc95bd7 100644 --- a/trunk/arch/arm/mach-davinci/clock.c +++ b/trunk/arch/arm/mach-davinci/clock.c @@ -230,11 +230,6 @@ static struct clk davinci_clks[] = { .rate = &commonrate, .lpsc = DAVINCI_LPSC_GPIO, }, - { - .name = "usb", - .rate = &commonrate, - .lpsc = DAVINCI_LPSC_USB, - }, { .name = "AEMIFCLK", .rate = &commonrate, diff --git a/trunk/arch/arm/mach-davinci/usb.c b/trunk/arch/arm/mach-davinci/usb.c index 69680784448a..867ead2559ad 100644 --- a/trunk/arch/arm/mach-davinci/usb.c +++ b/trunk/arch/arm/mach-davinci/usb.c @@ -47,7 +47,6 @@ static struct musb_hdrc_platform_data usb_data = { #elif defined(CONFIG_USB_MUSB_HOST) .mode = MUSB_HOST, #endif - .clock = "usb", .config = &musb_config, }; diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/gesbc9312.h b/trunk/arch/arm/mach-ep93xx/include/mach/gesbc9312.h new file mode 100644 index 000000000000..21fe2b922aa5 --- /dev/null +++ b/trunk/arch/arm/mach-ep93xx/include/mach/gesbc9312.h @@ -0,0 +1,3 @@ +/* + * arch/arm/mach-ep93xx/include/mach/gesbc9312.h + */ diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/hardware.h b/trunk/arch/arm/mach-ep93xx/include/mach/hardware.h index 2866297310b7..529807d182bf 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/hardware.h +++ b/trunk/arch/arm/mach-ep93xx/include/mach/hardware.h @@ -10,6 +10,7 @@ #include "platform.h" +#include "gesbc9312.h" #include "ts72xx.h" #endif diff --git a/trunk/arch/arm/mach-kirkwood/irq.c b/trunk/arch/arm/mach-kirkwood/irq.c index 06083b23bb44..efb86b700276 100644 --- a/trunk/arch/arm/mach-kirkwood/irq.c +++ b/trunk/arch/arm/mach-kirkwood/irq.c @@ -42,7 +42,7 @@ void __init kirkwood_init_irq(void) writel(0, GPIO_EDGE_CAUSE(32)); for (i = IRQ_KIRKWOOD_GPIO_START; i < NR_IRQS; i++) { - set_irq_chip(i, &orion_gpio_irq_chip); + set_irq_chip(i, &orion_gpio_irq_level_chip); set_irq_handler(i, handle_level_irq); irq_desc[i].status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); diff --git a/trunk/arch/arm/mach-msm/board-halibut.c b/trunk/arch/arm/mach-msm/board-halibut.c index e61967dde9a1..c2a96e3965a6 100644 --- a/trunk/arch/arm/mach-msm/board-halibut.c +++ b/trunk/arch/arm/mach-msm/board-halibut.c @@ -27,7 +27,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-mv78xx0/irq.c b/trunk/arch/arm/mach-mv78xx0/irq.c index 30b7e4bcdbc7..e273418797b4 100644 --- a/trunk/arch/arm/mach-mv78xx0/irq.c +++ b/trunk/arch/arm/mach-mv78xx0/irq.c @@ -40,7 +40,7 @@ void __init mv78xx0_init_irq(void) writel(0, GPIO_EDGE_CAUSE(0)); for (i = IRQ_MV78XX0_GPIO_START; i < NR_IRQS; i++) { - set_irq_chip(i, &orion_gpio_irq_chip); + set_irq_chip(i, &orion_gpio_irq_level_chip); set_irq_handler(i, handle_level_irq); irq_desc[i].status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); diff --git a/trunk/arch/arm/mach-omap1/devices.c b/trunk/arch/arm/mach-omap1/devices.c index ba5d7c08dc17..77382d8b6b2f 100644 --- a/trunk/arch/arm/mach-omap1/devices.c +++ b/trunk/arch/arm/mach-omap1/devices.c @@ -181,7 +181,7 @@ void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, } size = OMAP1_MMC_SIZE; - omap_mmc_add("mmci-omap", i, base, size, irq, mmc_data[i]); + omap_mmc_add(i, base, size, irq, mmc_data[i]); }; } diff --git a/trunk/arch/arm/mach-omap1/mcbsp.c b/trunk/arch/arm/mach-omap1/mcbsp.c index 575ba31295cf..ca7a0cc1707c 100644 --- a/trunk/arch/arm/mach-omap1/mcbsp.c +++ b/trunk/arch/arm/mach-omap1/mcbsp.c @@ -28,8 +28,81 @@ #define DPS_RSTCT2_PER_EN (1 << 0) #define DSP_RSTCT2_WD_PER_EN (1 << 1) +struct mcbsp_internal_clk { + struct clk clk; + struct clk **childs; + int n_childs; +}; + #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) -const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" }; +static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) +{ + const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" }; + int i; + + mclk->n_childs = ARRAY_SIZE(clk_names); + mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *), + GFP_KERNEL); + + for (i = 0; i < mclk->n_childs; i++) { + /* We fake a platform device to get correct device id */ + struct platform_device pdev; + + pdev.dev.bus = &platform_bus_type; + pdev.id = mclk->clk.id; + mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]); + if (IS_ERR(mclk->childs[i])) + printk(KERN_ERR "Could not get clock %s (%d).\n", + clk_names[i], mclk->clk.id); + } +} + +static int omap_mcbsp_clk_enable(struct clk *clk) +{ + struct mcbsp_internal_clk *mclk = container_of(clk, + struct mcbsp_internal_clk, clk); + int i; + + for (i = 0; i < mclk->n_childs; i++) + clk_enable(mclk->childs[i]); + return 0; +} + +static void omap_mcbsp_clk_disable(struct clk *clk) +{ + struct mcbsp_internal_clk *mclk = container_of(clk, + struct mcbsp_internal_clk, clk); + int i; + + for (i = 0; i < mclk->n_childs; i++) + clk_disable(mclk->childs[i]); +} + +static struct mcbsp_internal_clk omap_mcbsp_clks[] = { + { + .clk = { + .name = "mcbsp_clk", + .id = 1, + .enable = omap_mcbsp_clk_enable, + .disable = omap_mcbsp_clk_disable, + }, + }, + { + .clk = { + .name = "mcbsp_clk", + .id = 3, + .enable = omap_mcbsp_clk_enable, + .disable = omap_mcbsp_clk_disable, + }, + }, +}; + +#define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks) +#else +#define omap_mcbsp_clks_size 0 +static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks; +static inline void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) +{ } #endif static void omap1_mcbsp_request(unsigned int id) @@ -94,9 +167,8 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = { .rx_irq = INT_McBSP1RX, .tx_irq = INT_McBSP1TX, .ops = &omap1_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 3, - }, + .clk_name = "mcbsp_clk", + }, { .phys_base = OMAP1510_MCBSP2_BASE, .dma_rx_sync = OMAP_DMA_MCBSP2_RX, @@ -112,8 +184,7 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = { .rx_irq = INT_McBSP3RX, .tx_irq = INT_McBSP3TX, .ops = &omap1_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 3, + .clk_name = "mcbsp_clk", }, }; #define OMAP15XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap15xx_mcbsp_pdata) @@ -131,8 +202,7 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = { .rx_irq = INT_McBSP1RX, .tx_irq = INT_McBSP1TX, .ops = &omap1_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 3, + .clk_name = "mcbsp_clk", }, { .phys_base = OMAP1610_MCBSP2_BASE, @@ -149,8 +219,7 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = { .rx_irq = INT_McBSP3RX, .tx_irq = INT_McBSP3TX, .ops = &omap1_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 3, + .clk_name = "mcbsp_clk", }, }; #define OMAP16XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap16xx_mcbsp_pdata) @@ -161,6 +230,15 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = { int __init omap1_mcbsp_init(void) { + int i; + + for (i = 0; i < omap_mcbsp_clks_size; i++) { + if (cpu_is_omap15xx() || cpu_is_omap16xx()) { + omap_mcbsp_clk_init(&omap_mcbsp_clks[i]); + clk_register(&omap_mcbsp_clks[i].clk); + } + } + if (cpu_is_omap730()) omap_mcbsp_count = OMAP730_MCBSP_PDATA_SZ; if (cpu_is_omap15xx()) diff --git a/trunk/arch/arm/mach-omap2/clock.c b/trunk/arch/arm/mach-omap2/clock.c index ce4d46a4a838..ad721e0cbf7a 100644 --- a/trunk/arch/arm/mach-omap2/clock.c +++ b/trunk/arch/arm/mach-omap2/clock.c @@ -565,7 +565,7 @@ u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val) * * Given a struct clk of a rate-selectable clksel clock, and a clock divisor, * find the corresponding register field value. The return register value is - * the value before left-shifting. Returns ~0 on error + * the value before left-shifting. Returns 0xffffffff on error */ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) { @@ -577,7 +577,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) clks = omap2_get_clksel_by_parent(clk, clk->parent); if (clks == NULL) - return ~0; + return 0; for (clkr = clks->rates; clkr->div; clkr++) { if ((clkr->flags & cpu_mask) && (clkr->div == div)) @@ -588,7 +588,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) printk(KERN_ERR "clock: Could not find divisor %d for " "clock %s parent %s\n", div, clk->name, clk->parent->name); - return ~0; + return 0; } return clkr->val; @@ -708,7 +708,7 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr, return 0; for (clkr = clks->rates; clkr->div; clkr++) { - if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE) + if (clkr->flags & (cpu_mask | DEFAULT_RATE)) break; /* Found the default rate for this platform */ } @@ -746,7 +746,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) return -EINVAL; if (clk->usecount > 0) - omap2_clk_disable(clk); + _omap2_clk_disable(clk); /* Set new source value (previous dividers if any in effect) */ reg_val = __raw_readl(src_addr) & ~field_mask; @@ -759,10 +759,10 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) wmb(); } - clk->parent = new_parent; - if (clk->usecount > 0) - omap2_clk_enable(clk); + _omap2_clk_enable(clk); + + clk->parent = new_parent; /* CLKSEL clocks follow their parents' rates, divided by a divisor */ clk->rate = new_parent->rate; diff --git a/trunk/arch/arm/mach-omap2/devices.c b/trunk/arch/arm/mach-omap2/devices.c index ce03fa750775..9d7216ff6c9f 100644 --- a/trunk/arch/arm/mach-omap2/devices.c +++ b/trunk/arch/arm/mach-omap2/devices.c @@ -421,7 +421,6 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers) { int i; - char *name; for (i = 0; i < nr_controllers; i++) { unsigned long base, size; @@ -451,14 +450,12 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, continue; } - if (cpu_is_omap2420()) { + if (cpu_is_omap2420()) size = OMAP2420_MMC_SIZE; - name = "mmci-omap"; - } else { + else size = HSMMC_SIZE; - name = "mmci-omap-hs"; - } - omap_mmc_add(name, i, base, size, irq, mmc_data[i]); + + omap_mmc_add(i, base, size, irq, mmc_data[i]); }; } diff --git a/trunk/arch/arm/mach-omap2/id.c b/trunk/arch/arm/mach-omap2/id.c index b52a02fc7cd6..b0f8e7d62798 100644 --- a/trunk/arch/arm/mach-omap2/id.c +++ b/trunk/arch/arm/mach-omap2/id.c @@ -172,13 +172,9 @@ void __init omap34xx_check_revision(void) omap_revision = OMAP3430_REV_ES3_0; rev_name = "ES3.0"; break; - case 4: - omap_revision = OMAP3430_REV_ES3_1; - rev_name = "ES3.1"; - break; default: /* Use the latest known revision as default */ - omap_revision = OMAP3430_REV_ES3_1; + omap_revision = OMAP3430_REV_ES3_0; rev_name = "Unknown revision\n"; } } diff --git a/trunk/arch/arm/mach-omap2/irq.c b/trunk/arch/arm/mach-omap2/irq.c index 9ba20d985dda..636e2821af7d 100644 --- a/trunk/arch/arm/mach-omap2/irq.c +++ b/trunk/arch/arm/mach-omap2/irq.c @@ -134,7 +134,6 @@ static struct irq_chip omap_irq_chip = { .ack = omap_mask_ack_irq, .mask = omap_mask_irq, .unmask = omap_unmask_irq, - .disable = omap_mask_irq, }; static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank) diff --git a/trunk/arch/arm/mach-omap2/mcbsp.c b/trunk/arch/arm/mach-omap2/mcbsp.c index a9e631fc1134..e20023c9d15d 100644 --- a/trunk/arch/arm/mach-omap2/mcbsp.c +++ b/trunk/arch/arm/mach-omap2/mcbsp.c @@ -24,7 +24,106 @@ #include #include -const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" }; +struct mcbsp_internal_clk { + struct clk clk; + struct clk **childs; + int n_childs; +}; + +#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) +static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) +{ + const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" }; + int i; + + mclk->n_childs = ARRAY_SIZE(clk_names); + mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *), + GFP_KERNEL); + + for (i = 0; i < mclk->n_childs; i++) { + /* We fake a platform device to get correct device id */ + struct platform_device pdev; + + pdev.dev.bus = &platform_bus_type; + pdev.id = mclk->clk.id; + mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]); + if (IS_ERR(mclk->childs[i])) + printk(KERN_ERR "Could not get clock %s (%d).\n", + clk_names[i], mclk->clk.id); + } +} + +static int omap_mcbsp_clk_enable(struct clk *clk) +{ + struct mcbsp_internal_clk *mclk = container_of(clk, + struct mcbsp_internal_clk, clk); + int i; + + for (i = 0; i < mclk->n_childs; i++) + clk_enable(mclk->childs[i]); + return 0; +} + +static void omap_mcbsp_clk_disable(struct clk *clk) +{ + struct mcbsp_internal_clk *mclk = container_of(clk, + struct mcbsp_internal_clk, clk); + int i; + + for (i = 0; i < mclk->n_childs; i++) + clk_disable(mclk->childs[i]); +} + +static struct mcbsp_internal_clk omap_mcbsp_clks[] = { + { + .clk = { + .name = "mcbsp_clk", + .id = 1, + .enable = omap_mcbsp_clk_enable, + .disable = omap_mcbsp_clk_disable, + }, + }, + { + .clk = { + .name = "mcbsp_clk", + .id = 2, + .enable = omap_mcbsp_clk_enable, + .disable = omap_mcbsp_clk_disable, + }, + }, + { + .clk = { + .name = "mcbsp_clk", + .id = 3, + .enable = omap_mcbsp_clk_enable, + .disable = omap_mcbsp_clk_disable, + }, + }, + { + .clk = { + .name = "mcbsp_clk", + .id = 4, + .enable = omap_mcbsp_clk_enable, + .disable = omap_mcbsp_clk_disable, + }, + }, + { + .clk = { + .name = "mcbsp_clk", + .id = 5, + .enable = omap_mcbsp_clk_enable, + .disable = omap_mcbsp_clk_disable, + }, + }, +}; + +#define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks) +#else +#define omap_mcbsp_clks_size 0 +static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks; +static inline void omap_mcbsp_clk_init(struct clk *clk) +{ } +#endif static void omap2_mcbsp2_mux_setup(void) { @@ -57,8 +156,7 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP1_IRQ_RX, .tx_irq = INT_24XX_MCBSP1_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, { .phys_base = OMAP24XX_MCBSP2_BASE, @@ -67,8 +165,7 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP2_IRQ_RX, .tx_irq = INT_24XX_MCBSP2_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, }; #define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata) @@ -86,8 +183,7 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP1_IRQ_RX, .tx_irq = INT_24XX_MCBSP1_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, { .phys_base = OMAP24XX_MCBSP2_BASE, @@ -96,8 +192,7 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP2_IRQ_RX, .tx_irq = INT_24XX_MCBSP2_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, { .phys_base = OMAP2430_MCBSP3_BASE, @@ -106,8 +201,7 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP3_IRQ_RX, .tx_irq = INT_24XX_MCBSP3_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, { .phys_base = OMAP2430_MCBSP4_BASE, @@ -116,8 +210,7 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP4_IRQ_RX, .tx_irq = INT_24XX_MCBSP4_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, { .phys_base = OMAP2430_MCBSP5_BASE, @@ -126,8 +219,7 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP5_IRQ_RX, .tx_irq = INT_24XX_MCBSP5_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, }; #define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata) @@ -145,8 +237,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP1_IRQ_RX, .tx_irq = INT_24XX_MCBSP1_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, { .phys_base = OMAP34XX_MCBSP2_BASE, @@ -155,8 +246,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP2_IRQ_RX, .tx_irq = INT_24XX_MCBSP2_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, { .phys_base = OMAP34XX_MCBSP3_BASE, @@ -165,8 +255,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP3_IRQ_RX, .tx_irq = INT_24XX_MCBSP3_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, { .phys_base = OMAP34XX_MCBSP4_BASE, @@ -175,8 +264,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP4_IRQ_RX, .tx_irq = INT_24XX_MCBSP4_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, { .phys_base = OMAP34XX_MCBSP5_BASE, @@ -185,8 +273,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP5_IRQ_RX, .tx_irq = INT_24XX_MCBSP5_IRQ_TX, .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, + .clk_name = "mcbsp_clk", }, }; #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) @@ -197,6 +284,14 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { static int __init omap2_mcbsp_init(void) { + int i; + + for (i = 0; i < omap_mcbsp_clks_size; i++) { + /* Once we call clk_get inside init, we do not register it */ + omap_mcbsp_clk_init(&omap_mcbsp_clks[i]); + clk_register(&omap_mcbsp_clks[i].clk); + } + if (cpu_is_omap2420()) omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ; if (cpu_is_omap2430()) diff --git a/trunk/arch/arm/mach-omap2/sleep24xx.S b/trunk/arch/arm/mach-omap2/sleep24xx.S index bf9e96105e11..43336b93b21c 100644 --- a/trunk/arch/arm/mach-omap2/sleep24xx.S +++ b/trunk/arch/arm/mach-omap2/sleep24xx.S @@ -93,8 +93,9 @@ ENTRY(omap24xx_cpu_suspend) orr r4, r4, #0x40 @ enable self refresh on idle req mov r5, #0x2000 @ set delay (DPLL relock + DLL relock) str r4, [r2] @ make it so + mov r2, #0 nop - mcr p15, 0, r3, c7, c0, 4 @ wait for interrupt + mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt nop loop: subs r5, r5, #0x1 @ awake, wait just a bit diff --git a/trunk/arch/arm/mach-omap2/timer-gp.c b/trunk/arch/arm/mach-omap2/timer-gp.c index 9fc13a2cc3f4..ae6036300f60 100644 --- a/trunk/arch/arm/mach-omap2/timer-gp.c +++ b/trunk/arch/arm/mach-omap2/timer-gp.c @@ -118,8 +118,7 @@ static void __init omap2_gp_clockevent_init(void) clockevent_gpt.max_delta_ns = clockevent_delta2ns(0xffffffff, &clockevent_gpt); clockevent_gpt.min_delta_ns = - clockevent_delta2ns(3, &clockevent_gpt); - /* Timer internal resynch latency. */ + clockevent_delta2ns(1, &clockevent_gpt); clockevent_gpt.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_gpt); diff --git a/trunk/arch/arm/mach-orion5x/irq.c b/trunk/arch/arm/mach-orion5x/irq.c index e03f7b45cb0d..0caae43301e5 100644 --- a/trunk/arch/arm/mach-orion5x/irq.c +++ b/trunk/arch/arm/mach-orion5x/irq.c @@ -44,7 +44,7 @@ void __init orion5x_init_irq(void) * User can use set_type() if he wants to use edge types handlers. */ for (i = IRQ_ORION5X_GPIO_START; i < NR_IRQS; i++) { - set_irq_chip(i, &orion_gpio_irq_chip); + set_irq_chip(i, &orion_gpio_irq_level_chip); set_irq_handler(i, handle_level_irq); irq_desc[i].status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); diff --git a/trunk/arch/arm/mach-pxa/dma.c b/trunk/arch/arm/mach-pxa/dma.c index 7de17fc5d54b..b1514fb20d3a 100644 --- a/trunk/arch/arm/mach-pxa/dma.c +++ b/trunk/arch/arm/mach-pxa/dma.c @@ -121,16 +121,6 @@ int __init pxa_init_dma(int num_ch) if (dma_channels == NULL) return -ENOMEM; - /* dma channel priorities on pxa2xx processors: - * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH - * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM - * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW - */ - for (i = 0; i < num_ch; i++) { - DCSR(i) = 0; - dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW); - } - ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL); if (ret) { printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); @@ -138,6 +128,14 @@ int __init pxa_init_dma(int num_ch) return ret; } + /* dma channel priorities on pxa2xx processors: + * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH + * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM + * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW + */ + for (i = 0; i < num_ch; i++) + dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW); + num_dma_channels = num_ch; return 0; } diff --git a/trunk/arch/arm/mach-pxa/include/mach/regs-ac97.h b/trunk/arch/arm/mach-pxa/include/mach/regs-ac97.h index b8d14bd9ae59..e41b9d202b8c 100644 --- a/trunk/arch/arm/mach-pxa/include/mach/regs-ac97.h +++ b/trunk/arch/arm/mach-pxa/include/mach/regs-ac97.h @@ -1,8 +1,6 @@ #ifndef __ASM_ARCH_REGS_AC97_H #define __ASM_ARCH_REGS_AC97_H -#include - /* * AC97 Controller registers */ diff --git a/trunk/arch/arm/mach-pxa/include/mach/regs-ssp.h b/trunk/arch/arm/mach-pxa/include/mach/regs-ssp.h index cf31986f6f05..3c04cde2cf1f 100644 --- a/trunk/arch/arm/mach-pxa/include/mach/regs-ssp.h +++ b/trunk/arch/arm/mach-pxa/include/mach/regs-ssp.h @@ -41,9 +41,6 @@ #elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #define SSCR0_SCR (0x000fff00) /* Serial Clock Rate (mask) */ #define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */ -#endif - -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #define SSCR0_EDSS (1 << 20) /* Extended data size select */ #define SSCR0_NCS (1 << 21) /* Network clock select */ #define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */ diff --git a/trunk/arch/arm/mach-pxa/pxa300.c b/trunk/arch/arm/mach-pxa/pxa300.c index 83fb609b6eb7..f735e58e6669 100644 --- a/trunk/arch/arm/mach-pxa/pxa300.c +++ b/trunk/arch/arm/mach-pxa/pxa300.c @@ -88,13 +88,13 @@ static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = { static DEFINE_PXA3_CKEN(common_nand, NAND, 156000000, 0); static struct clk_lookup common_clkregs[] = { - INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL), + INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", "NANDCLK"), }; static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0); static struct clk_lookup pxa310_clkregs[] = { - INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", NULL), + INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", "MMCCLK"), }; static int __init pxa300_init(void) diff --git a/trunk/arch/arm/mach-pxa/pxa320.c b/trunk/arch/arm/mach-pxa/pxa320.c index 36f066196fa2..effe408c186f 100644 --- a/trunk/arch/arm/mach-pxa/pxa320.c +++ b/trunk/arch/arm/mach-pxa/pxa320.c @@ -83,7 +83,7 @@ static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = { static DEFINE_PXA3_CKEN(pxa320_nand, NAND, 104000000, 0); static struct clk_lookup pxa320_clkregs[] = { - INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL), + INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", "NANDCLK"), }; static int __init pxa320_init(void) diff --git a/trunk/arch/arm/mach-rpc/riscpc.c b/trunk/arch/arm/mach-rpc/riscpc.c index c7fc01e9d1f6..e88d417736af 100644 --- a/trunk/arch/arm/mach-rpc/riscpc.c +++ b/trunk/arch/arm/mach-rpc/riscpc.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -202,13 +201,8 @@ static struct platform_device *devs[] __initdata = { &pata_device, }; -static struct i2c_board_info i2c_rtc = { - I2C_BOARD_INFO("pcf8583", 0x50) -}; - static int __init rpc_init(void) { - i2c_register_board_info(0, &i2c_rtc, 1); return platform_add_devices(devs, ARRAY_SIZE(devs)); } diff --git a/trunk/arch/arm/mach-sa1100/generic.c b/trunk/arch/arm/mach-sa1100/generic.c index 23cfdd593954..c1fbd5b5f9c4 100644 --- a/trunk/arch/arm/mach-sa1100/generic.c +++ b/trunk/arch/arm/mach-sa1100/generic.c @@ -289,7 +289,7 @@ static struct platform_device sa11x0pcmcia_device = { }; static struct platform_device sa11x0mtd_device = { - .name = "sa1100-mtd", + .name = "flash", .id = -1, }; diff --git a/trunk/arch/arm/mm/fault-armv.c b/trunk/arch/arm/mm/fault-armv.c index bc0099d5ae85..81d0b8772de3 100644 --- a/trunk/arch/arm/mm/fault-armv.c +++ b/trunk/arch/arm/mm/fault-armv.c @@ -66,10 +66,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address) * fault (ie, is old), we can safely ignore any issues. */ if (ret && (pte_val(entry) & L_PTE_MT_MASK) != shared_pte_mask) { - unsigned long pfn = pte_pfn(entry); - flush_cache_page(vma, address, pfn); - outer_flush_range((pfn << PAGE_SHIFT), - (pfn << PAGE_SHIFT) + PAGE_SIZE); + flush_cache_page(vma, address, pte_pfn(entry)); pte_val(entry) &= ~L_PTE_MT_MASK; pte_val(entry) |= shared_pte_mask; set_pte_at(vma->vm_mm, address, pte, entry); diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index d4d082c5c2d4..9b36c5cb5e9f 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -693,8 +693,7 @@ static void __init sanity_check_meminfo(void) * Check whether this memory bank would entirely overlap * the vmalloc area. */ - if (__va(bank->start) >= VMALLOC_MIN || - __va(bank->start) < PAGE_OFFSET) { + if (__va(bank->start) >= VMALLOC_MIN) { printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx " "(vmalloc region overlap).\n", bank->start, bank->start + bank->size - 1); diff --git a/trunk/arch/arm/plat-omap/devices.c b/trunk/arch/arm/plat-omap/devices.c index 208dbb121f47..ac15c23fd5da 100644 --- a/trunk/arch/arm/plat-omap/devices.c +++ b/trunk/arch/arm/plat-omap/devices.c @@ -200,15 +200,14 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, /* * Register MMC devices. Called from mach-omap1 and mach-omap2 device init. */ -int __init omap_mmc_add(const char *name, int id, unsigned long base, - unsigned long size, unsigned int irq, - struct omap_mmc_platform_data *data) +int __init omap_mmc_add(int id, unsigned long base, unsigned long size, + unsigned int irq, struct omap_mmc_platform_data *data) { struct platform_device *pdev; struct resource res[OMAP_MMC_NR_RES]; int ret; - pdev = platform_device_alloc(name, id); + pdev = platform_device_alloc("mmci-omap", id); if (!pdev) return -ENOMEM; diff --git a/trunk/arch/arm/plat-omap/dma.c b/trunk/arch/arm/plat-omap/dma.c index 47ec77af4ccb..e77373c39f8c 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -709,7 +709,6 @@ int omap_request_dma(int dev_id, const char *dev_name, chan->dev_name = dev_name; chan->callback = callback; chan->data = data; - chan->flags = 0; #ifndef CONFIG_ARCH_OMAP1 if (cpu_class_is_omap2()) { @@ -1889,11 +1888,11 @@ static int omap2_dma_handle_ch(int ch) status = dma_read(CSR(ch)); } - dma_write(status, CSR(ch)); - if (likely(dma_chan[ch].callback != NULL)) dma_chan[ch].callback(ch, status, dma_chan[ch].data); + dma_write(status, CSR(ch)); + return 0; } diff --git a/trunk/arch/arm/plat-omap/include/mach/cpu.h b/trunk/arch/arm/plat-omap/include/mach/cpu.h index a8e1178a9468..b2062f1175de 100644 --- a/trunk/arch/arm/plat-omap/include/mach/cpu.h +++ b/trunk/arch/arm/plat-omap/include/mach/cpu.h @@ -339,7 +339,6 @@ IS_OMAP_TYPE(3430, 0x3430) #define OMAP3430_REV_ES2_0 0x34301034 #define OMAP3430_REV_ES2_1 0x34302034 #define OMAP3430_REV_ES3_0 0x34303034 -#define OMAP3430_REV_ES3_1 0x34304034 /* * omap_chip bits diff --git a/trunk/arch/arm/plat-omap/include/mach/mcbsp.h b/trunk/arch/arm/plat-omap/include/mach/mcbsp.h index 113c2466c86a..eef873db3d48 100644 --- a/trunk/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/trunk/arch/arm/plat-omap/include/mach/mcbsp.h @@ -344,8 +344,7 @@ struct omap_mcbsp_platform_data { u8 dma_rx_sync, dma_tx_sync; u16 rx_irq, tx_irq; struct omap_mcbsp_ops *ops; - char const **clk_names; - int num_clks; + char const *clk_name; }; struct omap_mcbsp { @@ -377,8 +376,7 @@ struct omap_mcbsp { /* Protect the field .free, while checking if the mcbsp is in use */ spinlock_t lock; struct omap_mcbsp_platform_data *pdata; - struct clk **clks; - int num_clks; + struct clk *clk; }; extern struct omap_mcbsp **mcbsp_ptr; extern int omap_mcbsp_count; diff --git a/trunk/arch/arm/plat-omap/include/mach/mmc.h b/trunk/arch/arm/plat-omap/include/mach/mmc.h index 73a9e15031b1..031250f02805 100644 --- a/trunk/arch/arm/plat-omap/include/mach/mmc.h +++ b/trunk/arch/arm/plat-omap/include/mach/mmc.h @@ -115,9 +115,8 @@ void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers); void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers); -int omap_mmc_add(const char *name, int id, unsigned long base, - unsigned long size, unsigned int irq, - struct omap_mmc_platform_data *data); +int omap_mmc_add(int id, unsigned long base, unsigned long size, + unsigned int irq, struct omap_mmc_platform_data *data); #else static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers) @@ -127,9 +126,8 @@ static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers) { } -static inline int omap_mmc_add(const char *name, int id, unsigned long base, - unsigned long size, unsigned int irq, - struct omap_mmc_platform_data *data) +static inline int omap_mmc_add(int id, unsigned long base, unsigned long size, + unsigned int irq, struct omap_mmc_platform_data *data) { return 0; } diff --git a/trunk/arch/arm/plat-omap/mcbsp.c b/trunk/arch/arm/plat-omap/mcbsp.c index e5842e30e534..f2401a831f99 100644 --- a/trunk/arch/arm/plat-omap/mcbsp.c +++ b/trunk/arch/arm/plat-omap/mcbsp.c @@ -214,7 +214,6 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type); int omap_mcbsp_request(unsigned int id) { struct omap_mcbsp *mcbsp; - int i; int err; if (!omap_mcbsp_check_valid_id(id)) { @@ -226,8 +225,7 @@ int omap_mcbsp_request(unsigned int id) if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request) mcbsp->pdata->ops->request(id); - for (i = 0; i < mcbsp->num_clks; i++) - clk_enable(mcbsp->clks[i]); + clk_enable(mcbsp->clk); spin_lock(&mcbsp->lock); if (!mcbsp->free) { @@ -278,7 +276,6 @@ EXPORT_SYMBOL(omap_mcbsp_request); void omap_mcbsp_free(unsigned int id) { struct omap_mcbsp *mcbsp; - int i; if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); @@ -289,8 +286,7 @@ void omap_mcbsp_free(unsigned int id) if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) mcbsp->pdata->ops->free(id); - for (i = mcbsp->num_clks - 1; i >= 0; i--) - clk_disable(mcbsp->clks[i]); + clk_disable(mcbsp->clk); spin_lock(&mcbsp->lock); if (mcbsp->free) { @@ -876,7 +872,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; struct omap_mcbsp *mcbsp; int id = pdev->id - 1; - int i; int ret = 0; if (!pdata) { @@ -921,25 +916,14 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) mcbsp->dma_rx_sync = pdata->dma_rx_sync; mcbsp->dma_tx_sync = pdata->dma_tx_sync; - if (pdata->num_clks) { - mcbsp->num_clks = pdata->num_clks; - mcbsp->clks = kzalloc(mcbsp->num_clks * sizeof(struct clk *), - GFP_KERNEL); - if (!mcbsp->clks) { - ret = -ENOMEM; - goto exit; - } - for (i = 0; i < mcbsp->num_clks; i++) { - mcbsp->clks[i] = clk_get(&pdev->dev, pdata->clk_names[i]); - if (IS_ERR(mcbsp->clks[i])) { - dev_err(&pdev->dev, - "Invalid %s configuration for McBSP%d.\n", - pdata->clk_names[i], mcbsp->id); - ret = PTR_ERR(mcbsp->clks[i]); - goto err_clk; - } - } - + if (pdata->clk_name) + mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name); + if (IS_ERR(mcbsp->clk)) { + dev_err(&pdev->dev, + "Invalid clock configuration for McBSP%d.\n", + mcbsp->id); + ret = PTR_ERR(mcbsp->clk); + goto err_clk; } mcbsp->pdata = pdata; @@ -948,9 +932,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) return 0; err_clk: - while (i--) - clk_put(mcbsp->clks[i]); - kfree(mcbsp->clks); iounmap(mcbsp->io_base); err_ioremap: mcbsp->free = 0; @@ -961,7 +942,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) static int __devexit omap_mcbsp_remove(struct platform_device *pdev) { struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); - int i; platform_set_drvdata(pdev, NULL); if (mcbsp) { @@ -970,18 +950,12 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev) mcbsp->pdata->ops->free) mcbsp->pdata->ops->free(mcbsp->id); - for (i = mcbsp->num_clks - 1; i >= 0; i--) { - clk_disable(mcbsp->clks[i]); - clk_put(mcbsp->clks[i]); - } + clk_disable(mcbsp->clk); + clk_put(mcbsp->clk); iounmap(mcbsp->io_base); - if (mcbsp->num_clks) { - kfree(mcbsp->clks); - mcbsp->clks = NULL; - mcbsp->num_clks = 0; - } + mcbsp->clk = NULL; mcbsp->free = 0; mcbsp->dev = NULL; } diff --git a/trunk/arch/arm/plat-orion/gpio.c b/trunk/arch/arm/plat-orion/gpio.c index 0d12c2164766..967186425ca1 100644 --- a/trunk/arch/arm/plat-orion/gpio.c +++ b/trunk/arch/arm/plat-orion/gpio.c @@ -265,36 +265,51 @@ EXPORT_SYMBOL(orion_gpio_set_blink); * polarity LEVEL mask * ****************************************************************************/ +static void gpio_irq_edge_ack(u32 irq) +{ + int pin = irq_to_gpio(irq); + + writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin)); +} -static void gpio_irq_ack(u32 irq) +static void gpio_irq_edge_mask(u32 irq) { - int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK; - if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { - int pin = irq_to_gpio(irq); - writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin)); - } + int pin = irq_to_gpio(irq); + u32 u; + + u = readl(GPIO_EDGE_MASK(pin)); + u &= ~(1 << (pin & 31)); + writel(u, GPIO_EDGE_MASK(pin)); +} + +static void gpio_irq_edge_unmask(u32 irq) +{ + int pin = irq_to_gpio(irq); + u32 u; + + u = readl(GPIO_EDGE_MASK(pin)); + u |= 1 << (pin & 31); + writel(u, GPIO_EDGE_MASK(pin)); } -static void gpio_irq_mask(u32 irq) +static void gpio_irq_level_mask(u32 irq) { int pin = irq_to_gpio(irq); - int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK; - u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ? - GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin); - u32 u = readl(reg); + u32 u; + + u = readl(GPIO_LEVEL_MASK(pin)); u &= ~(1 << (pin & 31)); - writel(u, reg); + writel(u, GPIO_LEVEL_MASK(pin)); } -static void gpio_irq_unmask(u32 irq) +static void gpio_irq_level_unmask(u32 irq) { int pin = irq_to_gpio(irq); - int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK; - u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ? - GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin); - u32 u = readl(reg); + u32 u; + + u = readl(GPIO_LEVEL_MASK(pin)); u |= 1 << (pin & 31); - writel(u, reg); + writel(u, GPIO_LEVEL_MASK(pin)); } static int gpio_irq_set_type(u32 irq, u32 type) @@ -316,9 +331,9 @@ static int gpio_irq_set_type(u32 irq, u32 type) * Set edge/level type. */ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { - desc->handle_irq = handle_edge_irq; + desc->chip = &orion_gpio_irq_edge_chip; } else if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { - desc->handle_irq = handle_level_irq; + desc->chip = &orion_gpio_irq_level_chip; } else { printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type); return -EINVAL; @@ -356,11 +371,19 @@ static int gpio_irq_set_type(u32 irq, u32 type) return 0; } -struct irq_chip orion_gpio_irq_chip = { - .name = "orion_gpio", - .ack = gpio_irq_ack, - .mask = gpio_irq_mask, - .unmask = gpio_irq_unmask, +struct irq_chip orion_gpio_irq_edge_chip = { + .name = "orion_gpio_irq_edge", + .ack = gpio_irq_edge_ack, + .mask = gpio_irq_edge_mask, + .unmask = gpio_irq_edge_unmask, + .set_type = gpio_irq_set_type, +}; + +struct irq_chip orion_gpio_irq_level_chip = { + .name = "orion_gpio_irq_level", + .mask = gpio_irq_level_mask, + .mask_ack = gpio_irq_level_mask, + .unmask = gpio_irq_level_unmask, .set_type = gpio_irq_set_type, }; diff --git a/trunk/arch/arm/plat-orion/include/plat/gpio.h b/trunk/arch/arm/plat-orion/include/plat/gpio.h index ec743e82c876..54deaf274b52 100644 --- a/trunk/arch/arm/plat-orion/include/plat/gpio.h +++ b/trunk/arch/arm/plat-orion/include/plat/gpio.h @@ -31,7 +31,8 @@ void orion_gpio_set_blink(unsigned pin, int blink); /* * GPIO interrupt handling. */ -extern struct irq_chip orion_gpio_irq_chip; +extern struct irq_chip orion_gpio_irq_edge_chip; +extern struct irq_chip orion_gpio_irq_level_chip; void orion_gpio_irq_handler(int irqoff); diff --git a/trunk/arch/avr32/mach-at32ap/include/mach/board.h b/trunk/arch/avr32/mach-at32ap/include/mach/board.h index cff8e84f78f2..aafaf7a78886 100644 --- a/trunk/arch/avr32/mach-at32ap/include/mach/board.h +++ b/trunk/arch/avr32/mach-at32ap/include/mach/board.h @@ -116,7 +116,6 @@ struct atmel_nand_data { int enable_pin; /* chip enable */ int det_pin; /* card detect */ int rdy_pin; /* ready/busy */ - u8 rdy_pin_active_low; /* rdy_pin value is inverted */ u8 ale; /* address line number connected to ALE */ u8 cle; /* address line number connected to CLE */ u8 bus_width_16; /* buswidth is 16 bit */ diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig index 8f1f97d56e1e..a949c4fbbddd 100644 --- a/trunk/arch/blackfin/Kconfig +++ b/trunk/arch/blackfin/Kconfig @@ -169,51 +169,26 @@ config BF542 help BF542 Processor Support. -config BF542M - bool "BF542m" - help - BF542 Processor Support. - config BF544 bool "BF544" help BF544 Processor Support. -config BF544M - bool "BF544m" - help - BF544 Processor Support. - config BF547 bool "BF547" help BF547 Processor Support. -config BF547M - bool "BF547m" - help - BF547 Processor Support. - config BF548 bool "BF548" help BF548 Processor Support. -config BF548M - bool "BF548m" - help - BF548 Processor Support. - config BF549 bool "BF549" help BF549 Processor Support. -config BF549M - bool "BF549m" - help - BF549 Processor Support. - config BF561 bool "BF561" help @@ -249,39 +224,39 @@ config TICK_SOURCE_SYSTMR0 config BF_REV_MIN int - default 0 if (BF51x || BF52x || (BF54x && !BF54xM)) + default 0 if (BF51x || BF52x || BF54x) default 2 if (BF537 || BF536 || BF534) - default 3 if (BF561 || BF533 || BF532 || BF531 || BF54xM) + default 3 if (BF561 ||BF533 || BF532 || BF531) default 4 if (BF538 || BF539) config BF_REV_MAX int - default 2 if (BF51x || BF52x || (BF54x && !BF54xM)) - default 3 if (BF537 || BF536 || BF534 || BF54xM) + default 2 if (BF51x || BF52x || BF54x) + default 3 if (BF537 || BF536 || BF534) default 5 if (BF561 || BF538 || BF539) default 6 if (BF533 || BF532 || BF531) choice prompt "Silicon Rev" - default BF_REV_0_1 if (BF51x || BF52x || (BF54x && !BF54xM)) + default BF_REV_0_1 if (BF51x || BF52x || BF54x) default BF_REV_0_2 if (BF534 || BF536 || BF537) - default BF_REV_0_3 if (BF531 || BF532 || BF533 || BF54xM || BF561) + default BF_REV_0_3 if (BF531 || BF532 || BF533 || BF561) config BF_REV_0_0 bool "0.0" - depends on (BF51x || BF52x || (BF54x && !BF54xM)) + depends on (BF51x || BF52x || BF54x) config BF_REV_0_1 bool "0.1" - depends on (BF52x || (BF54x && !BF54xM)) + depends on (BF52x || BF54x) config BF_REV_0_2 bool "0.2" - depends on (BF52x || BF537 || BF536 || BF534 || (BF54x && !BF54xM)) + depends on (BF52x || BF537 || BF536 || BF534 || BF54x) config BF_REV_0_3 bool "0.3" - depends on (BF54xM || BF561 || BF537 || BF536 || BF534 || BF533 || BF532 || BF531) + depends on (BF561 || BF537 || BF536 || BF534 || BF533 || BF532 || BF531) config BF_REV_0_4 bool "0.4" @@ -318,14 +293,9 @@ config BF53x depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537) default y -config BF54xM - bool - depends on (BF542M || BF544M || BF547M || BF548M || BF549M) - default y - config BF54x bool - depends on (BF542 || BF544 || BF547 || BF548 || BF549 || BF54xM) + depends on (BF542 || BF544 || BF547 || BF548 || BF549) default y config MEM_GENERIC_BOARD diff --git a/trunk/arch/blackfin/Makefile b/trunk/arch/blackfin/Makefile index d54c8283825c..e550c8d46066 100644 --- a/trunk/arch/blackfin/Makefile +++ b/trunk/arch/blackfin/Makefile @@ -21,67 +21,57 @@ KALLSYMS += --symbol-prefix=_ KBUILD_DEFCONFIG := BF537-STAMP_defconfig # setup the machine name and the machine dependent settings -machine-$(CONFIG_BF512) := bf518 -machine-$(CONFIG_BF514) := bf518 -machine-$(CONFIG_BF516) := bf518 -machine-$(CONFIG_BF518) := bf518 -machine-$(CONFIG_BF522) := bf527 -machine-$(CONFIG_BF523) := bf527 -machine-$(CONFIG_BF524) := bf527 -machine-$(CONFIG_BF525) := bf527 -machine-$(CONFIG_BF526) := bf527 -machine-$(CONFIG_BF527) := bf527 -machine-$(CONFIG_BF531) := bf533 -machine-$(CONFIG_BF532) := bf533 -machine-$(CONFIG_BF533) := bf533 -machine-$(CONFIG_BF534) := bf537 -machine-$(CONFIG_BF536) := bf537 -machine-$(CONFIG_BF537) := bf537 -machine-$(CONFIG_BF538) := bf538 -machine-$(CONFIG_BF539) := bf538 -machine-$(CONFIG_BF542) := bf548 -machine-$(CONFIG_BF542M) := bf548 -machine-$(CONFIG_BF544) := bf548 -machine-$(CONFIG_BF544M) := bf548 -machine-$(CONFIG_BF547) := bf548 -machine-$(CONFIG_BF547M) := bf548 -machine-$(CONFIG_BF548) := bf548 -machine-$(CONFIG_BF548M) := bf548 -machine-$(CONFIG_BF549) := bf548 -machine-$(CONFIG_BF549M) := bf548 -machine-$(CONFIG_BF561) := bf561 +machine-$(CONFIG_BF512) := bf518 +machine-$(CONFIG_BF514) := bf518 +machine-$(CONFIG_BF516) := bf518 +machine-$(CONFIG_BF518) := bf518 +machine-$(CONFIG_BF522) := bf527 +machine-$(CONFIG_BF523) := bf527 +machine-$(CONFIG_BF524) := bf527 +machine-$(CONFIG_BF525) := bf527 +machine-$(CONFIG_BF526) := bf527 +machine-$(CONFIG_BF527) := bf527 +machine-$(CONFIG_BF531) := bf533 +machine-$(CONFIG_BF532) := bf533 +machine-$(CONFIG_BF533) := bf533 +machine-$(CONFIG_BF534) := bf537 +machine-$(CONFIG_BF536) := bf537 +machine-$(CONFIG_BF537) := bf537 +machine-$(CONFIG_BF538) := bf538 +machine-$(CONFIG_BF539) := bf538 +machine-$(CONFIG_BF542) := bf548 +machine-$(CONFIG_BF544) := bf548 +machine-$(CONFIG_BF547) := bf548 +machine-$(CONFIG_BF548) := bf548 +machine-$(CONFIG_BF549) := bf548 +machine-$(CONFIG_BF561) := bf561 MACHINE := $(machine-y) export MACHINE -cpu-$(CONFIG_BF512) := bf512 -cpu-$(CONFIG_BF514) := bf514 -cpu-$(CONFIG_BF516) := bf516 -cpu-$(CONFIG_BF518) := bf518 -cpu-$(CONFIG_BF522) := bf522 -cpu-$(CONFIG_BF523) := bf523 -cpu-$(CONFIG_BF524) := bf524 -cpu-$(CONFIG_BF525) := bf525 -cpu-$(CONFIG_BF526) := bf526 -cpu-$(CONFIG_BF527) := bf527 -cpu-$(CONFIG_BF531) := bf531 -cpu-$(CONFIG_BF532) := bf532 -cpu-$(CONFIG_BF533) := bf533 -cpu-$(CONFIG_BF534) := bf534 -cpu-$(CONFIG_BF536) := bf536 -cpu-$(CONFIG_BF537) := bf537 -cpu-$(CONFIG_BF538) := bf538 -cpu-$(CONFIG_BF539) := bf539 -cpu-$(CONFIG_BF542) := bf542 -cpu-$(CONFIG_BF542M) := bf542m -cpu-$(CONFIG_BF544) := bf544 -cpu-$(CONFIG_BF544M) := bf544m -cpu-$(CONFIG_BF547) := bf547 -cpu-$(CONFIG_BF547M) := bf547m -cpu-$(CONFIG_BF548) := bf548 -cpu-$(CONFIG_BF548M) := bf548m -cpu-$(CONFIG_BF549) := bf549 -cpu-$(CONFIG_BF549M) := bf549m -cpu-$(CONFIG_BF561) := bf561 +cpu-$(CONFIG_BF512) := bf512 +cpu-$(CONFIG_BF514) := bf514 +cpu-$(CONFIG_BF516) := bf516 +cpu-$(CONFIG_BF518) := bf518 +cpu-$(CONFIG_BF522) := bf522 +cpu-$(CONFIG_BF523) := bf523 +cpu-$(CONFIG_BF524) := bf524 +cpu-$(CONFIG_BF525) := bf525 +cpu-$(CONFIG_BF526) := bf526 +cpu-$(CONFIG_BF527) := bf527 +cpu-$(CONFIG_BF531) := bf531 +cpu-$(CONFIG_BF532) := bf532 +cpu-$(CONFIG_BF533) := bf533 +cpu-$(CONFIG_BF534) := bf534 +cpu-$(CONFIG_BF536) := bf536 +cpu-$(CONFIG_BF537) := bf537 +cpu-$(CONFIG_BF538) := bf538 +cpu-$(CONFIG_BF539) := bf539 +cpu-$(CONFIG_BF542) := bf542 +cpu-$(CONFIG_BF544) := bf544 +cpu-$(CONFIG_BF547) := bf547 +cpu-$(CONFIG_BF548) := bf548 +cpu-$(CONFIG_BF549) := bf549 +cpu-$(CONFIG_BF561) := bf561 rev-$(CONFIG_BF_REV_0_0) := 0.0 rev-$(CONFIG_BF_REV_0_1) := 0.1 diff --git a/trunk/arch/blackfin/configs/BF518F-EZBRD_defconfig b/trunk/arch/blackfin/configs/BF518F-EZBRD_defconfig index 4fdb9e04759f..defb9785c65b 100644 --- a/trunk/arch/blackfin/configs/BF518F-EZBRD_defconfig +++ b/trunk/arch/blackfin/configs/BF518F-EZBRD_defconfig @@ -1,7 +1,6 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.28-rc2 -# Fri Jan 9 17:58:41 2009 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -150,7 +149,6 @@ CONFIG_BF_REV_0_0=y # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF51x=y -CONFIG_MEM_MT48LC32M8A2_75=y CONFIG_BFIN518F_EZBRD=y # @@ -600,10 +598,7 @@ CONFIG_PHYLIB=y # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y -CONFIG_BFIN_MAC=y -CONFIG_BFIN_TX_DESC_NUM=10 -CONFIG_BFIN_RX_DESC_NUM=20 -# CONFIG_BFIN_MAC_RMII is not set +# CONFIG_BFIN_MAC is not set # CONFIG_SMC91X is not set # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set @@ -684,7 +679,7 @@ CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_DEVKMEM is not set -CONFIG_BFIN_JTAG_COMM=m +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # diff --git a/trunk/arch/blackfin/configs/BF526-EZBRD_defconfig b/trunk/arch/blackfin/configs/BF526-EZBRD_defconfig index 8e2b855b8db7..992424ff3153 100644 --- a/trunk/arch/blackfin/configs/BF526-EZBRD_defconfig +++ b/trunk/arch/blackfin/configs/BF526-EZBRD_defconfig @@ -723,7 +723,7 @@ CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_DEVKMEM is not set -CONFIG_BFIN_JTAG_COMM=m +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # diff --git a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig index 833128b39724..21e3c1af55ba 100644 --- a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -767,7 +767,7 @@ CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_DEVKMEM is not set -CONFIG_BFIN_JTAG_COMM=m +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # diff --git a/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig index 334c94b51c40..0bdf20a1af61 100644 --- a/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig @@ -672,7 +672,7 @@ CONFIG_BFIN_DMA_INTERFACE=m CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set -CONFIG_BFIN_JTAG_COMM=m +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # diff --git a/trunk/arch/blackfin/configs/BF533-STAMP_defconfig b/trunk/arch/blackfin/configs/BF533-STAMP_defconfig index 9d733436e300..2f747d6e97e2 100644 --- a/trunk/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/trunk/arch/blackfin/configs/BF533-STAMP_defconfig @@ -679,7 +679,7 @@ CONFIG_BFIN_DMA_INTERFACE=m CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set -CONFIG_BFIN_JTAG_COMM=m +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # diff --git a/trunk/arch/blackfin/configs/BF537-STAMP_defconfig b/trunk/arch/blackfin/configs/BF537-STAMP_defconfig index 4fb4108d3103..8b0a81294e65 100644 --- a/trunk/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/trunk/arch/blackfin/configs/BF537-STAMP_defconfig @@ -722,7 +722,7 @@ CONFIG_BFIN_DMA_INTERFACE=m CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set -CONFIG_BFIN_JTAG_COMM=m +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # diff --git a/trunk/arch/blackfin/configs/BF538-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF538-EZKIT_defconfig index cb32f5624a1b..a1f766bf7d9b 100644 --- a/trunk/arch/blackfin/configs/BF538-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF538-EZKIT_defconfig @@ -726,7 +726,7 @@ CONFIG_BFIN_DMA_INTERFACE=m CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set -CONFIG_BFIN_JTAG_COMM=m +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # diff --git a/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig index 0f8697618aa5..cd2da6b7692c 100644 --- a/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -856,7 +856,7 @@ CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_DEVKMEM is not set -CONFIG_BFIN_JTAG_COMM=m +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # diff --git a/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig index 042c7adfccfa..b398ca202dbd 100644 --- a/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig @@ -709,7 +709,7 @@ CONFIG_BFIN_DMA_INTERFACE=m CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set -CONFIG_BFIN_JTAG_COMM=m +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # diff --git a/trunk/arch/blackfin/configs/CM-BF527_defconfig b/trunk/arch/blackfin/configs/CM-BF527_defconfig index 865ed85a5760..95146948166f 100644 --- a/trunk/arch/blackfin/configs/CM-BF527_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF527_defconfig @@ -1,6 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28 +# Linux kernel version: 2.6.24.7 +# Fri Jul 18 18:00:41 2008 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -8,6 +9,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y CONFIG_ZONE_DMA=y +CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y @@ -30,16 +32,18 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -# CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -48,35 +52,26 @@ CONFIG_EMBEDDED=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set -CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y CONFIG_EVENTFD=y -CONFIG_AIO=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -87,7 +82,6 @@ CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers @@ -101,11 +95,9 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -# CONFIG_FREEZER is not set # # Blackfin Processor Options @@ -114,10 +106,6 @@ CONFIG_PREEMPT_VOLUNTARY=y # # Processor and Board Settings # -# CONFIG_BF512 is not set -# CONFIG_BF514 is not set -# CONFIG_BF516 is not set -# CONFIG_BF518 is not set # CONFIG_BF522 is not set # CONFIG_BF523 is not set # CONFIG_BF524 is not set @@ -130,32 +118,48 @@ CONFIG_BF527=y # CONFIG_BF534 is not set # CONFIG_BF536 is not set # CONFIG_BF537 is not set -# CONFIG_BF538 is not set -# CONFIG_BF539 is not set # CONFIG_BF542 is not set -# CONFIG_BF542M is not set # CONFIG_BF544 is not set -# CONFIG_BF544M is not set # CONFIG_BF547 is not set -# CONFIG_BF547M is not set # CONFIG_BF548 is not set -# CONFIG_BF548M is not set # CONFIG_BF549 is not set -# CONFIG_BF549M is not set # CONFIG_BF561 is not set -CONFIG_BF_REV_MIN=0 -CONFIG_BF_REV_MAX=2 # CONFIG_BF_REV_0_0 is not set CONFIG_BF_REV_0_1=y # CONFIG_BF_REV_0_2 is not set # CONFIG_BF_REV_0_3 is not set # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set -# CONFIG_BF_REV_0_6 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF52x=y CONFIG_MEM_MT48LC16M16A2TG_75=y +# CONFIG_BFIN527_EZKIT is not set +CONFIG_BFIN527_BLUETECHNIX_CM=y + +# +# BF527 Specific Configuration +# + +# +# Alternative Multiplexing Scheme +# +# CONFIG_BF527_SPORT0_PORTF is not set +CONFIG_BF527_SPORT0_PORTG=y +CONFIG_BF527_SPORT0_TSCLK_PG10=y +# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set +CONFIG_BF527_UART1_PORTF=y +# CONFIG_BF527_UART1_PORTG is not set +# CONFIG_BF527_NAND_D_PORTF is not set +CONFIG_BF527_NAND_D_PORTH=y + +# +# Interrupt Priority Assignment +# + +# +# Priority +# CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_DMA0_ERROR=7 CONFIG_IRQ_DMAR0_BLK=7 @@ -175,6 +179,7 @@ CONFIG_IRQ_SPORT0_TX=9 CONFIG_IRQ_SPORT1_RX=9 CONFIG_IRQ_SPORT1_TX=9 CONFIG_IRQ_TWI=10 +CONFIG_IRQ_SPI=10 CONFIG_IRQ_UART0_RX=10 CONFIG_IRQ_UART0_TX=10 CONFIG_IRQ_UART1_RX=10 @@ -200,34 +205,6 @@ CONFIG_IRQ_MEM_DMA1=13 CONFIG_IRQ_WATCH=13 CONFIG_IRQ_PORTF_INTA=13 CONFIG_IRQ_PORTF_INTB=13 -# CONFIG_BFIN527_EZKIT is not set -CONFIG_BFIN527_BLUETECHNIX_CM=y -# CONFIG_BFIN526_EZBRD is not set - -# -# BF527 Specific Configuration -# - -# -# Alternative Multiplexing Scheme -# -# CONFIG_BF527_SPORT0_PORTF is not set -CONFIG_BF527_SPORT0_PORTG=y -CONFIG_BF527_SPORT0_TSCLK_PG10=y -# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set -CONFIG_BF527_UART1_PORTF=y -# CONFIG_BF527_UART1_PORTG is not set -# CONFIG_BF527_NAND_D_PORTF is not set -CONFIG_BF527_NAND_D_PORTH=y - -# -# Interrupt Priority Assignment -# - -# -# Priority -# -CONFIG_IRQ_SPI=10 CONFIG_IRQ_SPI_ERROR=7 CONFIG_IRQ_NFC_ERROR=7 CONFIG_IRQ_HDMA_ERROR=7 @@ -249,6 +226,7 @@ CONFIG_BOOT_LOAD=0x1000 # CONFIG_CLKIN_HZ=25000000 # CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=600000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -262,10 +240,10 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_CYCLES_CLOCKSOURCE is not set +# CONFIG_TICK_ONESHOT is not set # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set CONFIG_GENERIC_CLOCKEVENTS_BUILD=y @@ -299,12 +277,6 @@ CONFIG_ACCESS_OK_L1=y CONFIG_CACHELINE_ALIGNED_L1=y # CONFIG_SYSCALL_TAB_L1 is not set # CONFIG_CPLB_SWITCH_TAB_L1 is not set -CONFIG_APP_STACK_L1=y - -# -# Speed Optimizations -# -CONFIG_BFIN_INS_LOWOVERHEAD=y CONFIG_RAMKERNEL=y # CONFIG_ROMKERNEL is not set CONFIG_SELECT_MEMORY_MODEL=y @@ -313,10 +285,10 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_PAGEFLAGS_EXTENDED=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set -# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y CONFIG_BFIN_GPTIMERS=y @@ -362,6 +334,7 @@ CONFIG_BANK_3=0xFFC0 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # +# CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCCARD is not set @@ -372,20 +345,25 @@ CONFIG_BINFMT_ELF_FDPIC=y CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_ZFLAT=y # CONFIG_BINFMT_SHARED_FLAT is not set -# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set # # Power management options # # CONFIG_PM is not set -CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_SUSPEND_UP_POSSIBLE=y +# CONFIG_PM_BFIN_SLEEP_DEEPER is not set +# CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set # # CPU Frequency scaling # # CONFIG_CPU_FREQ is not set + +# +# Networking +# CONFIG_NET=y # @@ -398,7 +376,6 @@ CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -428,6 +405,8 @@ CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set # CONFIG_NETLABEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -436,7 +415,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set @@ -453,14 +431,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y + +# +# Wireless +# # CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y # CONFIG_WIRELESS_EXT is not set # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set @@ -478,8 +456,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set CONFIG_MTD=y @@ -488,7 +464,6 @@ CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers @@ -532,7 +507,6 @@ CONFIG_MTD_ROM=m # CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_GPIO_ADDR is not set # CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set @@ -568,12 +542,10 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_XIP is not set +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# CONFIG_BLK_DEV_HD is not set # CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -586,6 +558,7 @@ CONFIG_HAVE_IDE=y # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set @@ -606,7 +579,6 @@ CONFIG_PHYLIB=y # CONFIG_SMSC_PHY is not set # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -619,14 +591,11 @@ CONFIG_BFIN_MAC_RMII=y # CONFIG_SMC91X is not set # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set -# CONFIG_ENC28J60 is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -635,7 +604,6 @@ CONFIG_BFIN_MAC_RMII=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # # USB Network Adapters @@ -648,6 +616,7 @@ CONFIG_BFIN_MAC_RMII=y # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set +# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -673,15 +642,14 @@ CONFIG_BFIN_MAC_RMII=y # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set -# CONFIG_BF5xx_EPPI is not set +CONFIG_BFIN_OTP=y +# CONFIG_BFIN_OTP_WRITE_ENABLE is not set # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_TWI_LCD is not set -CONFIG_BFIN_DMA_INTERFACE=m CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set -# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -705,8 +673,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set -CONFIG_BFIN_OTP=y -# CONFIG_BFIN_OTP_WRITE_ENABLE is not set # # CAN, the car bus and industrial fieldbus @@ -714,49 +680,44 @@ CONFIG_BFIN_OTP=y # CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set +# CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=m -CONFIG_I2C_HELPER_AUTO=y # -# I2C Hardware Bus support +# I2C Algorithms # +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set # -# I2C system bus drivers (mostly embedded / system-on-chip) +# I2C Hardware Bus support # CONFIG_I2C_BLACKFIN_TWI=m CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # CONFIG_I2C_GPIO is not set # CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# # CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set # # Miscellaneous I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set # CONFIG_DS1682 is not set -# CONFIG_AT24 is not set # CONFIG_SENSORS_AD5252 is not set -# CONFIG_SENSORS_EEPROM is not set +# CONFIG_EEPROM_LEGACY is not set # CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCF8575 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set @@ -765,41 +726,37 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y # # SPI Master Controller Drivers # CONFIG_SPI_BFIN=y -# CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BITBANG is not set # # SPI Protocol Masters # -# CONFIG_SPI_AT25 is not set +# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -# CONFIG_GPIOLIB is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD7414 is not set # CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set @@ -820,7 +777,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set @@ -829,7 +785,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set @@ -837,12 +792,9 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83793 is not set # CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -858,31 +810,21 @@ CONFIG_BFIN_WDT=y # CONFIG_USBPCWATCHDOG is not set # -# Multifunction device drivers +# Sonics Silicon Backplane # -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_REGULATOR is not set +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # -# Multimedia devices +# Multifunction device drivers # +# CONFIG_MFD_SM501 is not set # -# Multimedia core support +# Multimedia devices # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# # CONFIG_DAB is not set # @@ -897,6 +839,10 @@ CONFIG_BFIN_WDT=y # Display device support # # CONFIG_DISPLAY_SUPPORT is not set + +# +# Sound +# # CONFIG_SOUND is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y @@ -904,7 +850,6 @@ CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_EHCI is not set CONFIG_USB=y # CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # # Miscellaneous USB options @@ -915,48 +860,40 @@ CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set CONFIG_USB_OTG_BLACKLIST_HUB=y -CONFIG_USB_MON=y -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers # -# CONFIG_USB_C67X00_HCD is not set # CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set # CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_HWA_HCD is not set CONFIG_USB_MUSB_HDRC=y CONFIG_USB_MUSB_SOC=y # -# Blackfin high speed USB Support +# Blackfin high speed USB support # CONFIG_USB_MUSB_HOST=y # CONFIG_USB_MUSB_PERIPHERAL is not set # CONFIG_USB_MUSB_OTG is not set CONFIG_USB_MUSB_HDRC_HCD=y CONFIG_MUSB_PIO_ONLY=y -CONFIG_MUSB_DMA_POLL=y -# CONFIG_USB_MUSB_DEBUG is not set +CONFIG_USB_MUSB_LOGLEVEL=0 # # USB Device Class drivers # # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # # -# see USB_STORAGE Help for more information +# may also be needed; see USB_STORAGE Help for more information # # CONFIG_USB_LIBUSUAL is not set @@ -964,10 +901,15 @@ CONFIG_MUSB_DMA_POLL=y # USB Imaging devices # # CONFIG_USB_MDC800 is not set +CONFIG_USB_MON=y # # USB port drivers # + +# +# USB Serial Converter support +# # CONFIG_USB_SERIAL is not set # @@ -976,7 +918,7 @@ CONFIG_MUSB_DMA_POLL=y # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set @@ -992,13 +934,17 @@ CONFIG_MUSB_DMA_POLL=y # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -1027,59 +973,51 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set # # SPI RTC drivers # -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_MAX6902 is not set # # Platform RTC drivers # -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_V3020 is not set # # on-CPU RTC drivers # CONFIG_RTC_DRV_BFIN=y -# CONFIG_DMADEVICES is not set + +# +# Userspace I/O +# # CONFIG_UIO is not set -# CONFIG_STAGING is not set # # File systems # # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set -# CONFIG_EXT4_FS is not set +# CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_DNOTIFY is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -1121,11 +1059,8 @@ CONFIG_SYSFS=y # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set CONFIG_NETWORK_FILESYSTEMS=y @@ -1133,12 +1068,13 @@ CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set +# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1194,6 +1130,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set # CONFIG_DLM is not set +# CONFIG_INSTRUMENTATION is not set # # Kernel hacking @@ -1201,61 +1138,14 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -# CONFIG_SCHED_DEBUG is not set -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_FRAME_POINTER is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_KGDB_TESTCASE is not set -CONFIG_DEBUG_VERBOSE=y CONFIG_DEBUG_MMRS=y -# CONFIG_DEBUG_HWERR is not set -# CONFIG_DEBUG_DOUBLEFAULT is not set CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y @@ -1264,7 +1154,7 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -# CONFIG_EARLY_PRINTK is not set +CONFIG_EARLY_PRINTK=y # CONFIG_CPLB_INFO is not set CONFIG_ACCESS_CHECK=y @@ -1273,96 +1163,10 @@ CONFIG_ACCESS_CHECK=y # # CONFIG_KEYS is not set CONFIG_SECURITY=y -# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_CAPABILITIES is not set # CONFIG_SECURITY_ROOTPLUG is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_FIPS is not set -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_MANAGER2 is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO is not set # # Library routines @@ -1370,7 +1174,6 @@ CONFIG_CRYPTO_HW=y CONFIG_BITREVERSE=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set -# CONFIG_CRC_T10DIF is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_CRC7 is not set diff --git a/trunk/arch/blackfin/include/asm/checksum.h b/trunk/arch/blackfin/include/asm/checksum.h index 793581fc9556..f67289a0d8d2 100644 --- a/trunk/arch/blackfin/include/asm/checksum.h +++ b/trunk/arch/blackfin/include/asm/checksum.h @@ -63,23 +63,23 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, __wsum sum) { - unsigned int carry; - - __asm__ ("%0 = %0 + %2;\n\t" - "CC = AC0;\n\t" - "%1 = CC;\n\t" - "%0 = %0 + %1;\n\t" - "%0 = %0 + %3;\n\t" - "CC = AC0;\n\t" - "%1 = CC;\n\t" - "%0 = %0 + %1;\n\t" - "%0 = %0 + %4;\n\t" - "CC = AC0;\n\t" - "%1 = CC;\n\t" - "%0 = %0 + %1;\n\t" - : "=d" (sum), "=&d" (carry) - : "d" (daddr), "d" (saddr), "d" ((len + proto) << 8), "0"(sum) - : "CC"); + + __asm__ ("%0 = %0 + %1;\n\t" + "CC = AC0;\n\t" + "if !CC jump 4;\n\t" + "%0 = %0 + %4;\n\t" + "%0 = %0 + %2;\n\t" + "CC = AC0;\n\t" + "if !CC jump 4;\n\t" + "%0 = %0 + %4;\n\t" + "%0 = %0 + %3;\n\t" + "CC = AC0;\n\t" + "if !CC jump 4;\n\t" + "%0 = %0 + %4;\n\t" + "NOP;\n\t" + : "=d" (sum) + : "d" (daddr), "d" (saddr), "d" ((ntohs(len)<<16)+proto*256), "d" (1), "0"(sum) + : "CC"); return (sum); } diff --git a/trunk/arch/blackfin/include/asm/delay.h b/trunk/arch/blackfin/include/asm/delay.h index c31f91cc1d5d..0889c3abb593 100644 --- a/trunk/arch/blackfin/include/asm/delay.h +++ b/trunk/arch/blackfin/include/asm/delay.h @@ -13,7 +13,29 @@ static inline void __delay(unsigned long loops) { -__asm__ __volatile__ ( + if (ANOMALY_05000312) { + /* Interrupted loads to loop registers -> bad */ + unsigned long tmp; + __asm__ __volatile__( + "[--SP] = LC0;" + "[--SP] = LT0;" + "[--SP] = LB0;" + "LSETUP (1f,1f) LC0 = %1;" + "1: NOP;" + /* We take advantage of the fact that LC0 is 0 at + * the end of the loop. Otherwise we'd need some + * NOPs after the CLI here. + */ + "CLI %0;" + "LB0 = [SP++];" + "LT0 = [SP++];" + "LC0 = [SP++];" + "STI %0;" + : "=d" (tmp) + : "a" (loops) + ); + } else + __asm__ __volatile__ ( "LSETUP(1f, 1f) LC0 = %0;" "1: NOP;" : @@ -25,15 +47,16 @@ __asm__ __volatile__ ( #include /* needed for HZ */ /* - * close approximation borrowed from m68knommu to avoid 64-bit math + * Use only for very small delays ( < 1 msec). Should probably use a + * lookup table, really, as the multiplications take much too long with + * short delays. This is a "reasonable" implementation, though (and the + * first constant multiplications gets optimized away if the delay is + * a constant) */ - -#define HZSCALE (268435456 / (1000000/HZ)) - static inline void udelay(unsigned long usecs) { extern unsigned long loops_per_jiffy; - __delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6); + __delay(usecs * loops_per_jiffy / (1000000 / HZ)); } #endif diff --git a/trunk/arch/blackfin/include/asm/gpio.h b/trunk/arch/blackfin/include/asm/gpio.h index d4a082ef75b4..9477d82fcad2 100644 --- a/trunk/arch/blackfin/include/asm/gpio.h +++ b/trunk/arch/blackfin/include/asm/gpio.h @@ -27,6 +27,60 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +/* +* Number BF537/6/4 BF561 BF533/2/1 +* BF527/5/2 +* +* GPIO_0 PF0 PF0 PF0 +* GPIO_1 PF1 PF1 PF1 +* GPIO_2 PF2 PF2 PF2 +* GPIO_3 PF3 PF3 PF3 +* GPIO_4 PF4 PF4 PF4 +* GPIO_5 PF5 PF5 PF5 +* GPIO_6 PF6 PF6 PF6 +* GPIO_7 PF7 PF7 PF7 +* GPIO_8 PF8 PF8 PF8 +* GPIO_9 PF9 PF9 PF9 +* GPIO_10 PF10 PF10 PF10 +* GPIO_11 PF11 PF11 PF11 +* GPIO_12 PF12 PF12 PF12 +* GPIO_13 PF13 PF13 PF13 +* GPIO_14 PF14 PF14 PF14 +* GPIO_15 PF15 PF15 PF15 +* GPIO_16 PG0 PF16 +* GPIO_17 PG1 PF17 +* GPIO_18 PG2 PF18 +* GPIO_19 PG3 PF19 +* GPIO_20 PG4 PF20 +* GPIO_21 PG5 PF21 +* GPIO_22 PG6 PF22 +* GPIO_23 PG7 PF23 +* GPIO_24 PG8 PF24 +* GPIO_25 PG9 PF25 +* GPIO_26 PG10 PF26 +* GPIO_27 PG11 PF27 +* GPIO_28 PG12 PF28 +* GPIO_29 PG13 PF29 +* GPIO_30 PG14 PF30 +* GPIO_31 PG15 PF31 +* GPIO_32 PH0 PF32 +* GPIO_33 PH1 PF33 +* GPIO_34 PH2 PF34 +* GPIO_35 PH3 PF35 +* GPIO_36 PH4 PF36 +* GPIO_37 PH5 PF37 +* GPIO_38 PH6 PF38 +* GPIO_39 PH7 PF39 +* GPIO_40 PH8 PF40 +* GPIO_41 PH9 PF41 +* GPIO_42 PH10 PF42 +* GPIO_43 PH11 PF43 +* GPIO_44 PH12 PF44 +* GPIO_45 PH13 PF45 +* GPIO_46 PH14 PF46 +* GPIO_47 PH15 PF47 +*/ + #ifndef __ARCH_BLACKFIN_GPIO_H__ #define __ARCH_BLACKFIN_GPIO_H__ @@ -241,6 +295,10 @@ int bfin_gpio_direction_output(unsigned gpio, int value); int bfin_gpio_get_value(unsigned gpio); void bfin_gpio_set_value(unsigned gpio, int value); +#ifndef BF548_FAMILY +#define bfin_gpio_set_value(gpio, value) set_gpio_data(gpio, value) +#endif + #ifdef CONFIG_GPIOLIB #include /* cansleep wrappers */ diff --git a/trunk/arch/blackfin/include/asm/kgdb.h b/trunk/arch/blackfin/include/asm/kgdb.h index c8b256d2ea30..26ebac6646d8 100644 --- a/trunk/arch/blackfin/include/asm/kgdb.h +++ b/trunk/arch/blackfin/include/asm/kgdb.h @@ -1,8 +1,32 @@ -/* Blackfin KGDB header +/* + * File: include/asm-blackfin/kgdb.h + * Based on: + * Author: Sonic Zhang + * + * Created: + * Description: + * + * Rev: $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $ + * + * Modified: + * Copyright 2005-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ * - * Copyright 2005-2009 Analog Devices Inc. + * 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. * - * Licensed under the GPL-2 or later. + * 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, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __ASM_BLACKFIN_KGDB_H__ @@ -13,18 +37,17 @@ /* gdb locks */ #define KGDB_MAX_NO_CPUS 8 -/* - * BUFMAX defines the maximum number of characters in inbound/outbound buffers. - * At least NUMREGBYTES*2 are needed for register packets. - * Longer buffer is needed to list all threads. - */ +/************************************************************************/ +/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ +/* at least NUMREGBYTES*2 are needed for register packets */ +/* Longer buffer is needed to list all threads */ #define BUFMAX 2048 /* - * Note that this register image is different from - * the register image that Linux produces at interrupt time. - * - * Linux's register image is defined by struct pt_regs in ptrace.h. + * Note that this register image is different from + * the register image that Linux produces at interrupt time. + * + * Linux's register image is defined by struct pt_regs in ptrace.h. */ enum regnames { /* Core Registers */ @@ -81,14 +104,14 @@ enum regnames { BFIN_RETX, BFIN_RETN, BFIN_RETE, - + /* Pseudo Registers */ BFIN_PC, BFIN_CC, BFIN_EXTRA1, /* Address of .text section. */ BFIN_EXTRA2, /* Address of .data section. */ BFIN_EXTRA3, /* Address of .bss section. */ - BFIN_FDPIC_EXEC, + BFIN_FDPIC_EXEC, BFIN_FDPIC_INTERP, /* MMRs */ @@ -103,7 +126,7 @@ enum regnames { static inline void arch_kgdb_breakpoint(void) { - asm("EXCPT 2;"); + asm(" EXCPT 2;"); } #define BREAK_INSTR_SIZE 2 #define CACHE_FLUSH_IS_SAFE 1 diff --git a/trunk/arch/blackfin/include/asm/mem_init.h b/trunk/arch/blackfin/include/asm/mem_init.h index 61f7487fbf12..255a9316ad36 100644 --- a/trunk/arch/blackfin/include/asm/mem_init.h +++ b/trunk/arch/blackfin/include/asm/mem_init.h @@ -115,7 +115,7 @@ #define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) /* Enable SCLK Out */ -#define mem_SDGCTL (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS) +#define mem_SDGCTL (0x80000000 | SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS) #else #define mem_SDRRC CONFIG_MEM_SDRRC #define mem_SDGCTL CONFIG_MEM_SDGCTL diff --git a/trunk/arch/blackfin/include/asm/pda.h b/trunk/arch/blackfin/include/asm/pda.h index a67142740df0..bd8d4a7efeb2 100644 --- a/trunk/arch/blackfin/include/asm/pda.h +++ b/trunk/arch/blackfin/include/asm/pda.h @@ -59,7 +59,6 @@ struct blackfin_pda { /* Per-processor Data Area */ unsigned long icplb_fault_addr; unsigned long retx; unsigned long seqstat; - unsigned int __nmi_count; /* number of times NMI asserted on this CPU */ }; extern struct blackfin_pda cpu_pda[]; diff --git a/trunk/arch/blackfin/include/asm/reboot.h b/trunk/arch/blackfin/include/asm/reboot.h index ae1e36329bec..4856d62b7467 100644 --- a/trunk/arch/blackfin/include/asm/reboot.h +++ b/trunk/arch/blackfin/include/asm/reboot.h @@ -15,6 +15,6 @@ extern void native_machine_halt(void); extern void native_machine_power_off(void); /* common reboot workarounds */ -extern void bfin_reset_boot_spi_cs(unsigned short pin); +extern void bfin_gpio_reset_spi0_ssel1(void); #endif diff --git a/trunk/arch/blackfin/kernel/Makefile b/trunk/arch/blackfin/kernel/Makefile index 4a92a86824b7..38a233374f07 100644 --- a/trunk/arch/blackfin/kernel/Makefile +++ b/trunk/arch/blackfin/kernel/Makefile @@ -15,8 +15,6 @@ else obj-y += time.o endif -CFLAGS_kgdb_test.o := -mlong-calls -O0 - obj-$(CONFIG_IPIPE) += ipipe.o obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount.o obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o diff --git a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c b/trunk/arch/blackfin/kernel/bfin_dma_5xx.c index 8531693fb48d..07e02c0d1c07 100644 --- a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/trunk/arch/blackfin/kernel/bfin_dma_5xx.c @@ -249,13 +249,6 @@ static void __dma_memcpy(u32 daddr, s16 dmod, u32 saddr, s16 smod, size_t cnt, u spin_lock_irqsave(&mdma_lock, flags); - /* Force a sync in case a previous config reset on this channel - * occurred. This is needed so subsequent writes to DMA registers - * are not spuriously lost/corrupted. Do it under irq lock and - * without the anomaly version (because we are atomic already). - */ - __builtin_bfin_ssync(); - if (bfin_read_MDMA_S0_CONFIG()) while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) continue; diff --git a/trunk/arch/blackfin/kernel/bfin_gpio.c b/trunk/arch/blackfin/kernel/bfin_gpio.c index 51dac55c524a..4c14331978f6 100644 --- a/trunk/arch/blackfin/kernel/bfin_gpio.c +++ b/trunk/arch/blackfin/kernel/bfin_gpio.c @@ -27,6 +27,59 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +/* +* Number BF537/6/4 BF561 BF533/2/1 BF549/8/4/2 +* +* GPIO_0 PF0 PF0 PF0 PA0...PJ13 +* GPIO_1 PF1 PF1 PF1 +* GPIO_2 PF2 PF2 PF2 +* GPIO_3 PF3 PF3 PF3 +* GPIO_4 PF4 PF4 PF4 +* GPIO_5 PF5 PF5 PF5 +* GPIO_6 PF6 PF6 PF6 +* GPIO_7 PF7 PF7 PF7 +* GPIO_8 PF8 PF8 PF8 +* GPIO_9 PF9 PF9 PF9 +* GPIO_10 PF10 PF10 PF10 +* GPIO_11 PF11 PF11 PF11 +* GPIO_12 PF12 PF12 PF12 +* GPIO_13 PF13 PF13 PF13 +* GPIO_14 PF14 PF14 PF14 +* GPIO_15 PF15 PF15 PF15 +* GPIO_16 PG0 PF16 +* GPIO_17 PG1 PF17 +* GPIO_18 PG2 PF18 +* GPIO_19 PG3 PF19 +* GPIO_20 PG4 PF20 +* GPIO_21 PG5 PF21 +* GPIO_22 PG6 PF22 +* GPIO_23 PG7 PF23 +* GPIO_24 PG8 PF24 +* GPIO_25 PG9 PF25 +* GPIO_26 PG10 PF26 +* GPIO_27 PG11 PF27 +* GPIO_28 PG12 PF28 +* GPIO_29 PG13 PF29 +* GPIO_30 PG14 PF30 +* GPIO_31 PG15 PF31 +* GPIO_32 PH0 PF32 +* GPIO_33 PH1 PF33 +* GPIO_34 PH2 PF34 +* GPIO_35 PH3 PF35 +* GPIO_36 PH4 PF36 +* GPIO_37 PH5 PF37 +* GPIO_38 PH6 PF38 +* GPIO_39 PH7 PF39 +* GPIO_40 PH8 PF40 +* GPIO_41 PH9 PF41 +* GPIO_42 PH10 PF42 +* GPIO_43 PH11 PF43 +* GPIO_44 PH12 PF44 +* GPIO_45 PH13 PF45 +* GPIO_46 PH14 PF46 +* GPIO_47 PH15 PF47 +*/ + #include #include #include @@ -66,61 +119,62 @@ enum { #define AWA_DUMMY_READ(...) do { } while (0) #endif -static struct gpio_port_t * const gpio_array[] = { #if defined(BF533_FAMILY) || defined(BF538_FAMILY) +static struct gpio_port_t *gpio_bankb[] = { (struct gpio_port_t *) FIO_FLAG_D, -#elif defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) +}; +#endif + +#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) +static struct gpio_port_t *gpio_bankb[] = { (struct gpio_port_t *) PORTFIO, (struct gpio_port_t *) PORTGIO, (struct gpio_port_t *) PORTHIO, -#elif defined(BF561_FAMILY) - (struct gpio_port_t *) FIO0_FLAG_D, - (struct gpio_port_t *) FIO1_FLAG_D, - (struct gpio_port_t *) FIO2_FLAG_D, -#elif defined(BF548_FAMILY) - (struct gpio_port_t *)PORTA_FER, - (struct gpio_port_t *)PORTB_FER, - (struct gpio_port_t *)PORTC_FER, - (struct gpio_port_t *)PORTD_FER, - (struct gpio_port_t *)PORTE_FER, - (struct gpio_port_t *)PORTF_FER, - (struct gpio_port_t *)PORTG_FER, - (struct gpio_port_t *)PORTH_FER, - (struct gpio_port_t *)PORTI_FER, - (struct gpio_port_t *)PORTJ_FER, -#else -# error no gpio arrays defined -#endif }; -#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) -static unsigned short * const port_fer[] = { +static unsigned short *port_fer[] = { (unsigned short *) PORTF_FER, (unsigned short *) PORTG_FER, (unsigned short *) PORTH_FER, }; +#endif -# if !defined(BF537_FAMILY) -static unsigned short * const port_mux[] = { +#if defined(BF527_FAMILY) || defined(BF518_FAMILY) +static unsigned short *port_mux[] = { (unsigned short *) PORTF_MUX, (unsigned short *) PORTG_MUX, (unsigned short *) PORTH_MUX, }; static const -u8 pmux_offset[][16] = { -# if defined(BF527_FAMILY) - { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */ - { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */ - { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */ -# elif defined(BF518_FAMILY) - { 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */ - { 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */ - { 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */ -# endif +u8 pmux_offset[][16] = + {{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */ + { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */ + { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */ + }; +#endif + +#ifdef BF561_FAMILY +static struct gpio_port_t *gpio_bankb[] = { + (struct gpio_port_t *) FIO0_FLAG_D, + (struct gpio_port_t *) FIO1_FLAG_D, + (struct gpio_port_t *) FIO2_FLAG_D, }; -# endif +#endif +#ifdef BF548_FAMILY +static struct gpio_port_t *gpio_array[] = { + (struct gpio_port_t *)PORTA_FER, + (struct gpio_port_t *)PORTB_FER, + (struct gpio_port_t *)PORTC_FER, + (struct gpio_port_t *)PORTD_FER, + (struct gpio_port_t *)PORTE_FER, + (struct gpio_port_t *)PORTF_FER, + (struct gpio_port_t *)PORTG_FER, + (struct gpio_port_t *)PORTH_FER, + (struct gpio_port_t *)PORTI_FER, + (struct gpio_port_t *)PORTJ_FER, +}; #endif static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; @@ -134,9 +188,35 @@ static struct str_ident { } str_ident[MAX_RESOURCES]; #if defined(CONFIG_PM) +#if defined(CONFIG_BF54x) +static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; +#else +static unsigned short wakeup_map[GPIO_BANK_NUM]; +static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; + +#ifdef BF533_FAMILY +static unsigned int sic_iwr_irqs[] = {IRQ_PROG_INTB}; +#endif + +#ifdef BF537_FAMILY +static unsigned int sic_iwr_irqs[] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX}; +#endif + +#ifdef BF538_FAMILY +static unsigned int sic_iwr_irqs[] = {IRQ_PORTF_INTB}; #endif +#if defined(BF527_FAMILY) || defined(BF518_FAMILY) +static unsigned int sic_iwr_irqs[] = {IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB}; +#endif + +#ifdef BF561_FAMILY +static unsigned int sic_iwr_irqs[] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; +#endif +#endif +#endif /* CONFIG_PM */ + inline int check_gpio(unsigned gpio) { #if defined(BF548_FAMILY) @@ -250,10 +330,9 @@ static struct { {.res = P_SPI0_SSEL3, .offset = 0}, }; -static void portmux_setup(unsigned short per) +static void portmux_setup(unsigned short per, unsigned short function) { u16 y, offset, muxreg; - u16 function = P_FUNCT2MUX(per); for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) { if (port_mux_lut[y].res == per) { @@ -274,33 +353,30 @@ static void portmux_setup(unsigned short per) } } #elif defined(BF548_FAMILY) -inline void portmux_setup(unsigned short per) +inline void portmux_setup(unsigned short portno, unsigned short function) { u32 pmux; - u16 ident = P_IDENT(per); - u16 function = P_FUNCT2MUX(per); - pmux = gpio_array[gpio_bank(ident)]->port_mux; + pmux = gpio_array[gpio_bank(portno)]->port_mux; - pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); - pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); + pmux &= ~(0x3 << (2 * gpio_sub_n(portno))); + pmux |= (function & 0x3) << (2 * gpio_sub_n(portno)); - gpio_array[gpio_bank(ident)]->port_mux = pmux; + gpio_array[gpio_bank(portno)]->port_mux = pmux; } -inline u16 get_portmux(unsigned short per) +inline u16 get_portmux(unsigned short portno) { u32 pmux; - u16 ident = P_IDENT(per); - pmux = gpio_array[gpio_bank(ident)]->port_mux; + pmux = gpio_array[gpio_bank(portno)]->port_mux; - return (pmux >> (2 * gpio_sub_n(ident)) & 0x3); + return (pmux >> (2 * gpio_sub_n(portno)) & 0x3); } #elif defined(BF527_FAMILY) || defined(BF518_FAMILY) -inline void portmux_setup(unsigned short per) +inline void portmux_setup(unsigned short portno, unsigned short function) { - u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per); + u16 pmux, ident = P_IDENT(portno); u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)]; pmux = *port_mux[gpio_bank(ident)]; @@ -348,71 +424,90 @@ void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ unsigned long flags; \ local_irq_save_hw(flags); \ if (arg) \ - gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ + gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ else \ - gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ + gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ AWA_DUMMY_READ(name); \ local_irq_restore_hw(flags); \ } \ EXPORT_SYMBOL(set_gpio_ ## name); -SET_GPIO(dir) /* set_gpio_dir() */ -SET_GPIO(inen) /* set_gpio_inen() */ -SET_GPIO(polar) /* set_gpio_polar() */ -SET_GPIO(edge) /* set_gpio_edge() */ -SET_GPIO(both) /* set_gpio_both() */ +SET_GPIO(dir) +SET_GPIO(inen) +SET_GPIO(polar) +SET_GPIO(edge) +SET_GPIO(both) +#if ANOMALY_05000311 || ANOMALY_05000323 #define SET_GPIO_SC(name) \ void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ { \ unsigned long flags; \ - if (ANOMALY_05000311 || ANOMALY_05000323) \ - local_irq_save_hw(flags); \ + local_irq_save_hw(flags); \ + if (arg) \ + gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ + else \ + gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ + AWA_DUMMY_READ(name); \ + local_irq_restore_hw(flags); \ +} \ +EXPORT_SYMBOL(set_gpio_ ## name); +#else +#define SET_GPIO_SC(name) \ +void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ +{ \ if (arg) \ - gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ + gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ else \ - gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ - if (ANOMALY_05000311 || ANOMALY_05000323) { \ - AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ - } \ + gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ } \ EXPORT_SYMBOL(set_gpio_ ## name); +#endif SET_GPIO_SC(maska) SET_GPIO_SC(maskb) SET_GPIO_SC(data) +#if ANOMALY_05000311 || ANOMALY_05000323 void set_gpio_toggle(unsigned gpio) { unsigned long flags; - if (ANOMALY_05000311 || ANOMALY_05000323) - local_irq_save_hw(flags); - gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio); - if (ANOMALY_05000311 || ANOMALY_05000323) { - AWA_DUMMY_READ(toggle); - local_irq_restore_hw(flags); - } + local_irq_save_hw(flags); + gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); + AWA_DUMMY_READ(toggle); + local_irq_restore_hw(flags); +} +#else +void set_gpio_toggle(unsigned gpio) +{ + gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); } +#endif EXPORT_SYMBOL(set_gpio_toggle); /*Set current PORT date (16-bit word)*/ +#if ANOMALY_05000311 || ANOMALY_05000323 #define SET_GPIO_P(name) \ void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ { \ unsigned long flags; \ - if (ANOMALY_05000311 || ANOMALY_05000323) \ - local_irq_save_hw(flags); \ - gpio_array[gpio_bank(gpio)]->name = arg; \ - if (ANOMALY_05000311 || ANOMALY_05000323) { \ - AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ - } \ + local_irq_save_hw(flags); \ + gpio_bankb[gpio_bank(gpio)]->name = arg; \ + AWA_DUMMY_READ(name); \ + local_irq_restore_hw(flags); \ } \ EXPORT_SYMBOL(set_gpiop_ ## name); +#else +#define SET_GPIO_P(name) \ +void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ +{ \ + gpio_bankb[gpio_bank(gpio)]->name = arg; \ +} \ +EXPORT_SYMBOL(set_gpiop_ ## name); +#endif SET_GPIO_P(data) SET_GPIO_P(dir) @@ -424,21 +519,27 @@ SET_GPIO_P(maska) SET_GPIO_P(maskb) /* Get a specific bit */ +#if ANOMALY_05000311 || ANOMALY_05000323 #define GET_GPIO(name) \ unsigned short get_gpio_ ## name(unsigned gpio) \ { \ unsigned long flags; \ unsigned short ret; \ - if (ANOMALY_05000311 || ANOMALY_05000323) \ - local_irq_save_hw(flags); \ - ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \ - if (ANOMALY_05000311 || ANOMALY_05000323) { \ - AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ - } \ + local_irq_save_hw(flags); \ + ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \ + AWA_DUMMY_READ(name); \ + local_irq_restore_hw(flags); \ return ret; \ } \ EXPORT_SYMBOL(get_gpio_ ## name); +#else +#define GET_GPIO(name) \ +unsigned short get_gpio_ ## name(unsigned gpio) \ +{ \ + return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ +} \ +EXPORT_SYMBOL(get_gpio_ ## name); +#endif GET_GPIO(data) GET_GPIO(dir) @@ -451,21 +552,27 @@ GET_GPIO(maskb) /*Get current PORT date (16-bit word)*/ +#if ANOMALY_05000311 || ANOMALY_05000323 #define GET_GPIO_P(name) \ unsigned short get_gpiop_ ## name(unsigned gpio) \ { \ unsigned long flags; \ unsigned short ret; \ - if (ANOMALY_05000311 || ANOMALY_05000323) \ - local_irq_save_hw(flags); \ - ret = (gpio_array[gpio_bank(gpio)]->name); \ - if (ANOMALY_05000311 || ANOMALY_05000323) { \ - AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ - } \ + local_irq_save_hw(flags); \ + ret = (gpio_bankb[gpio_bank(gpio)]->name); \ + AWA_DUMMY_READ(name); \ + local_irq_restore_hw(flags); \ return ret; \ } \ EXPORT_SYMBOL(get_gpiop_ ## name); +#else +#define GET_GPIO_P(name) \ +unsigned short get_gpiop_ ## name(unsigned gpio) \ +{ \ + return (gpio_bankb[gpio_bank(gpio)]->name);\ +} \ +EXPORT_SYMBOL(get_gpiop_ ## name); +#endif GET_GPIO_P(data) GET_GPIO_P(dir) @@ -478,26 +585,6 @@ GET_GPIO_P(maskb) #ifdef CONFIG_PM - -static unsigned short wakeup_map[GPIO_BANK_NUM]; -static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; - -static const unsigned int sic_iwr_irqs[] = { -#if defined(BF533_FAMILY) - IRQ_PROG_INTB -#elif defined(BF537_FAMILY) - IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX -#elif defined(BF538_FAMILY) - IRQ_PORTF_INTB -#elif defined(BF527_FAMILY) || defined(BF518_FAMILY) - IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB -#elif defined(BF561_FAMILY) - IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB -#else -# error no SIC_IWR defined -#endif -}; - /*********************************************************** * * FUNCTIONS: Blackfin PM Setup API @@ -582,18 +669,18 @@ u32 bfin_pm_standby_setup(void) mask = wakeup_map[gpio_bank(i)]; bank = gpio_bank(i); - gpio_bank_saved[bank].maskb = gpio_array[bank]->maskb; - gpio_array[bank]->maskb = 0; + gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb; + gpio_bankb[bank]->maskb = 0; if (mask) { #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) gpio_bank_saved[bank].fer = *port_fer[bank]; #endif - gpio_bank_saved[bank].inen = gpio_array[bank]->inen; - gpio_bank_saved[bank].polar = gpio_array[bank]->polar; - gpio_bank_saved[bank].dir = gpio_array[bank]->dir; - gpio_bank_saved[bank].edge = gpio_array[bank]->edge; - gpio_bank_saved[bank].both = gpio_array[bank]->both; + gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; + gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; + gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; + gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; + gpio_bank_saved[bank].both = gpio_bankb[bank]->both; gpio_bank_saved[bank].reserved = reserved_gpio_map[bank]; @@ -613,7 +700,7 @@ u32 bfin_pm_standby_setup(void) } bfin_internal_set_wake(sic_iwr_irqs[bank], 1); - gpio_array[bank]->maskb_set = wakeup_map[gpio_bank(i)]; + gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)]; } } @@ -634,18 +721,18 @@ void bfin_pm_standby_restore(void) #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) *port_fer[bank] = gpio_bank_saved[bank].fer; #endif - gpio_array[bank]->inen = gpio_bank_saved[bank].inen; - gpio_array[bank]->dir = gpio_bank_saved[bank].dir; - gpio_array[bank]->polar = gpio_bank_saved[bank].polar; - gpio_array[bank]->edge = gpio_bank_saved[bank].edge; - gpio_array[bank]->both = gpio_bank_saved[bank].both; + gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; + gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; + gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; + gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; + gpio_bankb[bank]->both = gpio_bank_saved[bank].both; reserved_gpio_map[bank] = gpio_bank_saved[bank].reserved; bfin_internal_set_wake(sic_iwr_irqs[bank], 0); } - gpio_array[bank]->maskb = gpio_bank_saved[bank].maskb; + gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; } AWA_DUMMY_READ(maskb); } @@ -658,21 +745,21 @@ void bfin_gpio_pm_hibernate_suspend(void) bank = gpio_bank(i); #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) - gpio_bank_saved[bank].fer = *port_fer[bank]; + gpio_bank_saved[bank].fer = *port_fer[bank]; #if defined(BF527_FAMILY) || defined(BF518_FAMILY) - gpio_bank_saved[bank].mux = *port_mux[bank]; + gpio_bank_saved[bank].mux = *port_mux[bank]; #else - if (bank == 0) - gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); + if (bank == 0) + gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); #endif #endif - gpio_bank_saved[bank].data = gpio_array[bank]->data; - gpio_bank_saved[bank].inen = gpio_array[bank]->inen; - gpio_bank_saved[bank].polar = gpio_array[bank]->polar; - gpio_bank_saved[bank].dir = gpio_array[bank]->dir; - gpio_bank_saved[bank].edge = gpio_array[bank]->edge; - gpio_bank_saved[bank].both = gpio_array[bank]->both; - gpio_bank_saved[bank].maska = gpio_array[bank]->maska; + gpio_bank_saved[bank].data = gpio_bankb[bank]->data; + gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; + gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; + gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; + gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; + gpio_bank_saved[bank].both = gpio_bankb[bank]->both; + gpio_bank_saved[bank].maska = gpio_bankb[bank]->maska; } AWA_DUMMY_READ(maska); @@ -683,27 +770,27 @@ void bfin_gpio_pm_hibernate_restore(void) int i, bank; for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - bank = gpio_bank(i); + bank = gpio_bank(i); #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) #if defined(BF527_FAMILY) || defined(BF518_FAMILY) - *port_mux[bank] = gpio_bank_saved[bank].mux; + *port_mux[bank] = gpio_bank_saved[bank].mux; #else - if (bank == 0) - bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); + if (bank == 0) + bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); #endif - *port_fer[bank] = gpio_bank_saved[bank].fer; + *port_fer[bank] = gpio_bank_saved[bank].fer; #endif - gpio_array[bank]->inen = gpio_bank_saved[bank].inen; - gpio_array[bank]->dir = gpio_bank_saved[bank].dir; - gpio_array[bank]->polar = gpio_bank_saved[bank].polar; - gpio_array[bank]->edge = gpio_bank_saved[bank].edge; - gpio_array[bank]->both = gpio_bank_saved[bank].both; + gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; + gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; + gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; + gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; + gpio_bankb[bank]->both = gpio_bank_saved[bank].both; - gpio_array[bank]->data_set = gpio_bank_saved[bank].data - | gpio_bank_saved[bank].dir; + gpio_bankb[bank]->data_set = gpio_bank_saved[bank].data + | gpio_bank_saved[bank].dir; - gpio_array[bank]->maska = gpio_bank_saved[bank].maska; + gpio_bankb[bank]->maska = gpio_bank_saved[bank].maska; } AWA_DUMMY_READ(maska); } @@ -730,12 +817,12 @@ void bfin_gpio_pm_hibernate_suspend(void) for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { bank = gpio_bank(i); - gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; - gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; - gpio_bank_saved[bank].data = gpio_array[bank]->data; - gpio_bank_saved[bank].data = gpio_array[bank]->data; - gpio_bank_saved[bank].inen = gpio_array[bank]->inen; - gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set; + gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; + gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; + gpio_bank_saved[bank].data = gpio_array[bank]->port_data; + gpio_bank_saved[bank].data = gpio_array[bank]->port_data; + gpio_bank_saved[bank].inen = gpio_array[bank]->port_inen; + gpio_bank_saved[bank].dir = gpio_array[bank]->port_dir_set; } } @@ -744,21 +831,21 @@ void bfin_gpio_pm_hibernate_restore(void) int i, bank; for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - bank = gpio_bank(i); - - gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; - gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; - gpio_array[bank]->inen = gpio_bank_saved[bank].inen; - gpio_array[bank]->dir_set = gpio_bank_saved[bank].dir; - gpio_array[bank]->data_set = gpio_bank_saved[bank].data - | gpio_bank_saved[bank].dir; + bank = gpio_bank(i); + + gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; + gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; + gpio_array[bank]->port_inen = gpio_bank_saved[bank].inen; + gpio_array[bank]->port_dir_set = gpio_bank_saved[bank].dir; + gpio_array[bank]->port_set = gpio_bank_saved[bank].data + | gpio_bank_saved[bank].dir; } } #endif unsigned short get_gpio_dir(unsigned gpio) { - return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio))); + return (0x01 & (gpio_array[gpio_bank(gpio)]->port_dir_clear >> gpio_sub_n(gpio))); } EXPORT_SYMBOL(get_gpio_dir); @@ -818,7 +905,9 @@ int peripheral_request(unsigned short per, const char *label) */ #ifdef BF548_FAMILY - if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { + u16 funct = get_portmux(ident); + + if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) { #else if (!(per & P_MAYSHARE)) { #endif @@ -842,7 +931,11 @@ int peripheral_request(unsigned short per, const char *label) anyway: reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident); - portmux_setup(per); +#ifdef BF548_FAMILY + portmux_setup(ident, P_FUNCT2MUX(per)); +#else + portmux_setup(per, P_FUNCT2MUX(per)); +#endif port_setup(ident, PERIPHERAL_USAGE); local_irq_restore_hw(flags); @@ -884,6 +977,9 @@ void peripheral_free(unsigned short per) if (!(per & P_DEFINED)) return; + if (check_gpio(ident) < 0) + return; + local_irq_save_hw(flags); if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) { @@ -960,15 +1056,9 @@ int bfin_gpio_request(unsigned gpio, const char *label) local_irq_restore_hw(flags); return -EBUSY; } - if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); - } -#ifndef BF548_FAMILY - else { /* Reset POLAR setting when acquiring a gpio for the first time */ - set_gpio_polar(gpio, 0); - } -#endif reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); set_label(gpio, label); @@ -988,8 +1078,6 @@ void bfin_gpio_free(unsigned gpio) if (check_gpio(gpio) < 0) return; - might_sleep(); - local_irq_save_hw(flags); if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { @@ -1070,16 +1158,8 @@ void bfin_gpio_irq_free(unsigned gpio) local_irq_restore_hw(flags); } -static inline void __bfin_gpio_direction_input(unsigned gpio) -{ -#ifdef BF548_FAMILY - gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); -#else - gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); -#endif - gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); -} +#ifdef BF548_FAMILY int bfin_gpio_direction_input(unsigned gpio) { unsigned long flags; @@ -1090,85 +1170,125 @@ int bfin_gpio_direction_input(unsigned gpio) } local_irq_save_hw(flags); - __bfin_gpio_direction_input(gpio); - AWA_DUMMY_READ(inen); + gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); + gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); local_irq_restore_hw(flags); return 0; } EXPORT_SYMBOL(bfin_gpio_direction_input); -void bfin_gpio_irq_prepare(unsigned gpio) +int bfin_gpio_direction_output(unsigned gpio, int value) { -#ifdef BF548_FAMILY unsigned long flags; -#endif - port_setup(gpio, GPIO_USAGE); + if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + gpio_error(gpio); + return -EINVAL; + } -#ifdef BF548_FAMILY local_irq_save_hw(flags); - __bfin_gpio_direction_input(gpio); + gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio); + gpio_set_value(gpio, value); + gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio); local_irq_restore_hw(flags); -#endif + + return 0; } +EXPORT_SYMBOL(bfin_gpio_direction_output); void bfin_gpio_set_value(unsigned gpio, int arg) { if (arg) - gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); + gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); else - gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); + gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); } EXPORT_SYMBOL(bfin_gpio_set_value); -int bfin_gpio_direction_output(unsigned gpio, int value) +int bfin_gpio_get_value(unsigned gpio) +{ + return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); +} +EXPORT_SYMBOL(bfin_gpio_get_value); + +void bfin_gpio_irq_prepare(unsigned gpio) { unsigned long flags; - if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { - gpio_error(gpio); - return -EINVAL; - } + port_setup(gpio, GPIO_USAGE); local_irq_save_hw(flags); - - gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); - gpio_set_value(gpio, value); -#ifdef BF548_FAMILY - gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); -#else - gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); -#endif - - AWA_DUMMY_READ(dir); + gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); + gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); local_irq_restore_hw(flags); - - return 0; } -EXPORT_SYMBOL(bfin_gpio_direction_output); + +#else int bfin_gpio_get_value(unsigned gpio) { -#ifdef BF548_FAMILY - return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); -#else unsigned long flags; + int ret; if (unlikely(get_gpio_edge(gpio))) { - int ret; local_irq_save_hw(flags); set_gpio_edge(gpio, 0); ret = get_gpio_data(gpio); set_gpio_edge(gpio, 1); local_irq_restore_hw(flags); + return ret; } else return get_gpio_data(gpio); -#endif } EXPORT_SYMBOL(bfin_gpio_get_value); + +int bfin_gpio_direction_input(unsigned gpio) +{ + unsigned long flags; + + if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + gpio_error(gpio); + return -EINVAL; + } + + local_irq_save_hw(flags); + gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); + gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); + AWA_DUMMY_READ(inen); + local_irq_restore_hw(flags); + + return 0; +} +EXPORT_SYMBOL(bfin_gpio_direction_input); + +int bfin_gpio_direction_output(unsigned gpio, int value) +{ + unsigned long flags; + + if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + gpio_error(gpio); + return -EINVAL; + } + + local_irq_save_hw(flags); + gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); + + if (value) + gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); + else + gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); + + gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); + AWA_DUMMY_READ(dir); + local_irq_restore_hw(flags); + + return 0; +} +EXPORT_SYMBOL(bfin_gpio_direction_output); + /* If we are booting from SPI and our board lacks a strong enough pull up, * the core can reset and execute the bootrom faster than the resistor can * pull the signal logically high. To work around this (common) error in @@ -1179,15 +1299,23 @@ EXPORT_SYMBOL(bfin_gpio_get_value); * lives here as we need to force all the GPIO states w/out going through * BUG() checks and such. */ -void bfin_reset_boot_spi_cs(unsigned short pin) +void bfin_gpio_reset_spi0_ssel1(void) { - unsigned short gpio = P_IDENT(pin); + u16 gpio = P_IDENT(P_SPI0_SSEL1); + port_setup(gpio, GPIO_USAGE); - gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); + gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); AWA_DUMMY_READ(data_set); udelay(1); } +void bfin_gpio_irq_prepare(unsigned gpio) +{ + port_setup(gpio, GPIO_USAGE); +} + +#endif /*BF548_FAMILY */ + #if defined(CONFIG_PROC_FS) static int gpio_proc_read(char *buf, char **start, off_t offset, int len, int *unused_i, void *unused_v) @@ -1241,7 +1369,11 @@ int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio) void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value) { +#ifdef BF548_FAMILY return bfin_gpio_set_value(gpio, value); +#else + return set_gpio_data(gpio, value); +#endif } int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio) diff --git a/trunk/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/trunk/arch/blackfin/kernel/cplb-mpu/cplbinit.c index 3e329a6ce041..bdb958486e76 100644 --- a/trunk/arch/blackfin/kernel/cplb-mpu/cplbinit.c +++ b/trunk/arch/blackfin/kernel/cplb-mpu/cplbinit.c @@ -63,8 +63,10 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) dcplb_tbl[cpu][i_d].addr = 0; dcplb_tbl[cpu][i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; +#if 0 icplb_tbl[cpu][i_i].addr = 0; - icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_1KB; + icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_4KB; +#endif /* Cover kernel memory with 4M pages. */ addr = 0; diff --git a/trunk/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/trunk/arch/blackfin/kernel/cplb-nompu/cplbmgr.c index 8cbb47c7b663..376249ab2694 100644 --- a/trunk/arch/blackfin/kernel/cplb-nompu/cplbmgr.c +++ b/trunk/arch/blackfin/kernel/cplb-nompu/cplbmgr.c @@ -163,14 +163,12 @@ MGR_ATTR static int icplb_miss(int cpu) nr_icplb_supv_miss[cpu]++; base = 0; - idx = 0; - do { + for (idx = 0; idx < icplb_nr_bounds; idx++) { eaddr = icplb_bounds[idx].eaddr; if (addr < eaddr) break; base = eaddr; - } while (++idx < icplb_nr_bounds); - + } if (unlikely(idx == icplb_nr_bounds)) return CPLB_NO_ADDR_MATCH; @@ -210,14 +208,12 @@ MGR_ATTR static int dcplb_miss(int cpu) nr_dcplb_supv_miss[cpu]++; base = 0; - idx = 0; - do { + for (idx = 0; idx < dcplb_nr_bounds; idx++) { eaddr = dcplb_bounds[idx].eaddr; if (addr < eaddr) break; base = eaddr; - } while (++idx < dcplb_nr_bounds); - + } if (unlikely(idx == dcplb_nr_bounds)) return CPLB_NO_ADDR_MATCH; diff --git a/trunk/arch/blackfin/kernel/irqchip.c b/trunk/arch/blackfin/kernel/irqchip.c index 75724eee6494..ab8209cbbad0 100644 --- a/trunk/arch/blackfin/kernel/irqchip.c +++ b/trunk/arch/blackfin/kernel/irqchip.c @@ -35,7 +35,6 @@ #include #include #include -#include static atomic_t irq_err_count; static spinlock_t irq_controller_lock; @@ -92,13 +91,8 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { - seq_printf(p, "NMI: "); - for_each_online_cpu(j) - seq_printf(p, "%10u ", cpu_pda[j].__nmi_count); - seq_printf(p, " CORE Non Maskable Interrupt\n"); + } else if (i == NR_IRQS) seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count)); - } return 0; } diff --git a/trunk/arch/blackfin/kernel/reboot.c b/trunk/arch/blackfin/kernel/reboot.c index 53d08dee8531..eeee8cb43360 100644 --- a/trunk/arch/blackfin/kernel/reboot.c +++ b/trunk/arch/blackfin/kernel/reboot.c @@ -20,8 +20,8 @@ * reset while the Core B bit (on dual core parts) is cleared by * the core reset. */ -__attribute__ ((__l1_text__, __noreturn__)) -static void bfin_reset(void) +__attribute__((l1_text)) +static void _bfin_reset(void) { /* Wait for completion of "system" events such as cache line * line fills so that we avoid infinite stalls later on as @@ -30,11 +30,7 @@ static void bfin_reset(void) */ __builtin_bfin_ssync(); - /* The bootrom checks to see how it was reset and will - * automatically perform a software reset for us when - * it starts executing after the core reset. - */ - if (ANOMALY_05000353 || ANOMALY_05000386) { + while (1) { /* Initiate System software reset. */ bfin_write_SWRST(0x7); @@ -54,11 +50,6 @@ static void bfin_reset(void) /* Clear System software reset */ bfin_write_SWRST(0); - /* The BF526 ROM will crash during reset */ -#if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__) - bfin_read_SWRST(); -#endif - /* Wait for the SWRST write to complete. Cannot rely on SSYNC * though as the System state is all reset now. */ @@ -69,11 +60,22 @@ static void bfin_reset(void) : "a" (15 * 1) : "LC1", "LB1", "LT1" ); - } - while (1) /* Issue core reset */ asm("raise 1"); + } +} + +static void bfin_reset(void) +{ + if (ANOMALY_05000353 || ANOMALY_05000386) + _bfin_reset(); + else + /* the bootrom checks to see how it was reset and will + * automatically perform a software reset for us when + * it starts executing boot + */ + asm("raise 1;"); } __attribute__((weak)) diff --git a/trunk/arch/blackfin/kernel/setup.c b/trunk/arch/blackfin/kernel/setup.c index e5c116230800..b2a811347b65 100644 --- a/trunk/arch/blackfin/kernel/setup.c +++ b/trunk/arch/blackfin/kernel/setup.c @@ -60,7 +60,7 @@ void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat, #define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */ #define BFIN_MEMMAP_RAM 1 #define BFIN_MEMMAP_RESERVED 2 -static struct bfin_memmap { +struct bfin_memmap { int nr_map; struct bfin_memmap_entry { unsigned long long addr; /* start of memory segment */ @@ -824,15 +824,7 @@ void __init setup_arch(char **cmdline_p) flash_probe(); #endif - printk(KERN_INFO "Boot Mode: %i\n", bfin_read_SYSCR() & 0xF); - - /* Newer parts mirror SWRST bits in SYSCR */ -#if defined(CONFIG_BF53x) || defined(CONFIG_BF561) || \ - defined(CONFIG_BF538) || defined(CONFIG_BF539) _bfin_swrst = bfin_read_SWRST(); -#else - _bfin_swrst = bfin_read_SYSCR(); -#endif #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT bfin_write_SWRST(_bfin_swrst & ~DOUBLE_FAULT); @@ -861,7 +853,7 @@ void __init setup_arch(char **cmdline_p) else if (_bfin_swrst & RESET_SOFTWARE) printk(KERN_NOTICE "Reset caused by Software reset\n"); - printk(KERN_INFO "Blackfin support (C) 2004-2009 Analog Devices, Inc.\n"); + printk(KERN_INFO "Blackfin support (C) 2004-2008 Analog Devices, Inc.\n"); if (bfin_compiled_revid() == 0xffff) printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU); else if (bfin_compiled_revid() == -1) diff --git a/trunk/arch/blackfin/kernel/traps.c b/trunk/arch/blackfin/kernel/traps.c index ffe7fb53eccb..5b0667da8d05 100644 --- a/trunk/arch/blackfin/kernel/traps.c +++ b/trunk/arch/blackfin/kernel/traps.c @@ -673,14 +673,6 @@ static void decode_instruction(unsigned short *address) verbose_printk("RTI"); else if (opcode == 0x0012) verbose_printk("RTX"); - else if (opcode == 0x0013) - verbose_printk("RTN"); - else if (opcode == 0x0014) - verbose_printk("RTE"); - else if (opcode == 0x0025) - verbose_printk("EMUEXCPT"); - else if (opcode == 0x0040 && opcode <= 0x0047) - verbose_printk("STI R%i", opcode & 7); else if (opcode >= 0x0050 && opcode <= 0x0057) verbose_printk("JUMP (P%i)", opcode & 7); else if (opcode >= 0x0060 && opcode <= 0x0067) @@ -689,10 +681,6 @@ static void decode_instruction(unsigned short *address) verbose_printk("CALL (PC+P%i)", opcode & 7); else if (opcode >= 0x0080 && opcode <= 0x0087) verbose_printk("JUMP (PC+P%i)", opcode & 7); - else if (opcode >= 0x0090 && opcode <= 0x009F) - verbose_printk("RAISE 0x%x", opcode & 0xF); - else if (opcode >= 0x00A0 && opcode <= 0x00AF) - verbose_printk("EXCPT 0x%x", opcode & 0xF); else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) verbose_printk("IF !CC JUMP"); else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) @@ -832,8 +820,11 @@ void show_stack(struct task_struct *task, unsigned long *stack) decode_address(buf, (unsigned int)stack); printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); + addr = (unsigned int *)((unsigned int)stack & ~0x3F); + /* First thing is to look for a frame pointer */ - for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { + for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; + addr < endstack; addr++, i++) { if (*addr & 0x1) continue; ins_addr = (unsigned short *)*addr; @@ -843,8 +834,7 @@ void show_stack(struct task_struct *task, unsigned long *stack) if (fp) { /* Let's check to see if it is a frame pointer */ - while (fp >= (addr - 1) && fp < endstack - && fp && ((unsigned int) fp & 0x3) == 0) + while (fp >= (addr - 1) && fp < endstack && fp) fp = (unsigned int *)*fp; if (fp == 0 || fp == endstack) { fp = addr - 1; @@ -1062,9 +1052,8 @@ void show_regs(struct pt_regs *fp) char buf [150]; struct irqaction *action; unsigned int i; - unsigned long flags = 0; + unsigned long flags; unsigned int cpu = smp_processor_id(); - unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", @@ -1084,22 +1073,17 @@ void show_regs(struct pt_regs *fp) } verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", fp->seqstat & SEQSTAT_EXCAUSE); - for (i = 2; i <= 15 ; i++) { + for (i = 6; i <= 15 ; i++) { if (fp->ipend & (1 << i)) { - if (i != 4) { - decode_address(buf, bfin_read32(EVT0 + 4*i)); - verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); - } else - verbose_printk(KERN_NOTICE " interrupts disabled\n"); + decode_address(buf, bfin_read32(EVT0 + 4*i)); + verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); } } /* if no interrupts are going off, don't print this out */ if (fp->ipend & ~0x3F) { for (i = 0; i < (NR_IRQS - 1); i++) { - if (!in_atomic) - spin_lock_irqsave(&irq_desc[i].lock, flags); - + spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto unlock; @@ -1112,8 +1096,7 @@ void show_regs(struct pt_regs *fp) } verbose_printk("\n"); unlock: - if (!in_atomic) - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } } diff --git a/trunk/arch/blackfin/mach-bf518/boards/ezbrd.c b/trunk/arch/blackfin/mach-bf518/boards/ezbrd.c index 0e175342112e..15f1351c8645 100644 --- a/trunk/arch/blackfin/mach-bf518/boards/ezbrd.c +++ b/trunk/arch/blackfin/mach-bf518/boards/ezbrd.c @@ -46,7 +46,6 @@ #include #include #include -#include /* * Name the Board for the /proc/cpuinfo @@ -105,31 +104,8 @@ static struct platform_device rtc_device = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mii_bus = { - .name = "bfin_mii_bus", -}; - static struct platform_device bfin_mac_device = { .name = "bfin_mac", - .dev.platform_data = &bfin_mii_bus, -}; -#endif - -#if defined(CONFIG_NET_DSA_KSZ8893M) || defined(CONFIG_NET_DSA_KSZ8893M_MODULE) -static struct dsa_platform_data ksz8893m_switch_data = { - .mii_bus = &bfin_mii_bus.dev, - .netdev = &bfin_mac_device.dev, - .port_names[0] = NULL, - .port_names[1] = "eth%d", - .port_names[2] = "eth%d", - .port_names[3] = "cpu", -}; - -static struct platform_device ksz8893m_switch_device = { - .name = "dsa", - .id = 0, - .num_resources = 0, - .dev.platform_data = &ksz8893m_switch_data, }; #endif @@ -171,15 +147,6 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_NET_DSA_KSZ8893M) \ - || defined(CONFIG_NET_DSA_KSZ8893M_MODULE) -/* SPI SWITCH CHIP */ -static struct bfin5xx_spi_chip spi_switch_info = { - .enable_dma = 0, - .bits_per_word = 8, -}; -#endif - #if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) static struct bfin5xx_spi_chip spi_mmc_chip_info = { .enable_dma = 1, @@ -259,19 +226,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_NET_DSA_KSZ8893M) \ - || defined(CONFIG_NET_DSA_KSZ8893M_MODULE) - { - .modalias = "ksz8893m", - .max_speed_hz = 5000000, - .bus_num = 0, - .chip_select = 1, - .platform_data = NULL, - .controller_data = &spi_switch_info, - .mode = SPI_MODE_3, - }, -#endif - #if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) { .modalias = "spi_mmc_dummy", @@ -519,6 +473,7 @@ static struct platform_device i2c_bfin_twi_device = { }; #endif +#ifdef CONFIG_I2C_BOARDINFO static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) { @@ -532,6 +487,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }, #endif }; +#endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) static struct platform_device bfin_sport0_uart_device = { @@ -628,14 +584,9 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mii_bus, &bfin_mac_device, #endif -#if defined(CONFIG_NET_DSA_KSZ8893M) || defined(CONFIG_NET_DSA_KSZ8893M_MODULE) - &ksz8893m_switch_device, -#endif - #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) &bfin_spi0_device, &bfin_spi1_device, @@ -681,8 +632,12 @@ static struct platform_device *stamp_devices[] __initdata = { static int __init ezbrd_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); + +#ifdef CONFIG_I2C_BOARDINFO i2c_register_board_info(0, bfin_i2c_board_info, ARRAY_SIZE(bfin_i2c_board_info)); +#endif + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); return 0; @@ -694,7 +649,7 @@ void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ if ((bfin_read_SYSCR() & 0x7) == 0x3) - bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); + bfin_gpio_reset_spi0_ssel1(); } void bfin_get_ether_addr(char *addr) diff --git a/trunk/arch/blackfin/mach-bf518/include/mach/portmux.h b/trunk/arch/blackfin/mach-bf518/include/mach/portmux.h index f618b487b2b0..ac16d54734d4 100644 --- a/trunk/arch/blackfin/mach-bf518/include/mach/portmux.h +++ b/trunk/arch/blackfin/mach-bf518/include/mach/portmux.h @@ -103,8 +103,6 @@ #define P_SPI1_SSEL4 (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(2)) #define P_SPI1_SSEL5 (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(2)) -#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2 - /* SPORT Port Mux */ #define P_SPORT0_DRPRI (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(0)) #define P_SPORT0_RSCLK (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(0)) diff --git a/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c b/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c index 856c097b5317..a2c3578f4b6c 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -403,13 +403,8 @@ static struct platform_device isp1362_hcd_device = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mii_bus = { - .name = "bfin_mii_bus", -}; - static struct platform_device bfin_mac_device = { .name = "bfin_mac", - .dev.platform_data = &bfin_mii_bus, }; #endif @@ -798,6 +793,7 @@ static struct platform_device i2c_bfin_twi_device = { }; #endif +#ifdef CONFIG_I2C_BOARDINFO static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) { @@ -813,6 +809,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }, #endif }; +#endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) static struct platform_device bfin_sport0_uart_device = { @@ -923,7 +920,6 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mii_bus, &bfin_mac_device, #endif @@ -972,23 +968,27 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_gpios_device, }; -static int __init cm_init(void) +static int __init stamp_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); + +#ifdef CONFIG_I2C_BOARDINFO i2c_register_board_info(0, bfin_i2c_board_info, ARRAY_SIZE(bfin_i2c_board_info)); +#endif + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); return 0; } -arch_initcall(cm_init); +arch_initcall(stamp_init); void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ if ((bfin_read_SYSCR() & 0x7) == 0x3) - bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); + bfin_gpio_reset_spi0_ssel1(); } void bfin_get_ether_addr(char *addr) diff --git a/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c b/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c index 83606fcdde27..0314bd3355eb 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -208,13 +208,8 @@ static struct platform_device rtc_device = { #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mii_bus = { - .name = "bfin_mii_bus", -}; - static struct platform_device bfin_mac_device = { .name = "bfin_mac", - .dev.platform_data = &bfin_mii_bus, }; #endif @@ -595,6 +590,7 @@ static struct platform_device i2c_bfin_twi_device = { }; #endif +#ifdef CONFIG_I2C_BOARDINFO static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) { @@ -608,6 +604,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }, #endif }; +#endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) static struct platform_device bfin_sport0_uart_device = { @@ -723,7 +720,6 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mii_bus, &bfin_mac_device, #endif @@ -768,23 +764,27 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_gpios_device, }; -static int __init ezbrd_init(void) +static int __init stamp_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); + +#ifdef CONFIG_I2C_BOARDINFO i2c_register_board_info(0, bfin_i2c_board_info, ARRAY_SIZE(bfin_i2c_board_info)); +#endif + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); return 0; } -arch_initcall(ezbrd_init); +arch_initcall(stamp_init); void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ if ((bfin_read_SYSCR() & 0x7) == 0x3) - bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); + bfin_gpio_reset_spi0_ssel1(); } void bfin_get_ether_addr(char *addr) diff --git a/trunk/arch/blackfin/mach-bf527/boards/ezkit.c b/trunk/arch/blackfin/mach-bf527/boards/ezkit.c index d0864111ef59..9454fb7b18c3 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf527/boards/ezkit.c @@ -425,13 +425,8 @@ static struct platform_device isp1362_hcd_device = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mii_bus = { - .name = "bfin_mii_bus", -}; - static struct platform_device bfin_mac_device = { .name = "bfin_mac", - .dev.platform_data = &bfin_mii_bus, }; #endif @@ -835,6 +830,7 @@ static struct platform_device i2c_bfin_twi_device = { }; #endif +#ifdef CONFIG_I2C_BOARDINFO static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) { @@ -848,6 +844,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }, #endif }; +#endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) static struct platform_device bfin_sport0_uart_device = { @@ -991,7 +988,6 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mii_bus, &bfin_mac_device, #endif @@ -1052,23 +1048,27 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_gpios_device, }; -static int __init ezkit_init(void) +static int __init stamp_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); + +#ifdef CONFIG_I2C_BOARDINFO i2c_register_board_info(0, bfin_i2c_board_info, ARRAY_SIZE(bfin_i2c_board_info)); +#endif + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); return 0; } -arch_initcall(ezkit_init); +arch_initcall(stamp_init); void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ if ((bfin_read_SYSCR() & 0x7) == 0x3) - bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); + bfin_gpio_reset_spi0_ssel1(); } void bfin_get_ether_addr(char *addr) diff --git a/trunk/arch/blackfin/mach-bf527/include/mach/portmux.h b/trunk/arch/blackfin/mach-bf527/include/mach/portmux.h index 72b1652be4da..7f6da2c386bb 100644 --- a/trunk/arch/blackfin/mach-bf527/include/mach/portmux.h +++ b/trunk/arch/blackfin/mach-bf527/include/mach/portmux.h @@ -73,8 +73,6 @@ #define P_HWAIT (P_DONTCARE) -#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL1 - #define P_SPI0_SS (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0)) #define P_SPI0_SSEL1 (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(2)) #define P_SPI0_SCK (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(2)) diff --git a/trunk/arch/blackfin/mach-bf533/boards/blackstamp.c b/trunk/arch/blackfin/mach-bf533/boards/blackstamp.c index 015c18f85e7f..6ee607c259ac 100644 --- a/trunk/arch/blackfin/mach-bf533/boards/blackstamp.c +++ b/trunk/arch/blackfin/mach-bf533/boards/blackstamp.c @@ -309,8 +309,10 @@ static struct platform_device i2c_gpio_device = { }; #endif +#ifdef CONFIG_I2C_BOARDINFO static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }; +#endif static const unsigned int cclk_vlev_datasheet[] = { @@ -388,8 +390,10 @@ static int __init blackstamp_init(void) printk(KERN_INFO "%s(): registering device resources\n", __func__); +#ifdef CONFIG_I2C_BOARDINFO i2c_register_board_info(0, bfin_i2c_board_info, ARRAY_SIZE(bfin_i2c_board_info)); +#endif ret = platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); if (ret < 0) diff --git a/trunk/arch/blackfin/mach-bf533/boards/stamp.c b/trunk/arch/blackfin/mach-bf533/boards/stamp.c index db96f33f72e2..07f9ad1e189c 100644 --- a/trunk/arch/blackfin/mach-bf533/boards/stamp.c +++ b/trunk/arch/blackfin/mach-bf533/boards/stamp.c @@ -441,6 +441,7 @@ static struct platform_device i2c_gpio_device = { }; #endif +#ifdef CONFIG_I2C_BOARDINFO static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE) { @@ -460,6 +461,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }, #endif }; +#endif static const unsigned int cclk_vlev_datasheet[] = { @@ -548,8 +550,10 @@ static int __init stamp_init(void) printk(KERN_INFO "%s(): registering device resources\n", __func__); +#ifdef CONFIG_I2C_BOARDINFO i2c_register_board_info(0, bfin_i2c_board_info, ARRAY_SIZE(bfin_i2c_board_info)); +#endif ret = platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); if (ret < 0) diff --git a/trunk/arch/blackfin/mach-bf533/include/mach/portmux.h b/trunk/arch/blackfin/mach-bf533/include/mach/portmux.h index 2f59ce0b0cb5..685a2651dcda 100644 --- a/trunk/arch/blackfin/mach-bf533/include/mach/portmux.h +++ b/trunk/arch/blackfin/mach-bf533/include/mach/portmux.h @@ -54,11 +54,14 @@ #define P_SPI0_SSEL2 (P_DEFINED | P_IDENT(GPIO_PF2)) #define P_SPI0_SSEL1 (P_DEFINED | P_IDENT(GPIO_PF1)) #define P_SPI0_SS (P_DEFINED | P_IDENT(GPIO_PF0)) -#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2 #define P_TMR2 (P_DONTCARE) #define P_TMR1 (P_DONTCARE) #define P_TMR0 (P_DONTCARE) #define P_TMRCLK (P_DEFINED | P_IDENT(GPIO_PF1)) + + + + #endif /* _MACH_PORTMUX_H_ */ diff --git a/trunk/arch/blackfin/mach-bf537/boards/cm_bf537.c b/trunk/arch/blackfin/mach-bf537/boards/cm_bf537.c index 9cd8fb2a30d3..6ac8e4d5bd38 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/cm_bf537.c +++ b/trunk/arch/blackfin/mach-bf537/boards/cm_bf537.c @@ -479,13 +479,8 @@ static struct platform_device bfin_sport1_uart_device = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mii_bus = { - .name = "bfin_mii_bus", -}; - static struct platform_device bfin_mac_device = { .name = "bfin_mac", - .dev.platform_data = &bfin_mii_bus, }; #endif @@ -596,7 +591,6 @@ static struct platform_device *cm_bf537_devices[] __initdata = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mii_bus, &bfin_mac_device, #endif diff --git a/trunk/arch/blackfin/mach-bf537/boards/generic_board.c b/trunk/arch/blackfin/mach-bf537/boards/generic_board.c index da710fdc4569..dd6e6bfb98ea 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/generic_board.c +++ b/trunk/arch/blackfin/mach-bf537/boards/generic_board.c @@ -262,13 +262,8 @@ static struct platform_device isp1362_hcd_device = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mii_bus = { - .name = "bfin_mii_bus", -}; - static struct platform_device bfin_mac_device = { .name = "bfin_mac", - .dev.platform_data = &bfin_mii_bus, }; #endif @@ -667,7 +662,6 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mii_bus, &bfin_mac_device, #endif @@ -714,7 +708,7 @@ static struct platform_device *stamp_devices[] __initdata = { #endif }; -static int __init generic_init(void) +static int __init stamp_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); @@ -726,13 +720,13 @@ static int __init generic_init(void) return 0; } -arch_initcall(generic_init); +arch_initcall(stamp_init); void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ if ((bfin_read_SYSCR() & 0x7) == 0x3) - bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); + bfin_gpio_reset_spi0_ssel1(); } #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) diff --git a/trunk/arch/blackfin/mach-bf537/boards/minotaur.c b/trunk/arch/blackfin/mach-bf537/boards/minotaur.c index db7d3a385e4b..bb795341cb17 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/minotaur.c +++ b/trunk/arch/blackfin/mach-bf537/boards/minotaur.c @@ -61,13 +61,8 @@ static struct platform_device rtc_device = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mii_bus = { - .name = "bfin_mii_bus", -}; - static struct platform_device bfin_mac_device = { .name = "bfin_mac", - .dev.platform_data = &bfin_mii_bus, }; #endif @@ -329,7 +324,6 @@ static struct platform_device *minotaur_devices[] __initdata = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mii_bus, &bfin_mac_device, #endif @@ -383,5 +377,5 @@ void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ if ((bfin_read_SYSCR() & 0x7) == 0x3) - bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); + bfin_gpio_reset_spi0_ssel1(); } diff --git a/trunk/arch/blackfin/mach-bf537/boards/pnav10.c b/trunk/arch/blackfin/mach-bf537/boards/pnav10.c index 590eb3a139b7..89de94f4545d 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/pnav10.c +++ b/trunk/arch/blackfin/mach-bf537/boards/pnav10.c @@ -198,13 +198,8 @@ static struct platform_device isp1362_hcd_device = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mii_bus = { - .name = "bfin_mii_bus", -}; - static struct platform_device bfin_mac_device = { .name = "bfin_mac", - .dev.platform_data = &bfin_mii_bus, }; #endif @@ -534,7 +529,6 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mii_bus, &bfin_mac_device, #endif @@ -564,7 +558,7 @@ static struct platform_device *stamp_devices[] __initdata = { #endif }; -static int __init pnav_init(void) +static int __init stamp_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); @@ -575,7 +569,7 @@ static int __init pnav_init(void) return 0; } -arch_initcall(pnav_init); +arch_initcall(stamp_init); void bfin_get_ether_addr(char *addr) { diff --git a/trunk/arch/blackfin/mach-bf537/boards/stamp.c b/trunk/arch/blackfin/mach-bf537/boards/stamp.c index cd04c5e44878..d812e2514a2f 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/stamp.c +++ b/trunk/arch/blackfin/mach-bf537/boards/stamp.c @@ -321,13 +321,8 @@ static struct platform_device isp1362_hcd_device = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mii_bus = { - .name = "bfin_mii_bus", -}; - static struct platform_device bfin_mac_device = { .name = "bfin_mac", - .dev.platform_data = &bfin_mii_bus, }; #endif @@ -1073,6 +1068,7 @@ static struct adp5588_kpad_platform_data adp5588_kpad_data = { }; #endif +#ifdef CONFIG_I2C_BOARDINFO static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE) { @@ -1106,6 +1102,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }, #endif }; +#endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) static struct platform_device bfin_sport0_uart_device = { @@ -1220,7 +1217,6 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mii_bus, &bfin_mac_device, #endif @@ -1288,8 +1284,12 @@ static struct platform_device *stamp_devices[] __initdata = { static int __init stamp_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); + +#ifdef CONFIG_I2C_BOARDINFO i2c_register_board_info(0, bfin_i2c_board_info, ARRAY_SIZE(bfin_i2c_board_info)); +#endif + bfin_plat_nand_init(); platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); @@ -1307,7 +1307,7 @@ void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ if ((bfin_read_SYSCR() & 0x7) == 0x3) - bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); + bfin_gpio_reset_spi0_ssel1(); } /* diff --git a/trunk/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/trunk/arch/blackfin/mach-bf537/boards/tcm_bf537.c index 3f4f203a06ec..2f4b066153c5 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/tcm_bf537.c +++ b/trunk/arch/blackfin/mach-bf537/boards/tcm_bf537.c @@ -481,13 +481,8 @@ static struct platform_device bfin_sport1_uart_device = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mii_bus = { - .name = "bfin_mii_bus", -}; - static struct platform_device bfin_mac_device = { .name = "bfin_mac", - .dev.platform_data = &bfin_mii_bus, }; #endif @@ -598,7 +593,6 @@ static struct platform_device *cm_bf537_devices[] __initdata = { #endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mii_bus, &bfin_mac_device, #endif @@ -621,7 +615,7 @@ static struct platform_device *cm_bf537_devices[] __initdata = { &bfin_gpios_device, }; -static int __init tcm_bf537_init(void) +static int __init cm_bf537_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices)); @@ -635,7 +629,7 @@ static int __init tcm_bf537_init(void) return 0; } -arch_initcall(tcm_bf537_init); +arch_initcall(cm_bf537_init); void bfin_get_ether_addr(char *addr) { diff --git a/trunk/arch/blackfin/mach-bf537/include/mach/portmux.h b/trunk/arch/blackfin/mach-bf537/include/mach/portmux.h index 87285e75e903..78fee6e0f237 100644 --- a/trunk/arch/blackfin/mach-bf537/include/mach/portmux.h +++ b/trunk/arch/blackfin/mach-bf537/include/mach/portmux.h @@ -31,7 +31,6 @@ #define P_PPI0_FS1 (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1)) #define P_TACLK0 (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1)) #define P_TMRCLK (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1)) -#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL1 #define P_PPI0_D0 (P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(0)) #define P_PPI0_D1 (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0)) diff --git a/trunk/arch/blackfin/mach-bf538/include/mach/portmux.h b/trunk/arch/blackfin/mach-bf538/include/mach/portmux.h index c8db264e3e4d..1e031b588b47 100644 --- a/trunk/arch/blackfin/mach-bf538/include/mach/portmux.h +++ b/trunk/arch/blackfin/mach-bf538/include/mach/portmux.h @@ -102,6 +102,5 @@ #define P_SPI0_SSEL2 (P_DEFINED | P_IDENT(GPIO_PF2)) #define P_SPI0_SSEL1 (P_DEFINED | P_IDENT(GPIO_PF1)) #define P_SPI0_SS (P_DEFINED | P_IDENT(GPIO_PF0)) -#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2 #endif /* _MACH_PORTMUX_H_ */ diff --git a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c index 096e661700a7..309c16014cae 100644 --- a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c @@ -781,6 +781,7 @@ static struct platform_device i2c_bfin_twi1_device = { #endif #endif +#ifdef CONFIG_I2C_BOARDINFO static struct i2c_board_info __initdata bfin_i2c_board_info0[] = { }; @@ -799,6 +800,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info1[] = { #endif }; #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #include @@ -954,11 +956,13 @@ static int __init ezkit_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); +#ifdef CONFIG_I2C_BOARDINFO i2c_register_board_info(0, bfin_i2c_board_info0, ARRAY_SIZE(bfin_i2c_board_info0)); #if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ i2c_register_board_info(1, bfin_i2c_board_info1, ARRAY_SIZE(bfin_i2c_board_info1)); +#endif #endif platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices)); diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h index 23d03c52f4b4..3b5430999f4f 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h @@ -175,7 +175,6 @@ #define ANOMALY_05000311 (0) #define ANOMALY_05000323 (0) #define ANOMALY_05000363 (0) -#define ANOMALY_05000380 (0) #define ANOMALY_05000412 (0) #define ANOMALY_05000432 (0) #define ANOMALY_05000435 (0) diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/bf548.h b/trunk/arch/blackfin/mach-bf548/include/mach/bf548.h index cd31f72bdd82..f0e569984810 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/bf548.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/bf548.h @@ -104,18 +104,6 @@ #define AMGCTLVAL (V_AMBEN | V_AMCKEN) -#if defined(CONFIG_BF542M) -# define CONFIG_BF542 -#elif defined(CONFIG_BF544M) -# define CONFIG_BF544 -#elif defined(CONFIG_BF547M) -# define CONFIG_BF547 -#elif defined(CONFIG_BF548M) -# define CONFIG_BF548 -#elif defined(CONFIG_BF549M) -# define CONFIG_BF549 -#endif - #if defined(CONFIG_BF542) # define CPU "BF542" # define CPUID 0x27de diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/gpio.h b/trunk/arch/blackfin/mach-bf548/include/mach/gpio.h index 3a2051709787..bba82dc75f16 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/gpio.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/gpio.h @@ -195,17 +195,17 @@ struct gpio_port_t { unsigned short port_fer; unsigned short dummy1; - unsigned short data; + unsigned short port_data; unsigned short dummy2; - unsigned short data_set; + unsigned short port_set; unsigned short dummy3; - unsigned short data_clear; + unsigned short port_clear; unsigned short dummy4; - unsigned short dir_set; + unsigned short port_dir_set; unsigned short dummy5; - unsigned short dir_clear; + unsigned short port_dir_clear; unsigned short dummy6; - unsigned short inen; + unsigned short port_inen; unsigned short dummy7; unsigned int port_mux; }; diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/portmux.h b/trunk/arch/blackfin/mach-bf548/include/mach/portmux.h index ffb1d0a44b4d..8177a567dcdb 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/portmux.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/portmux.h @@ -125,7 +125,6 @@ #define P_KEY_COL2 (P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(3)) #define P_KEY_COL3 (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(3)) -#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL1 #define P_SPI0_SCK (P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(0)) #define P_SPI0_MISO (P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(0)) #define P_SPI0_MOSI (P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(0)) diff --git a/trunk/arch/blackfin/mach-bf561/include/mach/defBF561.h b/trunk/arch/blackfin/mach-bf561/include/mach/defBF561.h index cf922295f4ce..d7c509759659 100644 --- a/trunk/arch/blackfin/mach-bf561/include/mach/defBF561.h +++ b/trunk/arch/blackfin/mach-bf561/include/mach/defBF561.h @@ -1106,8 +1106,6 @@ #define DLEN_8 0x0 /* PPI Data Length mask for DLEN=8 */ #define DLEN(x) (((x-9) & 0x07) << 11) /* PPI Data Length (only works for x=10-->x=16) */ #define POL 0x0000C000 /* PPI Signal Polarities */ -#define POLC 0x4000 /* PPI Clock Polarity */ -#define POLS 0x8000 /* PPI Frame Sync Polarity */ /* PPI_STATUS Masks */ #define FLD 0x00000400 /* Field Indicator */ diff --git a/trunk/arch/blackfin/mach-bf561/include/mach/portmux.h b/trunk/arch/blackfin/mach-bf561/include/mach/portmux.h index 2e5ad6347dea..a6ee8206efb6 100644 --- a/trunk/arch/blackfin/mach-bf561/include/mach/portmux.h +++ b/trunk/arch/blackfin/mach-bf561/include/mach/portmux.h @@ -85,6 +85,5 @@ #define P_SPI0_MOSI (P_DONTCARE) #define P_SPI0_MISO (P_DONTCARE) #define P_SPI0_SCK (P_DONTCARE) -#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2 #endif /* _MACH_PORTMUX_H_ */ diff --git a/trunk/arch/blackfin/mach-common/clocks-init.c b/trunk/arch/blackfin/mach-common/clocks-init.c index 9dddb6f8cc85..5d182abefc7b 100644 --- a/trunk/arch/blackfin/mach-common/clocks-init.c +++ b/trunk/arch/blackfin/mach-common/clocks-init.c @@ -14,7 +14,6 @@ #include #include -#define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */ #define PLL_CTL_VAL \ (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \ (PLL_BYPASS << 8) | (ANOMALY_05000265 ? 0x8000 : 0)) @@ -77,7 +76,7 @@ void init_clocks(void) bfin_write_PLL_DIV(CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); #ifdef EBIU_SDGCTL bfin_write_EBIU_SDRRC(mem_SDRRC); - bfin_write_EBIU_SDGCTL((bfin_read_EBIU_SDGCTL() & SDGCTL_WIDTH) | mem_SDGCTL); + bfin_write_EBIU_SDGCTL(mem_SDGCTL); #else bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() & ~(SRREQ)); do_sync(); diff --git a/trunk/arch/blackfin/mach-common/entry.S b/trunk/arch/blackfin/mach-common/entry.S index 88de053bbe8e..fae774651374 100644 --- a/trunk/arch/blackfin/mach-common/entry.S +++ b/trunk/arch/blackfin/mach-common/entry.S @@ -151,6 +151,13 @@ ENTRY(_ex_syscall) jump.s _bfin_return_from_exception; ENDPROC(_ex_syscall) +ENTRY(_ex_soft_bp) + r7 = retx; + r7 += -2; + retx = r7; + jump.s _ex_trap_c; +ENDPROC(_ex_soft_bp) + ENTRY(_ex_single_step) /* If we just returned from an interrupt, the single step event is for the RTI instruction. */ @@ -1080,7 +1087,7 @@ ENTRY(_ex_table) * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined */ .long _ex_syscall /* 0x00 - User Defined - Linux Syscall */ - .long _ex_trap_c /* 0x01 - User Defined - Software breakpoint */ + .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */ #ifdef CONFIG_KGDB .long _ex_trap_c /* 0x02 - User Defined - KGDB initial connection and break signal trap */ diff --git a/trunk/arch/blackfin/mach-common/head.S b/trunk/arch/blackfin/mach-common/head.S index 698d4c05947e..e1e42c029e15 100644 --- a/trunk/arch/blackfin/mach-common/head.S +++ b/trunk/arch/blackfin/mach-common/head.S @@ -17,19 +17,6 @@ __INIT -ENTRY(__init_clear_bss) - r2 = r2 - r1; - cc = r2 == 0; - if cc jump .L_bss_done; - r2 >>= 2; - p1 = r1; - p2 = r2; - lsetup (1f, 1f) lc0 = p2; -1: [p1++] = r0; -.L_bss_done: - rts; -ENDPROC(__init_clear_bss) - #define INITIAL_STACK (L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) ENTRY(__start) @@ -157,35 +144,6 @@ ENTRY(__start) call _init_early_exception_vectors; #endif - r0 = 0 (x); - /* Zero out all of the fun bss regions */ -#if L1_DATA_A_LENGTH > 0 - r1.l = __sbss_l1; - r1.h = __sbss_l1; - r2.l = __ebss_l1; - r2.h = __ebss_l1; - call __init_clear_bss -#endif -#if L1_DATA_B_LENGTH > 0 - r1.l = __sbss_b_l1; - r1.h = __sbss_b_l1; - r2.l = __ebss_b_l1; - r2.h = __ebss_b_l1; - call __init_clear_bss -#endif -#if L2_LENGTH > 0 - r1.l = __sbss_l2; - r1.h = __sbss_l2; - r2.l = __ebss_l2; - r2.h = __ebss_l2; - call __init_clear_bss -#endif - r1.l = ___bss_start; - r1.h = ___bss_start; - r2.l = ___bss_stop; - r2.h = ___bss_stop; - call __init_clear_bss - /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bfin_relocate_l1_mem; #ifdef CONFIG_BFIN_KERNEL_CLOCK @@ -227,6 +185,19 @@ ENDPROC(__start) # define WDOG_CTL WDOGA_CTL #endif +ENTRY(__init_clear_bss) + r2 = r2 - r1; + cc = r2 == 0; + if cc jump .L_bss_done; + r2 >>= 2; + p1 = r1; + p2 = r2; + lsetup (1f, 1f) lc0 = p2; +1: [p1++] = r0; +.L_bss_done: + rts; +ENDPROC(__init_clear_bss) + ENTRY(_real_start) /* Enable nested interrupts */ [--sp] = reti; @@ -238,6 +209,35 @@ ENTRY(_real_start) w[p0] = r0; ssync; + r0 = 0 (x); + /* Zero out all of the fun bss regions */ +#if L1_DATA_A_LENGTH > 0 + r1.l = __sbss_l1; + r1.h = __sbss_l1; + r2.l = __ebss_l1; + r2.h = __ebss_l1; + call __init_clear_bss +#endif +#if L1_DATA_B_LENGTH > 0 + r1.l = __sbss_b_l1; + r1.h = __sbss_b_l1; + r2.l = __ebss_b_l1; + r2.h = __ebss_b_l1; + call __init_clear_bss +#endif +#if L2_LENGTH > 0 + r1.l = __sbss_l2; + r1.h = __sbss_l2; + r2.l = __ebss_l2; + r2.h = __ebss_l2; + call __init_clear_bss +#endif + r1.l = ___bss_start; + r1.h = ___bss_start; + r2.l = ___bss_stop; + r2.h = ___bss_stop; + call __init_clear_bss + /* Pass the u-boot arguments to the global value command line */ R0 = R7; call _cmdline_init; diff --git a/trunk/arch/blackfin/mach-common/interrupt.S b/trunk/arch/blackfin/mach-common/interrupt.S index 43c4eb9acb65..473df0f7fa78 100644 --- a/trunk/arch/blackfin/mach-common/interrupt.S +++ b/trunk/arch/blackfin/mach-common/interrupt.S @@ -195,7 +195,7 @@ ENDPROC(_evt_ivhw) /* Interrupt routine for evt2 (NMI). * We don't actually use this, so just return. * For inner circle type details, please see: - * http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:nmi + * http://docs.blackfin.uclinux.org/doku.php?id=linux:nmi */ ENTRY(_evt_nmi) .weak _evt_nmi diff --git a/trunk/arch/blackfin/mach-common/ints-priority.c b/trunk/arch/blackfin/mach-common/ints-priority.c index 202494568c6c..1bba6030dce9 100644 --- a/trunk/arch/blackfin/mach-common/ints-priority.c +++ b/trunk/arch/blackfin/mach-common/ints-priority.c @@ -1101,9 +1101,10 @@ int __init init_arch_irq(void) IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; -#ifdef SIC_IWR0 +#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) \ + || defined(BF538_FAMILY) || defined(CONFIG_BF51x) bfin_write_SIC_IWR0(IWR_DISABLE_ALL); -# ifdef SIC_IWR1 +#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x) /* BF52x/BF51x system reset does not properly reset SIC_IWR1 which * will screw up the bootrom as it relies on MDMA0/1 waking it * up from IDLE instructions. See this report for more info: @@ -1113,8 +1114,10 @@ int __init init_arch_irq(void) bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11)); else bfin_write_SIC_IWR1(IWR_DISABLE_ALL); -# endif -# ifdef SIC_IWR2 +#else + bfin_write_SIC_IWR1(IWR_DISABLE_ALL); +#endif +# ifdef CONFIG_BF54x bfin_write_SIC_IWR2(IWR_DISABLE_ALL); # endif #else diff --git a/trunk/arch/blackfin/mach-common/pm.c b/trunk/arch/blackfin/mach-common/pm.c index f48a6aebb49b..d3d70fd67c16 100644 --- a/trunk/arch/blackfin/mach-common/pm.c +++ b/trunk/arch/blackfin/mach-common/pm.c @@ -82,9 +82,10 @@ void bfin_pm_suspend_standby_enter(void) bfin_pm_standby_restore(); -#ifdef SIC_IWR0 +#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) || \ + defined(CONFIG_BF538) || defined(CONFIG_BF539) || defined(CONFIG_BF51x) bfin_write_SIC_IWR0(IWR_DISABLE_ALL); -# ifdef SIC_IWR1 +#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x) /* BF52x system reset does not properly reset SIC_IWR1 which * will screw up the bootrom as it relies on MDMA0/1 waking it * up from IDLE instructions. See this report for more info: @@ -94,8 +95,10 @@ void bfin_pm_suspend_standby_enter(void) bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11)); else bfin_write_SIC_IWR1(IWR_DISABLE_ALL); -# endif -# ifdef SIC_IWR2 +#else + bfin_write_SIC_IWR1(IWR_DISABLE_ALL); +#endif +# ifdef CONFIG_BF54x bfin_write_SIC_IWR2(IWR_DISABLE_ALL); # endif #else diff --git a/trunk/arch/frv/mm/dma-alloc.c b/trunk/arch/frv/mm/dma-alloc.c index 44840e73e907..dc6522c464d4 100644 --- a/trunk/arch/frv/mm/dma-alloc.c +++ b/trunk/arch/frv/mm/dma-alloc.c @@ -36,10 +36,10 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 153e727a6e8e..6183aeccecf1 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -221,11 +221,7 @@ config IA64_HP_SIM config IA64_XEN_GUEST bool "Xen guest" - select SWIOTLB depends on XEN - help - Build a kernel that runs on Xen guest domain. At this moment only - 16KB page size in supported. endchoice @@ -483,7 +479,8 @@ config HOLES_IN_ZONE default y if VIRTUAL_MEM_MAP config HAVE_ARCH_EARLY_PFN_TO_NID - def_bool NUMA && SPARSEMEM + def_bool y + depends on NEED_MULTIPLE_NODES config HAVE_ARCH_NODEDATA_EXTENSION def_bool y @@ -638,17 +635,6 @@ config DMAR and include PCI device scope covered by these DMA remapping devices. -config DMAR_DEFAULT_ON - def_bool y - prompt "Enable DMA Remapping Devices by default" - depends on DMAR - help - Selecting this option will enable a DMAR device at boot time if - one is found. If this option is not selected, DMAR support can - be enabled by passing intel_iommu=on to the kernel. It is - recommended you say N here while the DMAR code remains - experimental. - endmenu endif diff --git a/trunk/arch/ia64/configs/xen_domu_defconfig b/trunk/arch/ia64/configs/xen_domu_defconfig deleted file mode 100644 index 0bb0714dc19d..000000000000 --- a/trunk/arch/ia64/configs/xen_domu_defconfig +++ /dev/null @@ -1,1601 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc1 -# Fri Jan 16 11:49:59 2009 -# -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=20 -CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y -# CONFIG_GROUP_SCHED is not set - -# -# Control Group support -# -# CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set -# CONFIG_IPC_NS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -# CONFIG_EMBEDDED is not set -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -CONFIG_KALLSYMS_STRIP_GENERATED=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_DMA_ATTRS=y -CONFIG_USE_GENERIC_SMP_HELPERS=y -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set -CONFIG_FREEZER=y - -# -# Processor type and features -# -CONFIG_IA64=y -CONFIG_64BIT=y -CONFIG_ZONE_DMA=y -CONFIG_QUICKLIST=y -CONFIG_MMU=y -CONFIG_SWIOTLB=y -CONFIG_IOMMU_HELPER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_HAVE_SETUP_PER_CPU_AREA=y -CONFIG_DMI=y -CONFIG_EFI=y -CONFIG_GENERIC_IOMAP=y -CONFIG_SCHED_OMIT_FRAME_POINTER=y -CONFIG_AUDIT_ARCH=y -CONFIG_PARAVIRT_GUEST=y -CONFIG_PARAVIRT=y -CONFIG_XEN=y -CONFIG_XEN_XENCOMM=y -CONFIG_NO_IDLE_HZ=y -# CONFIG_IA64_GENERIC is not set -# CONFIG_IA64_DIG is not set -# CONFIG_IA64_DIG_VTD is not set -# CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_HP_ZX1_SWIOTLB is not set -# CONFIG_IA64_SGI_SN2 is not set -# CONFIG_IA64_SGI_UV is not set -# CONFIG_IA64_HP_SIM is not set -CONFIG_IA64_XEN_GUEST=y -# CONFIG_ITANIUM is not set -CONFIG_MCKINLEY=y -# CONFIG_IA64_PAGE_SIZE_4KB is not set -# CONFIG_IA64_PAGE_SIZE_8KB is not set -CONFIG_IA64_PAGE_SIZE_16KB=y -# CONFIG_IA64_PAGE_SIZE_64KB is not set -CONFIG_PGTABLE_3=y -# CONFIG_PGTABLE_4 is not set -CONFIG_HZ=250 -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -# CONFIG_SCHED_HRTICK is not set -CONFIG_IA64_L1_CACHE_SHIFT=7 -CONFIG_IA64_CYCLONE=y -CONFIG_IOSAPIC=y -CONFIG_FORCE_MAX_ZONEORDER=17 -# CONFIG_VIRT_CPU_ACCOUNTING is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=16 -CONFIG_HOTPLUG_CPU=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -# CONFIG_SCHED_SMT is not set -CONFIG_PERMIT_BSP_REMOVE=y -CONFIG_FORCE_CPEI_RETARGET=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_NR_QUICK=1 -CONFIG_VIRT_TO_BUS=y -CONFIG_UNEVICTABLE_LRU=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_DISCONTIGMEM_ENABLE=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_VIRTUAL_MEM_MAP=y -CONFIG_HOLES_IN_ZONE=y -# CONFIG_IA32_SUPPORT is not set -# CONFIG_COMPAT_FOR_U64_ALIGNMENT is not set -CONFIG_IA64_MCA_RECOVERY=y -CONFIG_PERFMON=y -CONFIG_IA64_PALINFO=y -# CONFIG_IA64_MC_ERR_INJECT is not set -# CONFIG_IA64_ESI is not set -# CONFIG_IA64_HP_AML_NFW is not set -CONFIG_KEXEC=y -# CONFIG_CRASH_DUMP is not set - -# -# Firmware Drivers -# -# CONFIG_FIRMWARE_MEMMAP is not set -CONFIG_EFI_VARS=y -CONFIG_EFI_PCDP=y -CONFIG_DMIID=y -CONFIG_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_HAVE_AOUT is not set -CONFIG_BINFMT_MISC=m - -# -# Power management and ACPI options -# -CONFIG_PM=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_SLEEP=y -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_ACPI=y -CONFIG_ACPI_SLEEP=y -CONFIG_ACPI_PROCFS=y -CONFIG_ACPI_PROCFS_POWER=y -CONFIG_ACPI_SYSFS_POWER=y -CONFIG_ACPI_PROC_EVENT=y -CONFIG_ACPI_BUTTON=m -CONFIG_ACPI_FAN=m -# CONFIG_ACPI_DOCK is not set -CONFIG_ACPI_PROCESSOR=m -CONFIG_ACPI_HOTPLUG_CPU=y -CONFIG_ACPI_THERMAL=m -# CONFIG_ACPI_CUSTOM_DSDT is not set -CONFIG_ACPI_BLACKLIST_YEAR=0 -# CONFIG_ACPI_DEBUG is not set -# CONFIG_ACPI_PCI_SLOT is not set -CONFIG_ACPI_SYSTEM=y -CONFIG_ACPI_CONTAINER=m - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Bus options (PCI, PCMCIA) -# -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y -# CONFIG_PCIEPORTBUS is not set -CONFIG_ARCH_SUPPORTS_MSI=y -# CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY=y -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_STUB is not set -CONFIG_HOTPLUG_PCI=m -# CONFIG_HOTPLUG_PCI_FAKE is not set -CONFIG_HOTPLUG_PCI_ACPI=m -# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set -# CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_SHPC is not set -# CONFIG_PCCARD is not set -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NET_NS is not set -CONFIG_COMPAT_NET_DEV_OPS=y -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -CONFIG_ARPD=y -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -# CONFIG_WIRELESS is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_PNP=y -CONFIG_PNP_DEBUG_MESSAGES=y - -# -# Protocols -# -CONFIG_PNPACPI=y -CONFIG_BLK_DEV=y -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -CONFIG_XEN_BLKDEV_FRONTEND=y -# CONFIG_BLK_DEV_HD is not set -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -# CONFIG_C2PORT is not set -CONFIG_HAVE_IDE=y -CONFIG_IDE=y - -# -# Please see Documentation/ide/ide.txt for help/info on IDE drives -# -CONFIG_IDE_TIMINGS=y -CONFIG_IDE_ATAPI=y -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_IDE_GD=y -CONFIG_IDE_GD_ATA=y -# CONFIG_IDE_GD_ATAPI is not set -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEACPI is not set -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_IDE_PROC_FS=y - -# -# IDE chipset support/bugfixes -# -# CONFIG_IDE_GENERIC is not set -# CONFIG_BLK_DEV_PLATFORM is not set -# CONFIG_BLK_DEV_IDEPNP is not set -CONFIG_BLK_DEV_IDEDMA_SFF=y - -# -# PCI IDE chipsets support -# -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_PCIBUS_ORDER=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -CONFIG_BLK_DEV_CMD64X=y -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_IT8172 is not set -# CONFIG_BLK_DEV_IT8213 is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_BLK_DEV_TC86C001 is not set -CONFIG_BLK_DEV_IDEDMA=y - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -CONFIG_SCSI_NETLINK=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=m -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=m -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=m -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -CONFIG_SCSI_SPI_ATTRS=y -CONFIG_SCSI_FC_ATTRS=y -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_CXGB3_ISCSI is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_LIBFC is not set -# CONFIG_FCOE is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_STEX is not set -CONFIG_SCSI_SYM53C8XX_2=y -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -CONFIG_SCSI_SYM53C8XX_MMIO=y -CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_DH is not set -# CONFIG_ATA is not set -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -# CONFIG_MD_RAID10 is not set -# CONFIG_MD_RAID456 is not set -CONFIG_MD_MULTIPATH=m -# CONFIG_MD_FAULTY is not set -CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_MIRROR=m -CONFIG_DM_ZERO=m -# CONFIG_DM_MULTIPATH is not set -# CONFIG_DM_DELAY is not set -# CONFIG_DM_UEVENT is not set -CONFIG_FUSION=y -CONFIG_FUSION_SPI=y -CONFIG_FUSION_FC=y -# CONFIG_FUSION_SAS is not set -CONFIG_FUSION_MAX_SGE=128 -CONFIG_FUSION_CTL=y -# CONFIG_FUSION_LOGGING is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# Enable only one of the two stacks, unless you know what you are doing -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -# CONFIG_I2O is not set -CONFIG_NETDEVICES=y -CONFIG_DUMMY=m -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_NET_SB1000 is not set -# CONFIG_ARCNET is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=m -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -CONFIG_NET_TULIP=y -# CONFIG_DE2104X is not set -CONFIG_TULIP=m -# CONFIG_TULIP_MWI is not set -# CONFIG_TULIP_MMIO is not set -# CONFIG_TULIP_NAPI is not set -# CONFIG_DE4X5 is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_DM9102 is not set -# CONFIG_ULI526X is not set -# CONFIG_HP100 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -CONFIG_E100=m -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_R6040 is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SMSC9420 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_SC92031 is not set -# CONFIG_ATL2 is not set -CONFIG_NETDEV_1000=y -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -CONFIG_E1000=y -# CONFIG_E1000E is not set -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_VIA_VELOCITY is not set -CONFIG_TIGON3=y -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -# CONFIG_ATL1E is not set -# CONFIG_JME is not set -CONFIG_NETDEV_10000=y -# CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3_DEPENDS=y -# CONFIG_CHELSIO_T3 is not set -# CONFIG_ENIC is not set -# CONFIG_IXGBE is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set -# CONFIG_NIU is not set -# CONFIG_MLX4_EN is not set -# CONFIG_MLX4_CORE is not set -# CONFIG_TEHUTI is not set -# CONFIG_BNX2X is not set -# CONFIG_QLGE is not set -# CONFIG_SFC is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_WAN is not set -CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -CONFIG_NETCONSOLE=y -# CONFIG_NETCONSOLE_DYNAMIC is not set -CONFIG_NETPOLL=y -# CONFIG_NETPOLL_TRAP is not set -CONFIG_NET_POLL_CONTROLLER=y -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_ELANTECH is not set -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -CONFIG_GAMEPORT=m -# CONFIG_GAMEPORT_NS558 is not set -# CONFIG_GAMEPORT_L4 is not set -# CONFIG_GAMEPORT_EMU10K1 is not set -# CONFIG_GAMEPORT_FM801 is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -CONFIG_SERIAL_NONSTANDARD=y -# CONFIG_COMPUTONE is not set -# CONFIG_ROCKETPORT is not set -# CONFIG_CYCLADES is not set -# CONFIG_DIGIEPCA is not set -# CONFIG_MOXA_INTELLIO is not set -# CONFIG_MOXA_SMARTIO is not set -# CONFIG_ISI is not set -# CONFIG_SYNCLINKMP is not set -# CONFIG_SYNCLINK_GT is not set -# CONFIG_N_HDLC is not set -# CONFIG_RISCOM8 is not set -# CONFIG_SPECIALIX is not set -# CONFIG_SX is not set -# CONFIG_RIO is not set -# CONFIG_STALDRV is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_PNP=y -CONFIG_SERIAL_8250_NR_UARTS=6 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -CONFIG_HVC_DRIVER=y -CONFIG_HVC_IRQ=y -CONFIG_HVC_XEN=y -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -CONFIG_EFI_RTC=y -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -CONFIG_RAW_DRIVER=m -CONFIG_MAX_RAW_DEVS=256 -CONFIG_HPET=y -CONFIG_HPET_MMAP=y -# CONFIG_HANGCHECK_TIMER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -CONFIG_I2C=m -CONFIG_I2C_BOARDINFO=y -# CONFIG_I2C_CHARDEV is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_ALGOBIT=m - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_AT24 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set -# CONFIG_W1 is not set -CONFIG_POWER_SUPPLY=y -# CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_PDA_POWER is not set -# CONFIG_BATTERY_DS2760 is not set -# CONFIG_BATTERY_BQ27x00 is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_LTC4245 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_SENSORS_LIS3LV02D is not set -# CONFIG_HWMON_DEBUG_CHIP is not set -CONFIG_THERMAL=m -# CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -CONFIG_AGP=m -CONFIG_DRM=m -CONFIG_DRM_TDFX=m -CONFIG_DRM_R128=m -CONFIG_DRM_RADEON=m -CONFIG_DRM_MGA=m -CONFIG_DRM_SIS=m -# CONFIG_DRM_VIA is not set -# CONFIG_DRM_SAVAGE is not set -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_HID_PID is not set -# CONFIG_USB_HIDDEV is not set - -# -# Special HID drivers -# -CONFIG_HID_COMPAT=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_NTRIG=y -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_SUNPLUS=y -# CONFIG_GREENASIA_FF is not set -CONFIG_HID_TOPSEED=y -# CONFIG_THRUSTMASTER_FF is not set -# CONFIG_ZEROPLUS_FF is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_EHCI_HCD=m -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -CONFIG_USB_OHCI_HCD=m -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -CONFIG_USB_UHCI_HCD=y -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_HWA_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; -# - -# -# see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set -# CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# -# CONFIG_UWB is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_RTC_CLASS is not set -# CONFIG_DMADEVICES is not set -# CONFIG_UIO is not set -CONFIG_XEN_BALLOON=y -CONFIG_XEN_SCRUB_PAGES=y -CONFIG_XENFS=y -CONFIG_XEN_COMPAT_XENFS=y -# CONFIG_STAGING is not set -# CONFIG_MSPEC is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4_FS is not set -CONFIG_JBD=y -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=y -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_POSIX_ACL=y -CONFIG_REISERFS_FS_SECURITY=y -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_FILE_LOCKING=y -CONFIG_XFS_FS=y -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_RT is not set -# CONFIG_XFS_DEBUG is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -# CONFIG_MSDOS_FS is not set -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_NTFS_FS=m -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -CONFIG_NFSD_V4=y -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -CONFIG_SUNRPC_GSS=m -# CONFIG_SUNRPC_REGISTER_V4 is not set -CONFIG_RPCSEC_GSS_KRB5=m -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y -CONFIG_SMB_NLS_REMOTE="cp437" -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -CONFIG_EFI_PARTITION=y -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m -# CONFIG_DLM is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=2048 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_TRACE_BRANCH_PROFILING is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set -# CONFIG_SAMPLES is not set -CONFIG_IA64_GRANULE_16MB=y -# CONFIG_IA64_GRANULE_64MB is not set -# CONFIG_IA64_PRINT_HAZARDS is not set -# CONFIG_DISABLE_VHPT is not set -# CONFIG_IA64_DEBUG_CMPXCHG is not set -# CONFIG_IA64_DEBUG_IRQ is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_MANAGER=m -CONFIG_CRYPTO_MANAGER2=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=m -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=m -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_HIFN_795X is not set -CONFIG_HAVE_KVM=y -CONFIG_VIRTUALIZATION=y -# CONFIG_KVM is not set -# CONFIG_VIRTIO_PCI is not set -# CONFIG_VIRTIO_BALLOON is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_T10DIF is not set -CONFIG_CRC_ITU_T=m -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_PENDING_IRQ=y -CONFIG_IRQ_PER_CPU=y -# CONFIG_IOMMU_API is not set diff --git a/trunk/arch/ia64/include/asm/kvm.h b/trunk/arch/ia64/include/asm/kvm.h index bfa86b6af7cd..68aa6da807c1 100644 --- a/trunk/arch/ia64/include/asm/kvm.h +++ b/trunk/arch/ia64/include/asm/kvm.h @@ -25,10 +25,6 @@ #include -/* Select x86 specific features in */ -#define __KVM_HAVE_IOAPIC -#define __KVM_HAVE_DEVICE_ASSIGNMENT - /* Architectural interrupt line count. */ #define KVM_NR_INTERRUPTS 256 diff --git a/trunk/arch/ia64/include/asm/mmzone.h b/trunk/arch/ia64/include/asm/mmzone.h index f2ca32069b3f..34efe88eb849 100644 --- a/trunk/arch/ia64/include/asm/mmzone.h +++ b/trunk/arch/ia64/include/asm/mmzone.h @@ -31,6 +31,10 @@ static inline int pfn_to_nid(unsigned long pfn) #endif } +#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID +extern int early_pfn_to_nid(unsigned long pfn); +#endif + #ifdef CONFIG_IA64_DIG /* DIG systems are small */ # define MAX_PHYSNODE_ID 8 # define NR_NODE_MEMBLKS (MAX_NUMNODES * 8) diff --git a/trunk/arch/ia64/include/asm/sn/bte.h b/trunk/arch/ia64/include/asm/sn/bte.h index 96798d2da7c2..5efecf06c9a4 100644 --- a/trunk/arch/ia64/include/asm/sn/bte.h +++ b/trunk/arch/ia64/include/asm/sn/bte.h @@ -39,7 +39,7 @@ /* BTE status register only supports 16 bits for length field */ #define BTE_LEN_BITS (16) #define BTE_LEN_MASK ((1 << BTE_LEN_BITS) - 1) -#define BTE_MAX_XFER (BTE_LEN_MASK << L1_CACHE_SHIFT) +#define BTE_MAX_XFER ((1 << BTE_LEN_BITS) * L1_CACHE_BYTES) /* Define hardware */ diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index e13125058bed..5cfd3d91001a 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -507,7 +507,7 @@ static int iosapic_find_sharable_irq(unsigned long trigger, unsigned long pol) if (trigger == IOSAPIC_EDGE) return -EINVAL; - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i <= NR_IRQS; i++) { info = &iosapic_intr_info[i]; if (info->trigger == trigger && info->polarity == pol && (info->dmode == IOSAPIC_FIXED || diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 52290547c85b..11463994a7d5 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -736,15 +736,14 @@ int __cpu_disable(void) return -EBUSY; } - cpu_clear(cpu, cpu_online_map); - if (migrate_platform_irqs(cpu)) { cpu_set(cpu, cpu_online_map); - return -EBUSY; + return (-EBUSY); } remove_siblinginfo(cpu); fixup_irqs(); + cpu_clear(cpu, cpu_online_map); local_flush_tlb_all(); cpu_clear(cpu, cpu_callin_map); return 0; diff --git a/trunk/arch/ia64/kernel/unwind.c b/trunk/arch/ia64/kernel/unwind.c index b6c0e63a0bf6..67810b77d998 100644 --- a/trunk/arch/ia64/kernel/unwind.c +++ b/trunk/arch/ia64/kernel/unwind.c @@ -2149,7 +2149,7 @@ unw_remove_unwind_table (void *handle) /* next, remove hash table entries for this table */ - for (index = 0; index < UNW_HASH_SIZE; ++index) { + for (index = 0; index <= UNW_HASH_SIZE; ++index) { tmp = unw.cache + unw.hash[index]; if (unw.hash[index] >= UNW_CACHE_SIZE || tmp->ip < table->start || tmp->ip >= table->end) diff --git a/trunk/arch/ia64/kvm/kvm-ia64.c b/trunk/arch/ia64/kvm/kvm-ia64.c index 28f982045f29..4e586f6110aa 100644 --- a/trunk/arch/ia64/kvm/kvm-ia64.c +++ b/trunk/arch/ia64/kvm/kvm-ia64.c @@ -1337,10 +1337,6 @@ static void kvm_release_vm_pages(struct kvm *kvm) } } -void kvm_arch_sync_events(struct kvm *kvm) -{ -} - void kvm_arch_destroy_vm(struct kvm *kvm) { kvm_iommu_unmap_guest(kvm); diff --git a/trunk/arch/ia64/kvm/process.c b/trunk/arch/ia64/kvm/process.c index 230eae482f32..552d07724207 100644 --- a/trunk/arch/ia64/kvm/process.c +++ b/trunk/arch/ia64/kvm/process.c @@ -455,18 +455,13 @@ fpswa_ret_t vmm_fp_emulate(int fp_fault, void *bundle, unsigned long *ipsr, if (!vmm_fpswa_interface) return (fpswa_ret_t) {-1, 0, 0, 0}; - memset(&fp_state, 0, sizeof(fp_state_t)); - /* - * compute fp_state. only FP registers f6 - f11 are used by the - * vmm, so set those bits in the mask and set the low volatile - * pointer to point to these registers. + * Just let fpswa driver to use hardware fp registers. + * No fp register is valid in memory. */ - fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */ - - fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6; + memset(&fp_state, 0, sizeof(fp_state_t)); - /* + /* * unsigned long (*EFI_FPSWA) ( * unsigned long trap_type, * void *Bundle, @@ -550,6 +545,10 @@ void reflect_interruption(u64 ifa, u64 isr, u64 iim, status = vmm_handle_fpu_swa(0, regs, isr); if (!status) return ; + else if (-EAGAIN == status) { + vcpu_decrement_iip(vcpu); + return ; + } break; } diff --git a/trunk/arch/ia64/mm/numa.c b/trunk/arch/ia64/mm/numa.c index 3efea7d0a351..b73bf1838e57 100644 --- a/trunk/arch/ia64/mm/numa.c +++ b/trunk/arch/ia64/mm/numa.c @@ -58,7 +58,7 @@ paddr_to_nid(unsigned long paddr) * SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where * the section resides. */ -int __meminit __early_pfn_to_nid(unsigned long pfn) +int early_pfn_to_nid(unsigned long pfn) { int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec; @@ -70,7 +70,7 @@ int __meminit __early_pfn_to_nid(unsigned long pfn) return node_memblk[i].nid; } - return -1; + return 0; } #ifdef CONFIG_MEMORY_HOTPLUG diff --git a/trunk/arch/ia64/sn/kernel/bte.c b/trunk/arch/ia64/sn/kernel/bte.c index c6d6b62db66c..9456d4034024 100644 --- a/trunk/arch/ia64/sn/kernel/bte.c +++ b/trunk/arch/ia64/sn/kernel/bte.c @@ -97,10 +97,9 @@ bte_result_t bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification) return BTE_SUCCESS; } - BUG_ON(len & L1_CACHE_MASK); - BUG_ON(src & L1_CACHE_MASK); - BUG_ON(dest & L1_CACHE_MASK); - BUG_ON(len > BTE_MAX_XFER); + BUG_ON((len & L1_CACHE_MASK) || + (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)); + BUG_ON(!(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT))); /* * Start with interface corresponding to cpu number diff --git a/trunk/arch/ia64/sn/kernel/io_acpi_init.c b/trunk/arch/ia64/sn/kernel/io_acpi_init.c index d0223abbbbd4..c5a214026a77 100644 --- a/trunk/arch/ia64/sn/kernel/io_acpi_init.c +++ b/trunk/arch/ia64/sn/kernel/io_acpi_init.c @@ -443,7 +443,7 @@ sn_acpi_slot_fixup(struct pci_dev *dev) size = pci_resource_len(dev, PCI_ROM_RESOURCE); addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], size); - image_size = pci_get_rom_size(dev, addr, size); + image_size = pci_get_rom_size(addr, size); dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; dev->resource[PCI_ROM_RESOURCE].end = (unsigned long) addr + image_size - 1; diff --git a/trunk/arch/ia64/sn/kernel/io_init.c b/trunk/arch/ia64/sn/kernel/io_init.c index e2eb2da60f96..4e1801bad83a 100644 --- a/trunk/arch/ia64/sn/kernel/io_init.c +++ b/trunk/arch/ia64/sn/kernel/io_init.c @@ -269,7 +269,7 @@ sn_io_slot_fixup(struct pci_dev *dev) rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE), size + 1); - image_size = pci_get_rom_size(dev, rom, size + 1); + image_size = pci_get_rom_size(rom, size + 1); dev->resource[PCI_ROM_RESOURCE].end = dev->resource[PCI_ROM_RESOURCE].start + image_size - 1; diff --git a/trunk/arch/ia64/xen/Kconfig b/trunk/arch/ia64/xen/Kconfig index 515e0826803a..f1683a20275b 100644 --- a/trunk/arch/ia64/xen/Kconfig +++ b/trunk/arch/ia64/xen/Kconfig @@ -8,7 +8,8 @@ config XEN depends on PARAVIRT && MCKINLEY && IA64_PAGE_SIZE_16KB && EXPERIMENTAL select XEN_XENCOMM select NO_IDLE_HZ - # followings are required to save/restore. + + # those are required to save/restore. select ARCH_SUSPEND_POSSIBLE select SUSPEND select PM_SLEEP diff --git a/trunk/arch/ia64/xen/xen_pv_ops.c b/trunk/arch/ia64/xen/xen_pv_ops.c index 936cff3c96e0..04cd12350455 100644 --- a/trunk/arch/ia64/xen/xen_pv_ops.c +++ b/trunk/arch/ia64/xen/xen_pv_ops.c @@ -153,7 +153,7 @@ xen_post_smp_prepare_boot_cpu(void) xen_setup_vcpu_info_placement(); } -static const struct pv_init_ops xen_init_ops __initconst = { +static const struct pv_init_ops xen_init_ops __initdata = { .banner = xen_banner, .reserve_memory = xen_reserve_memory, @@ -337,7 +337,7 @@ xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op); } -static const struct pv_iosapic_ops xen_iosapic_ops __initconst = { +static const struct pv_iosapic_ops xen_iosapic_ops __initdata = { .pcat_compat_init = xen_pcat_compat_init, .__get_irq_chip = xen_iosapic_get_irq_chip, diff --git a/trunk/arch/m68k/atari/ataints.c b/trunk/arch/m68k/atari/ataints.c index 39478dd08e67..dba4afabb444 100644 --- a/trunk/arch/m68k/atari/ataints.c +++ b/trunk/arch/m68k/atari/ataints.c @@ -187,8 +187,8 @@ __asm__ (__ALIGN_STR "\n" \ " jbra ret_from_interrupt\n" \ : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]), \ "n" (PT_OFF_SR), "n" (n), \ - "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &st_mfp.int_mk_a) \ - : (n & 16 ? &tt_mfp.int_mk_b : &st_mfp.int_mk_b)), \ + "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &mfp.int_mk_a) \ + : (n & 16 ? &tt_mfp.int_mk_b : &mfp.int_mk_b)), \ "m" (preempt_count()), "di" (HARDIRQ_OFFSET) \ ); \ for (;;); /* fake noreturn */ \ @@ -366,14 +366,14 @@ void __init atari_init_IRQ(void) /* Initialize the MFP(s) */ #ifdef ATARI_USE_SOFTWARE_EOI - st_mfp.vec_adr = 0x48; /* Software EOI-Mode */ + mfp.vec_adr = 0x48; /* Software EOI-Mode */ #else - st_mfp.vec_adr = 0x40; /* Automatic EOI-Mode */ + mfp.vec_adr = 0x40; /* Automatic EOI-Mode */ #endif - st_mfp.int_en_a = 0x00; /* turn off MFP-Ints */ - st_mfp.int_en_b = 0x00; - st_mfp.int_mk_a = 0xff; /* no Masking */ - st_mfp.int_mk_b = 0xff; + mfp.int_en_a = 0x00; /* turn off MFP-Ints */ + mfp.int_en_b = 0x00; + mfp.int_mk_a = 0xff; /* no Masking */ + mfp.int_mk_b = 0xff; if (ATARIHW_PRESENT(TT_MFP)) { #ifdef ATARI_USE_SOFTWARE_EOI diff --git a/trunk/arch/m68k/atari/atakeyb.c b/trunk/arch/m68k/atari/atakeyb.c index 4add96d13b19..a5f33c059979 100644 --- a/trunk/arch/m68k/atari/atakeyb.c +++ b/trunk/arch/m68k/atari/atakeyb.c @@ -609,10 +609,10 @@ int atari_keyb_init(void) ACIA_RHTID : 0); /* make sure the interrupt line is up */ - } while ((st_mfp.par_dt_reg & 0x10) == 0); + } while ((mfp.par_dt_reg & 0x10) == 0); /* enable ACIA Interrupts */ - st_mfp.active_edge &= ~0x10; + mfp.active_edge &= ~0x10; atari_turnon_irq(IRQ_MFP_ACIA); ikbd_self_test = 1; diff --git a/trunk/arch/m68k/atari/config.c b/trunk/arch/m68k/atari/config.c index ae2d96e5d618..49c28cdbea5c 100644 --- a/trunk/arch/m68k/atari/config.c +++ b/trunk/arch/m68k/atari/config.c @@ -258,7 +258,7 @@ void __init config_atari(void) printk("STND_SHIFTER "); } } - if (hwreg_present(&st_mfp.par_dt_reg)) { + if (hwreg_present(&mfp.par_dt_reg)) { ATARIHW_SET(ST_MFP); printk("ST_MFP "); } diff --git a/trunk/arch/m68k/atari/debug.c b/trunk/arch/m68k/atari/debug.c index 28efdc33c1ae..702b15ccfab7 100644 --- a/trunk/arch/m68k/atari/debug.c +++ b/trunk/arch/m68k/atari/debug.c @@ -34,9 +34,9 @@ static struct console atari_console_driver = { static inline void ata_mfp_out(char c) { - while (!(st_mfp.trn_stat & 0x80)) /* wait for tx buf empty */ + while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ barrier(); - st_mfp.usart_dta = c; + mfp.usart_dta = c; } static void atari_mfp_console_write(struct console *co, const char *str, @@ -91,7 +91,7 @@ static int ata_par_out(char c) /* This a some-seconds timeout in case no printer is connected */ unsigned long i = loops_per_jiffy > 1 ? loops_per_jiffy : 10000000/HZ; - while ((st_mfp.par_dt_reg & 1) && --i) /* wait for BUSY == L */ + while ((mfp.par_dt_reg & 1) && --i) /* wait for BUSY == L */ ; if (!i) return 0; @@ -131,9 +131,9 @@ static void atari_par_console_write(struct console *co, const char *str, #if 0 int atari_mfp_console_wait_key(struct console *co) { - while (!(st_mfp.rcv_stat & 0x80)) /* wait for rx buf filled */ + while (!(mfp.rcv_stat & 0x80)) /* wait for rx buf filled */ barrier(); - return st_mfp.usart_dta; + return mfp.usart_dta; } int atari_scc_console_wait_key(struct console *co) @@ -175,12 +175,12 @@ static void __init atari_init_mfp_port(int cflag) baud = B9600; /* use default 9600bps for non-implemented rates */ baud -= B1200; /* baud_table[] starts at 1200bps */ - st_mfp.trn_stat &= ~0x01; /* disable TX */ - st_mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ - st_mfp.tim_ct_cd &= 0x70; /* stop timer D */ - st_mfp.tim_dt_d = baud_table[baud]; - st_mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ - st_mfp.trn_stat |= 0x01; /* enable TX */ + mfp.trn_stat &= ~0x01; /* disable TX */ + mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ + mfp.tim_ct_cd &= 0x70; /* stop timer D */ + mfp.tim_dt_d = baud_table[baud]; + mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ + mfp.trn_stat |= 0x01; /* enable TX */ } #define SCC_WRITE(reg, val) \ diff --git a/trunk/arch/m68k/atari/time.c b/trunk/arch/m68k/atari/time.c index a0531f34c617..d076ff8d1b39 100644 --- a/trunk/arch/m68k/atari/time.c +++ b/trunk/arch/m68k/atari/time.c @@ -27,9 +27,9 @@ void __init atari_sched_init(irq_handler_t timer_routine) { /* set Timer C data Register */ - st_mfp.tim_dt_c = INT_TICKS; + mfp.tim_dt_c = INT_TICKS; /* start timer C, div = 1:100 */ - st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 15) | 0x60; + mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60; /* install interrupt service routine for MFP Timer C */ if (request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW, "timer", timer_routine)) @@ -46,11 +46,11 @@ unsigned long atari_gettimeoffset (void) unsigned long ticks, offset = 0; /* read MFP timer C current value */ - ticks = st_mfp.tim_dt_c; + ticks = mfp.tim_dt_c; /* The probability of underflow is less than 2% */ if (ticks > INT_TICKS - INT_TICKS / 50) /* Check for pending timer interrupt */ - if (st_mfp.int_pn_b & (1 << 5)) + if (mfp.int_pn_b & (1 << 5)) offset = TICK_SIZE; ticks = INT_TICKS - ticks; diff --git a/trunk/arch/m68k/include/asm/atarihw.h b/trunk/arch/m68k/include/asm/atarihw.h index a714e1aa072a..1412b4ab202f 100644 --- a/trunk/arch/m68k/include/asm/atarihw.h +++ b/trunk/arch/m68k/include/asm/atarihw.h @@ -113,7 +113,7 @@ extern struct atari_hw_present atari_hw_present; * of nops on various machines. Somebody claimed that the tstb takes 600 ns. */ #define MFPDELAY() \ - __asm__ __volatile__ ( "tstb %0" : : "m" (st_mfp.par_dt_reg) : "cc" ); + __asm__ __volatile__ ( "tstb %0" : : "m" (mfp.par_dt_reg) : "cc" ); /* Do cache push/invalidate for DMA read/write. This function obeys the * snooping on some machines (Medusa) and processors: The Medusa itself can @@ -565,7 +565,7 @@ struct MFP u_char char_dummy23; u_char usart_dta; }; -# define st_mfp ((*(volatile struct MFP*)MFP_BAS)) +# define mfp ((*(volatile struct MFP*)MFP_BAS)) /* TT's second MFP */ diff --git a/trunk/arch/m68k/include/asm/atariints.h b/trunk/arch/m68k/include/asm/atariints.h index f597892e43a0..5748e99f4e26 100644 --- a/trunk/arch/m68k/include/asm/atariints.h +++ b/trunk/arch/m68k/include/asm/atariints.h @@ -113,7 +113,7 @@ static inline int get_mfp_bit( unsigned irq, int type ) { unsigned char mask, *reg; mask = 1 << (irq & 7); - reg = (unsigned char *)&st_mfp.int_en_a + type*4 + + reg = (unsigned char *)&mfp.int_en_a + type*4 + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); return( *reg & mask ); } @@ -123,7 +123,7 @@ static inline void set_mfp_bit( unsigned irq, int type ) { unsigned char mask, *reg; mask = 1 << (irq & 7); - reg = (unsigned char *)&st_mfp.int_en_a + type*4 + + reg = (unsigned char *)&mfp.int_en_a + type*4 + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); __asm__ __volatile__ ( "orb %0,%1" : : "di" (mask), "m" (*reg) : "memory" ); @@ -134,7 +134,7 @@ static inline void clear_mfp_bit( unsigned irq, int type ) { unsigned char mask, *reg; mask = ~(1 << (irq & 7)); - reg = (unsigned char *)&st_mfp.int_en_a + type*4 + + reg = (unsigned char *)&mfp.int_en_a + type*4 + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); if (type == MFP_PENDING || type == MFP_SERVICE) __asm__ __volatile__ ( "moveb %0,%1" diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index e61465a18c7e..600eef3f3ac7 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -603,7 +603,7 @@ config CAVIUM_OCTEON_SIMULATOR select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_HIGHMEM - select SYS_HAS_CPU_CAVIUM_OCTEON + select CPU_CAVIUM_OCTEON help The Octeon simulator is software performance model of the Cavium Octeon Processor. It supports simulating Octeon processors on x86 @@ -618,7 +618,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_HIGHMEM select SYS_HAS_EARLY_PRINTK - select SYS_HAS_CPU_CAVIUM_OCTEON + select CPU_CAVIUM_OCTEON select SWAP_IO_SPACE help This option supports all of the Octeon reference boards from Cavium @@ -1234,7 +1234,6 @@ config CPU_SB1 config CPU_CAVIUM_OCTEON bool "Cavium Octeon processor" - depends on SYS_HAS_CPU_CAVIUM_OCTEON select IRQ_CPU select IRQ_CPU_OCTEON select CPU_HAS_PREFETCH @@ -1315,9 +1314,6 @@ config SYS_HAS_CPU_RM9000 config SYS_HAS_CPU_SB1 bool -config SYS_HAS_CPU_CAVIUM_OCTEON - bool - # # CPU may reorder R->R, R->W, W->R, W->W # Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC @@ -1391,7 +1387,6 @@ config 32BIT config 64BIT bool "64-bit kernel" depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL - select HAVE_SYSCALL_WRAPPERS help Select this option if you want to build a 64-bit kernel. diff --git a/trunk/arch/mips/alchemy/common/time.c b/trunk/arch/mips/alchemy/common/time.c index f58d4ffb8945..6fd441d16af5 100644 --- a/trunk/arch/mips/alchemy/common/time.c +++ b/trunk/arch/mips/alchemy/common/time.c @@ -118,7 +118,7 @@ void __init plat_time_init(void) * setup counter 1 (RTC) to tick at full speed */ t = 0xffffff; - while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && --t) + while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && t--) asm volatile ("nop"); if (!t) goto cntr_err; @@ -127,7 +127,7 @@ void __init plat_time_init(void) au_sync(); t = 0xffffff; - while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t) + while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--) asm volatile ("nop"); if (!t) goto cntr_err; @@ -135,7 +135,7 @@ void __init plat_time_init(void) au_sync(); t = 0xffffff; - while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t) + while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--) asm volatile ("nop"); if (!t) goto cntr_err; diff --git a/trunk/arch/mips/include/asm/seccomp.h b/trunk/arch/mips/include/asm/seccomp.h index a6772e9507f5..36ed44070256 100644 --- a/trunk/arch/mips/include/asm/seccomp.h +++ b/trunk/arch/mips/include/asm/seccomp.h @@ -1,5 +1,6 @@ #ifndef __ASM_SECCOMP_H +#include #include #define __NR_seccomp_read __NR_read diff --git a/trunk/arch/mips/include/asm/spinlock.h b/trunk/arch/mips/include/asm/spinlock.h index 0884947ebe27..1a1f320c30d8 100644 --- a/trunk/arch/mips/include/asm/spinlock.h +++ b/trunk/arch/mips/include/asm/spinlock.h @@ -51,7 +51,6 @@ static inline int __raw_spin_is_contended(raw_spinlock_t *lock) return (((counters >> 14) - counters) & 0x1fff) > 1; } -#define __raw_spin_is_contended __raw_spin_is_contended static inline void __raw_spin_lock(raw_spinlock_t *lock) { diff --git a/trunk/arch/mips/kernel/irq.c b/trunk/arch/mips/kernel/irq.c index 4b4007b3083a..a0ff2b66e22b 100644 --- a/trunk/arch/mips/kernel/irq.c +++ b/trunk/arch/mips/kernel/irq.c @@ -111,6 +111,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif seq_printf(p, " %14s", irq_desc[i].chip->name); + seq_printf(p, "-%-8s", irq_desc[i].name); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index 2f8452b404c7..aa2c55e3b55f 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -64,9 +63,9 @@ #define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL)) #endif -SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len, - unsigned long, prot, unsigned long, flags, unsigned long, fd, - unsigned long, pgoff) +asmlinkage unsigned long +sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot, + unsigned long flags, unsigned long fd, unsigned long pgoff) { struct file * file = NULL; unsigned long error; @@ -122,21 +121,21 @@ struct rlimit32 { int rlim_max; }; -SYSCALL_DEFINE4(32_truncate64, const char __user *, path, - unsigned long, __dummy, unsigned long, a2, unsigned long, a3) +asmlinkage long sys32_truncate64(const char __user * path, + unsigned long __dummy, int a2, int a3) { return sys_truncate(path, merge_64(a2, a3)); } -SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy, - unsigned long, a2, unsigned long, a3) +asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, + int a2, int a3) { return sys_ftruncate(fd, merge_64(a2, a3)); } -SYSCALL_DEFINE5(32_llseek, unsigned long, fd, unsigned long, offset_high, - unsigned long, offset_low, loff_t __user *, result, - unsigned long, origin) +asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high, + unsigned int offset_low, loff_t __user * result, + unsigned int origin) { return sys_llseek(fd, offset_high, offset_low, result, origin); } @@ -145,20 +144,20 @@ SYSCALL_DEFINE5(32_llseek, unsigned long, fd, unsigned long, offset_high, lseek back to original location. They fail just like lseek does on non-seekable files. */ -SYSCALL_DEFINE6(32_pread, unsigned long, fd, char __user *, buf, size_t, count, - unsigned long, unused, unsigned long, a4, unsigned long, a5) +asmlinkage ssize_t sys32_pread(unsigned int fd, char __user * buf, + size_t count, u32 unused, u64 a4, u64 a5) { return sys_pread64(fd, buf, count, merge_64(a4, a5)); } -SYSCALL_DEFINE6(32_pwrite, unsigned int, fd, const char __user *, buf, - size_t, count, u32, unused, u64, a4, u64, a5) +asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char __user * buf, + size_t count, u32 unused, u64 a4, u64 a5) { return sys_pwrite64(fd, buf, count, merge_64(a4, a5)); } -SYSCALL_DEFINE2(32_sched_rr_get_interval, compat_pid_t, pid, - struct compat_timespec __user *, interval) +asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, + struct compat_timespec __user *interval) { struct timespec t; int ret; @@ -175,8 +174,8 @@ SYSCALL_DEFINE2(32_sched_rr_get_interval, compat_pid_t, pid, #ifdef CONFIG_SYSVIPC -SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third, - unsigned long, ptr, unsigned long, fifth) +asmlinkage long +sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth) { int version, err; @@ -234,8 +233,8 @@ SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third, #else -SYSCALL_DEFINE6(32_ipc, u32, call, int, first, int, second, int, third, - u32, ptr, u32 fifth) +asmlinkage long +sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth) { return -ENOSYS; } @@ -243,7 +242,7 @@ SYSCALL_DEFINE6(32_ipc, u32, call, int, first, int, second, int, third, #endif /* CONFIG_SYSVIPC */ #ifdef CONFIG_MIPS32_N32 -SYSCALL_DEFINE4(n32_semctl, int, semid, int, semnum, int, cmd, u32, arg) +asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg) { /* compat_sys_semctl expects a pointer to union semun */ u32 __user *uptr = compat_alloc_user_space(sizeof(u32)); @@ -252,14 +251,13 @@ SYSCALL_DEFINE4(n32_semctl, int, semid, int, semnum, int, cmd, u32, arg) return compat_sys_semctl(semid, semnum, cmd, uptr); } -SYSCALL_DEFINE4(n32_msgsnd, int, msqid, u32, msgp, unsigned int, msgsz, - int, msgflg) +asmlinkage long sysn32_msgsnd(int msqid, u32 msgp, unsigned msgsz, int msgflg) { return compat_sys_msgsnd(msqid, msgsz, msgflg, compat_ptr(msgp)); } -SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz, - int, msgtyp, int, msgflg) +asmlinkage long sysn32_msgrcv(int msqid, u32 msgp, size_t msgsz, int msgtyp, + int msgflg) { return compat_sys_msgrcv(msqid, msgsz, msgtyp, msgflg, IPC_64, compat_ptr(msgp)); @@ -279,7 +277,7 @@ struct sysctl_args32 #ifdef CONFIG_SYSCTL_SYSCALL -SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args) +asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args) { struct sysctl_args32 tmp; int error; @@ -318,16 +316,9 @@ SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args) return error; } -#else - -SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args) -{ - return -ENOSYS; -} - #endif /* CONFIG_SYSCTL_SYSCALL */ -SYSCALL_DEFINE1(32_newuname, struct new_utsname __user *, name) +asmlinkage long sys32_newuname(struct new_utsname __user * name) { int ret = 0; @@ -343,7 +334,7 @@ SYSCALL_DEFINE1(32_newuname, struct new_utsname __user *, name) return ret; } -SYSCALL_DEFINE1(32_personality, unsigned long, personality) +asmlinkage int sys32_personality(unsigned long personality) { int ret; personality &= 0xffffffff; @@ -366,7 +357,7 @@ struct ustat32 { extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf); -SYSCALL_DEFINE2(32_ustat, dev_t, dev, struct ustat32 __user *, ubuf32) +asmlinkage int sys32_ustat(dev_t dev, struct ustat32 __user * ubuf32) { int err; struct ustat tmp; @@ -390,8 +381,8 @@ SYSCALL_DEFINE2(32_ustat, dev_t, dev, struct ustat32 __user *, ubuf32) return err; } -SYSCALL_DEFINE4(32_sendfile, long, out_fd, long, in_fd, - compat_off_t __user *, offset, s32, count) +asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, + s32 count) { mm_segment_t old_fs = get_fs(); int ret; diff --git a/trunk/arch/mips/kernel/scall32-o32.S b/trunk/arch/mips/kernel/scall32-o32.S index 9ab70c3b5be6..51d1ba415b90 100644 --- a/trunk/arch/mips/kernel/scall32-o32.S +++ b/trunk/arch/mips/kernel/scall32-o32.S @@ -399,7 +399,7 @@ einval: li v0, -ENOSYS sys sys_swapon 2 sys sys_reboot 3 sys sys_old_readdir 3 - sys sys_mips_mmap 6 /* 4090 */ + sys old_mmap 6 /* 4090 */ sys sys_munmap 2 sys sys_truncate 2 sys sys_ftruncate 2 @@ -519,7 +519,7 @@ einval: li v0, -ENOSYS sys sys_sendfile 4 sys sys_ni_syscall 0 sys sys_ni_syscall 0 - sys sys_mips_mmap2 6 /* 4210 */ + sys sys_mmap2 6 /* 4210 */ sys sys_truncate64 4 sys sys_ftruncate64 4 sys sys_stat64 2 diff --git a/trunk/arch/mips/kernel/scall64-64.S b/trunk/arch/mips/kernel/scall64-64.S index 9b4698667154..a9e171618994 100644 --- a/trunk/arch/mips/kernel/scall64-64.S +++ b/trunk/arch/mips/kernel/scall64-64.S @@ -207,7 +207,7 @@ sys_call_table: PTR sys_newlstat PTR sys_poll PTR sys_lseek - PTR sys_mips_mmap + PTR old_mmap PTR sys_mprotect /* 5010 */ PTR sys_munmap PTR sys_brk diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index 7438e92f8a01..30f3b6317a83 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -129,12 +129,12 @@ EXPORT(sysn32_call_table) PTR sys_newlstat PTR sys_poll PTR sys_lseek - PTR sys_mips_mmap + PTR old_mmap PTR sys_mprotect /* 6010 */ PTR sys_munmap PTR sys_brk - PTR sys_32_rt_sigaction - PTR sys_32_rt_sigprocmask + PTR sys32_rt_sigaction + PTR sys32_rt_sigprocmask PTR compat_sys_ioctl /* 6015 */ PTR sys_pread64 PTR sys_pwrite64 @@ -159,7 +159,7 @@ EXPORT(sysn32_call_table) PTR compat_sys_setitimer PTR sys_alarm PTR sys_getpid - PTR sys_32_sendfile + PTR sys32_sendfile PTR sys_socket /* 6040 */ PTR sys_connect PTR sys_accept @@ -181,14 +181,14 @@ EXPORT(sysn32_call_table) PTR sys_exit PTR compat_sys_wait4 PTR sys_kill /* 6060 */ - PTR sys_32_newuname + PTR sys32_newuname PTR sys_semget PTR sys_semop - PTR sys_n32_semctl + PTR sysn32_semctl PTR sys_shmdt /* 6065 */ PTR sys_msgget - PTR sys_n32_msgsnd - PTR sys_n32_msgrcv + PTR sysn32_msgsnd + PTR sysn32_msgrcv PTR compat_sys_msgctl PTR compat_sys_fcntl /* 6070 */ PTR sys_flock @@ -245,15 +245,15 @@ EXPORT(sysn32_call_table) PTR sys_getsid PTR sys_capget PTR sys_capset - PTR sys_32_rt_sigpending /* 6125 */ + PTR sys32_rt_sigpending /* 6125 */ PTR compat_sys_rt_sigtimedwait - PTR sys_32_rt_sigqueueinfo + PTR sys32_rt_sigqueueinfo PTR sysn32_rt_sigsuspend PTR sys32_sigaltstack PTR compat_sys_utime /* 6130 */ PTR sys_mknod - PTR sys_32_personality - PTR sys_32_ustat + PTR sys32_personality + PTR sys32_ustat PTR compat_sys_statfs PTR compat_sys_fstatfs /* 6135 */ PTR sys_sysfs @@ -265,14 +265,14 @@ EXPORT(sysn32_call_table) PTR sys_sched_getscheduler PTR sys_sched_get_priority_max PTR sys_sched_get_priority_min - PTR sys_32_sched_rr_get_interval /* 6145 */ + PTR sys32_sched_rr_get_interval /* 6145 */ PTR sys_mlock PTR sys_munlock PTR sys_mlockall PTR sys_munlockall PTR sys_vhangup /* 6150 */ PTR sys_pivot_root - PTR sys_32_sysctl + PTR sys32_sysctl PTR sys_prctl PTR compat_sys_adjtimex PTR compat_sys_setrlimit /* 6155 */ diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index b0fef4ff9827..fefef4af8595 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -265,12 +265,12 @@ sys_call_table: PTR sys_olduname PTR sys_umask /* 4060 */ PTR sys_chroot - PTR sys_32_ustat + PTR sys32_ustat PTR sys_dup2 PTR sys_getppid PTR sys_getpgrp /* 4065 */ PTR sys_setsid - PTR sys_32_sigaction + PTR sys32_sigaction PTR sys_sgetmask PTR sys_ssetmask PTR sys_setreuid /* 4070 */ @@ -293,7 +293,7 @@ sys_call_table: PTR sys_swapon PTR sys_reboot PTR compat_sys_old_readdir - PTR sys_mips_mmap /* 4090 */ + PTR old_mmap /* 4090 */ PTR sys_munmap PTR sys_truncate PTR sys_ftruncate @@ -320,12 +320,12 @@ sys_call_table: PTR compat_sys_wait4 PTR sys_swapoff /* 4115 */ PTR compat_sys_sysinfo - PTR sys_32_ipc + PTR sys32_ipc PTR sys_fsync PTR sys32_sigreturn PTR sys32_clone /* 4120 */ PTR sys_setdomainname - PTR sys_32_newuname + PTR sys32_newuname PTR sys_ni_syscall /* sys_modify_ldt */ PTR compat_sys_adjtimex PTR sys_mprotect /* 4125 */ @@ -339,11 +339,11 @@ sys_call_table: PTR sys_fchdir PTR sys_bdflush PTR sys_sysfs /* 4135 */ - PTR sys_32_personality + PTR sys32_personality PTR sys_ni_syscall /* for afs_syscall */ PTR sys_setfsuid PTR sys_setfsgid - PTR sys_32_llseek /* 4140 */ + PTR sys32_llseek /* 4140 */ PTR compat_sys_getdents PTR compat_sys_select PTR sys_flock @@ -356,7 +356,7 @@ sys_call_table: PTR sys_ni_syscall /* 4150 */ PTR sys_getsid PTR sys_fdatasync - PTR sys_32_sysctl + PTR sys32_sysctl PTR sys_mlock PTR sys_munlock /* 4155 */ PTR sys_mlockall @@ -368,7 +368,7 @@ sys_call_table: PTR sys_sched_yield PTR sys_sched_get_priority_max PTR sys_sched_get_priority_min - PTR sys_32_sched_rr_get_interval /* 4165 */ + PTR sys32_sched_rr_get_interval /* 4165 */ PTR compat_sys_nanosleep PTR sys_mremap PTR sys_accept @@ -397,25 +397,25 @@ sys_call_table: PTR sys_getresgid PTR sys_prctl PTR sys32_rt_sigreturn - PTR sys_32_rt_sigaction - PTR sys_32_rt_sigprocmask /* 4195 */ - PTR sys_32_rt_sigpending + PTR sys32_rt_sigaction + PTR sys32_rt_sigprocmask /* 4195 */ + PTR sys32_rt_sigpending PTR compat_sys_rt_sigtimedwait - PTR sys_32_rt_sigqueueinfo + PTR sys32_rt_sigqueueinfo PTR sys32_rt_sigsuspend - PTR sys_32_pread /* 4200 */ - PTR sys_32_pwrite + PTR sys32_pread /* 4200 */ + PTR sys32_pwrite PTR sys_chown PTR sys_getcwd PTR sys_capget PTR sys_capset /* 4205 */ PTR sys32_sigaltstack - PTR sys_32_sendfile + PTR sys32_sendfile PTR sys_ni_syscall PTR sys_ni_syscall - PTR sys_mips_mmap2 /* 4210 */ - PTR sys_32_truncate64 - PTR sys_32_ftruncate64 + PTR sys32_mmap2 /* 4210 */ + PTR sys32_truncate64 + PTR sys32_ftruncate64 PTR sys_newstat PTR sys_newlstat PTR sys_newfstat /* 4215 */ @@ -481,7 +481,7 @@ sys_call_table: PTR compat_sys_mq_notify /* 4275 */ PTR compat_sys_mq_getsetattr PTR sys_ni_syscall /* sys_vserver */ - PTR sys_32_waitid + PTR sys32_waitid PTR sys_ni_syscall /* available, was setaltroot */ PTR sys_add_key /* 4280 */ PTR sys_request_key diff --git a/trunk/arch/mips/kernel/signal.c b/trunk/arch/mips/kernel/signal.c index 830c5ef9932b..a4e106c56ab5 100644 --- a/trunk/arch/mips/kernel/signal.c +++ b/trunk/arch/mips/kernel/signal.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -339,8 +338,8 @@ asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) } #ifdef CONFIG_TRAD_SIGNALS -SYSCALL_DEFINE3(sigaction, int, sig, const struct sigaction __user *, act, - struct sigaction __user *, oact) +asmlinkage int sys_sigaction(int sig, const struct sigaction __user *act, + struct sigaction __user *oact) { struct k_sigaction new_ka, old_ka; int ret; diff --git a/trunk/arch/mips/kernel/signal32.c b/trunk/arch/mips/kernel/signal32.c index 2e74075ac0ca..652709b353ad 100644 --- a/trunk/arch/mips/kernel/signal32.c +++ b/trunk/arch/mips/kernel/signal32.c @@ -349,8 +349,8 @@ asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) return -ERESTARTNOHAND; } -SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act, - struct sigaction32 __user *, oact) +asmlinkage int sys32_sigaction(int sig, const struct sigaction32 __user *act, + struct sigaction32 __user *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -704,9 +704,9 @@ struct mips_abi mips_abi_32 = { .restart = __NR_O32_restart_syscall }; -SYSCALL_DEFINE4(32_rt_sigaction, int, sig, - const struct sigaction32 __user *, act, - struct sigaction32 __user *, oact, unsigned int, sigsetsize) +asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, + struct sigaction32 __user *oact, + unsigned int sigsetsize) { struct k_sigaction new_sa, old_sa; int ret = -EINVAL; @@ -748,8 +748,8 @@ SYSCALL_DEFINE4(32_rt_sigaction, int, sig, return ret; } -SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set, - compat_sigset_t __user *, oset, unsigned int, sigsetsize) +asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, + compat_sigset_t __user *oset, unsigned int sigsetsize) { sigset_t old_set, new_set; int ret; @@ -770,8 +770,8 @@ SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set, return ret; } -SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset, - unsigned int, sigsetsize) +asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *uset, + unsigned int sigsetsize) { int ret; sigset_t set; @@ -787,8 +787,7 @@ SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset, return ret; } -SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig, - compat_siginfo_t __user *, uinfo) +asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) { siginfo_t info; int ret; @@ -803,9 +802,10 @@ SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig, return ret; } -SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid, - compat_siginfo_t __user *, uinfo, int, options, - struct compat_rusage __user *, uru) +asmlinkage long +sys32_waitid(int which, compat_pid_t pid, + compat_siginfo_t __user *uinfo, int options, + struct compat_rusage __user *uru) { siginfo_t info; struct rusage ru; diff --git a/trunk/arch/mips/kernel/syscall.c b/trunk/arch/mips/kernel/syscall.c index 8cf384644040..37970d9b2186 100644 --- a/trunk/arch/mips/kernel/syscall.c +++ b/trunk/arch/mips/kernel/syscall.c @@ -152,9 +152,9 @@ do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, return error; } -SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, - unsigned long, prot, unsigned long, flags, unsigned long, - fd, off_t, offset) +asmlinkage unsigned long +old_mmap(unsigned long addr, unsigned long len, int prot, + int flags, int fd, off_t offset) { unsigned long result; @@ -168,9 +168,9 @@ SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, return result; } -SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len, - unsigned long, prot, unsigned long, flags, unsigned long, fd, - unsigned long, pgoff) +asmlinkage unsigned long +sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, + unsigned long flags, unsigned long fd, unsigned long pgoff) { if (pgoff & (~PAGE_MASK >> 12)) return -EINVAL; @@ -240,7 +240,7 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) /* * Compacrapability ... */ -SYSCALL_DEFINE1(uname, struct old_utsname __user *, name) +asmlinkage int sys_uname(struct old_utsname __user * name) { if (name && !copy_to_user(name, utsname(), sizeof (*name))) return 0; @@ -250,7 +250,7 @@ SYSCALL_DEFINE1(uname, struct old_utsname __user *, name) /* * Compacrapability ... */ -SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) +asmlinkage int sys_olduname(struct oldold_utsname __user * name) { int error; @@ -279,7 +279,7 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) return error; } -SYSCALL_DEFINE1(set_thread_area, unsigned long, addr) +asmlinkage int sys_set_thread_area(unsigned long addr) { struct thread_info *ti = task_thread_info(current); @@ -290,7 +290,7 @@ SYSCALL_DEFINE1(set_thread_area, unsigned long, addr) return 0; } -asmlinkage int _sys_sysmips(long cmd, long arg1, long arg2, long arg3) +asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) { switch (cmd) { case MIPS_ATOMIC_SET: @@ -325,8 +325,8 @@ asmlinkage int _sys_sysmips(long cmd, long arg1, long arg2, long arg3) * * This is really horribly ugly. */ -SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second, - unsigned long, third, void __user *, ptr, long, fifth) +asmlinkage int sys_ipc(unsigned int call, int first, int second, + unsigned long third, void __user *ptr, long fifth) { int version, ret; @@ -411,7 +411,7 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second, /* * No implemented yet ... */ -SYSCALL_DEFINE3(cachectl, char *, addr, int, nbytes, int, op) +asmlinkage int sys_cachectl(char *addr, int nbytes, int op) { return -ENOSYS; } diff --git a/trunk/arch/mips/mm/cache.c b/trunk/arch/mips/mm/cache.c index 694d51f523d1..98ad0a82c29e 100644 --- a/trunk/arch/mips/mm/cache.c +++ b/trunk/arch/mips/mm/cache.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -59,8 +58,8 @@ EXPORT_SYMBOL(_dma_cache_wback_inv); * We could optimize the case where the cache argument is not BCACHE but * that seems very atypical use ... */ -SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes, - unsigned int, cache) +asmlinkage int sys_cacheflush(unsigned long addr, + unsigned long bytes, unsigned int cache) { if (bytes == 0) return 0; diff --git a/trunk/arch/mn10300/Kconfig b/trunk/arch/mn10300/Kconfig index 41d16822e616..9a9f43358879 100644 --- a/trunk/arch/mn10300/Kconfig +++ b/trunk/arch/mn10300/Kconfig @@ -7,7 +7,6 @@ mainmenu "Linux Kernel Configuration" config MN10300 def_bool y - select HAVE_OPROFILE config AM33 def_bool y diff --git a/trunk/arch/mn10300/unit-asb2305/pci.c b/trunk/arch/mn10300/unit-asb2305/pci.c index 07dbbcda3b2e..1a86425fec42 100644 --- a/trunk/arch/mn10300/unit-asb2305/pci.c +++ b/trunk/arch/mn10300/unit-asb2305/pci.c @@ -173,7 +173,7 @@ static int pci_ampci_write_config_byte(struct pci_bus *bus, unsigned int devfn, BRIDGEREGB(where) = value; } else { if (bus->number == 0 && - (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(3, 0)) + (devfn == PCI_DEVFN(2, 0) && devfn == PCI_DEVFN(3, 0)) ) __pcidebug("<= %02x", bus, devfn, where, value); CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where); diff --git a/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts b/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts index 3ebf7ec0484c..909a89cab9ac 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts @@ -191,8 +191,7 @@ interrupts = <37 0x8 36 0x8 35 0x8>; interrupt-parent = <&ipic>; tbi-handle = < &tbi0 >; - /* Vitesse 7385 isn't on the MDIO bus */ - fixed-link = <1 1 1000 0 0>; + phy-handle = < &phy1 >; fsl,magic-packet; mdio@24520 { @@ -200,6 +199,12 @@ #size-cells = <0>; compatible = "fsl,gianfar-mdio"; reg = <0x24520 0x20>; + phy1: ethernet-phy@1 { + interrupt-parent = <&ipic>; + interrupts = <19 0x8>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; phy4: ethernet-phy@4 { interrupt-parent = <&ipic>; interrupts = <20 0x8>; @@ -214,8 +219,6 @@ }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; diff --git a/trunk/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig b/trunk/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig index 409d017621a8..9e47ae957e2e 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig @@ -651,7 +651,7 @@ CONFIG_CICADA_PHY=y # CONFIG_NATIONAL_PHY is not set # CONFIG_STE10XP is not set # CONFIG_LSI_ET1011C_PHY is not set -CONFIG_FIXED_PHY=y +# CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y diff --git a/trunk/arch/powerpc/include/asm/compat.h b/trunk/arch/powerpc/include/asm/compat.h index 4774c2f92232..d811a8cd7b58 100644 --- a/trunk/arch/powerpc/include/asm/compat.h +++ b/trunk/arch/powerpc/include/asm/compat.h @@ -210,10 +210,5 @@ struct compat_shmid64_ds { compat_ulong_t __unused6; }; -static inline int is_compat_task(void) -{ - return test_thread_flag(TIF_32BIT); -} - #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_COMPAT_H */ diff --git a/trunk/arch/powerpc/include/asm/pgtable-4k.h b/trunk/arch/powerpc/include/asm/pgtable-4k.h index 1dbca4e7de67..6b18ba9d2d85 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-4k.h +++ b/trunk/arch/powerpc/include/asm/pgtable-4k.h @@ -60,7 +60,7 @@ /* It should be preserving the high 48 bits and then specifically */ /* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */ #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \ - _PAGE_HPTEFLAGS | _PAGE_SPECIAL) + _PAGE_HPTEFLAGS) /* Bits to mask out from a PMD to get to the PTE page */ #define PMD_MASKED_BITS 0 diff --git a/trunk/arch/powerpc/include/asm/pgtable-64k.h b/trunk/arch/powerpc/include/asm/pgtable-64k.h index 7389003349a6..07b0d8f09cb6 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-64k.h +++ b/trunk/arch/powerpc/include/asm/pgtable-64k.h @@ -114,7 +114,7 @@ static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd) * pgprot changes */ #define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_SPECIAL) + _PAGE_ACCESSED) /* Bits to mask out from a PMD to get to the PTE page */ #define PMD_MASKED_BITS 0x1ff diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc32.h b/trunk/arch/powerpc/include/asm/pgtable-ppc32.h index 820b5f0a35ce..f69a4d977729 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/trunk/arch/powerpc/include/asm/pgtable-ppc32.h @@ -429,8 +429,7 @@ extern int icache_44x_need_flush; #define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE() #endif -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \ - _PAGE_SPECIAL) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) #define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ diff --git a/trunk/arch/powerpc/include/asm/seccomp.h b/trunk/arch/powerpc/include/asm/seccomp.h index 00c1d9133cfe..853765eb1f65 100644 --- a/trunk/arch/powerpc/include/asm/seccomp.h +++ b/trunk/arch/powerpc/include/asm/seccomp.h @@ -1,6 +1,10 @@ #ifndef _ASM_POWERPC_SECCOMP_H #define _ASM_POWERPC_SECCOMP_H +#ifdef __KERNEL__ +#include +#endif + #include #define __NR_seccomp_read __NR_read diff --git a/trunk/arch/powerpc/kernel/align.c b/trunk/arch/powerpc/kernel/align.c index 73cb6a3229ae..5af4e9b2dbe2 100644 --- a/trunk/arch/powerpc/kernel/align.c +++ b/trunk/arch/powerpc/kernel/align.c @@ -367,24 +367,27 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, unsigned int flags) { - char *ptr0 = (char *) ¤t->thread.TS_FPR(reg); - char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); - int i, ret, sw = 0; + char *ptr = (char *) ¤t->thread.TS_FPR(reg); + int i, ret; if (!(flags & F)) return 0; if (reg & 1) return 0; /* invalid form: FRS/FRT must be even */ - if (flags & SW) - sw = 7; - ret = 0; - for (i = 0; i < 8; ++i) { - if (!(flags & ST)) { - ret |= __get_user(ptr0[i^sw], addr + i); - ret |= __get_user(ptr1[i^sw], addr + i + 8); - } else { - ret |= __put_user(ptr0[i^sw], addr + i); - ret |= __put_user(ptr1[i^sw], addr + i + 8); + if (!(flags & SW)) { + /* not byte-swapped - easy */ + if (!(flags & ST)) + ret = __copy_from_user(ptr, addr, 16); + else + ret = __copy_to_user(addr, ptr, 16); + } else { + /* each FPR value is byte-swapped separately */ + ret = 0; + for (i = 0; i < 16; ++i) { + if (!(flags & ST)) + ret |= __get_user(ptr[i^7], addr + i); + else + ret |= __put_user(ptr[i^7], addr + i); } } if (ret) @@ -643,16 +646,11 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, unsigned int areg, struct pt_regs *regs, unsigned int flags, unsigned int length) { - char *ptr; + char *ptr = (char *) ¤t->thread.TS_FPR(reg); int ret = 0; flush_vsx_to_thread(current); - if (reg < 32) - ptr = (char *) ¤t->thread.TS_FPR(reg); - else - ptr = (char *) ¤t->thread.vr[reg - 32]; - if (flags & ST) ret = __copy_to_user(addr, ptr, length); else { diff --git a/trunk/arch/powerpc/kernel/ftrace.c b/trunk/arch/powerpc/kernel/ftrace.c index 60c60ccf5e3c..5355244c99ff 100644 --- a/trunk/arch/powerpc/kernel/ftrace.c +++ b/trunk/arch/powerpc/kernel/ftrace.c @@ -195,9 +195,8 @@ __ftrace_make_nop(struct module *mod, return -EINVAL; } - /* The bottom half is signed extended */ - offset = ((unsigned)((unsigned short)jmp[0]) << 16) + - (int)((short)jmp[1]); + offset = (unsigned)((unsigned short)jmp[0]) << 16 | + (unsigned)((unsigned short)jmp[1]); DEBUGP(" %x ", offset); diff --git a/trunk/arch/powerpc/kernel/pci-common.c b/trunk/arch/powerpc/kernel/pci-common.c index 0f4181272311..19b12d2cbb4b 100644 --- a/trunk/arch/powerpc/kernel/pci-common.c +++ b/trunk/arch/powerpc/kernel/pci-common.c @@ -561,21 +561,8 @@ int pci_mmap_legacy_page_range(struct pci_bus *bus, (unsigned long long)(offset + size - 1)); if (mmap_state == pci_mmap_mem) { - /* Hack alert ! - * - * Because X is lame and can fail starting if it gets an error trying - * to mmap legacy_mem (instead of just moving on without legacy memory - * access) we fake it here by giving it anonymous memory, effectively - * behaving just like /dev/zero - */ - if ((offset + size) > hose->isa_mem_size) { - printk(KERN_DEBUG - "Process %s (pid:%d) mapped non-existing PCI legacy memory for 0%04x:%02x\n", - current->comm, current->pid, pci_domain_nr(bus), bus->number); - if (vma->vm_flags & VM_SHARED) - return shmem_zero_setup(vma); - return 0; - } + if ((offset + size) > hose->isa_mem_size) + return -ENXIO; offset += hose->isa_mem_phys; } else { unsigned long io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; diff --git a/trunk/arch/powerpc/kvm/powerpc.c b/trunk/arch/powerpc/kvm/powerpc.c index 5f81256287f5..2822c8ccfaaf 100644 --- a/trunk/arch/powerpc/kvm/powerpc.c +++ b/trunk/arch/powerpc/kvm/powerpc.c @@ -125,10 +125,6 @@ static void kvmppc_free_vcpus(struct kvm *kvm) } } -void kvm_arch_sync_events(struct kvm *kvm) -{ -} - void kvm_arch_destroy_vm(struct kvm *kvm) { kvmppc_free_vcpus(kvm); diff --git a/trunk/arch/powerpc/lib/copyuser_64.S b/trunk/arch/powerpc/lib/copyuser_64.S index 693b14a778fa..70693a5c12a1 100644 --- a/trunk/arch/powerpc/lib/copyuser_64.S +++ b/trunk/arch/powerpc/lib/copyuser_64.S @@ -62,19 +62,18 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 72: std r8,8(r3) beq+ 3f addi r3,r3,16 +23: ld r9,8(r4) .Ldo_tail: bf cr7*4+1,1f -23: lwz r9,8(r4) - addi r4,r4,4 + rotldi r9,r9,32 73: stw r9,0(r3) addi r3,r3,4 1: bf cr7*4+2,2f -44: lhz r9,8(r4) - addi r4,r4,2 + rotldi r9,r9,16 74: sth r9,0(r3) addi r3,r3,2 2: bf cr7*4+3,3f -45: lbz r9,8(r4) + rotldi r9,r9,8 75: stb r9,0(r3) 3: li r3,0 blr @@ -142,24 +141,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 6: cmpwi cr1,r5,8 addi r3,r3,32 sld r9,r9,r10 - ble cr1,7f + ble cr1,.Ldo_tail 34: ld r0,8(r4) srd r7,r0,r11 or r9,r7,r9 -7: - bf cr7*4+1,1f - rotldi r9,r9,32 -94: stw r9,0(r3) - addi r3,r3,4 -1: bf cr7*4+2,2f - rotldi r9,r9,16 -95: sth r9,0(r3) - addi r3,r3,2 -2: bf cr7*4+3,3f - rotldi r9,r9,8 -96: stb r9,0(r3) -3: li r3,0 - blr + b .Ldo_tail .Ldst_unaligned: PPC_MTOCRF 0x01,r6 /* put #bytes to 8B bdry into cr7 */ @@ -232,6 +218,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 121: 132: addi r3,r3,8 +123: 134: 135: 138: @@ -239,9 +226,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 140: 141: 142: -123: -144: -145: /* * here we have had a fault on a load and r3 points to the first @@ -325,9 +309,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 187: 188: 189: -194: -195: -196: 1: ld r6,-24(r1) ld r5,-8(r1) @@ -348,9 +329,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) .llong 72b,172b .llong 23b,123b .llong 73b,173b - .llong 44b,144b .llong 74b,174b - .llong 45b,145b .llong 75b,175b .llong 24b,124b .llong 25b,125b @@ -368,9 +347,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) .llong 79b,179b .llong 80b,180b .llong 34b,134b - .llong 94b,194b - .llong 95b,195b - .llong 96b,196b .llong 35b,135b .llong 81b,181b .llong 36b,136b diff --git a/trunk/arch/powerpc/lib/memcpy_64.S b/trunk/arch/powerpc/lib/memcpy_64.S index e178922b2c21..fe2d34e5332d 100644 --- a/trunk/arch/powerpc/lib/memcpy_64.S +++ b/trunk/arch/powerpc/lib/memcpy_64.S @@ -53,19 +53,18 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 3: std r8,8(r3) beq 3f addi r3,r3,16 + ld r9,8(r4) .Ldo_tail: bf cr7*4+1,1f - lwz r9,8(r4) - addi r4,r4,4 + rotldi r9,r9,32 stw r9,0(r3) addi r3,r3,4 1: bf cr7*4+2,2f - lhz r9,8(r4) - addi r4,r4,2 + rotldi r9,r9,16 sth r9,0(r3) addi r3,r3,2 2: bf cr7*4+3,3f - lbz r9,8(r4) + rotldi r9,r9,8 stb r9,0(r3) 3: ld r3,48(r1) /* return dest pointer */ blr @@ -134,24 +133,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) cmpwi cr1,r5,8 addi r3,r3,32 sld r9,r9,r10 - ble cr1,6f + ble cr1,.Ldo_tail ld r0,8(r4) srd r7,r0,r11 or r9,r7,r9 -6: - bf cr7*4+1,1f - rotldi r9,r9,32 - stw r9,0(r3) - addi r3,r3,4 -1: bf cr7*4+2,2f - rotldi r9,r9,16 - sth r9,0(r3) - addi r3,r3,2 -2: bf cr7*4+3,3f - rotldi r9,r9,8 - stb r9,0(r3) -3: ld r3,48(r1) /* return dest pointer */ - blr + b .Ldo_tail .Ldst_unaligned: PPC_MTOCRF 0x01,r6 # put #bytes to 8B bdry into cr7 diff --git a/trunk/arch/powerpc/lib/sstep.c b/trunk/arch/powerpc/lib/sstep.c index 13b7d54f185b..4aae0c387645 100644 --- a/trunk/arch/powerpc/lib/sstep.c +++ b/trunk/arch/powerpc/lib/sstep.c @@ -172,8 +172,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) } break; case 0x378: /* orx */ - if (instr & 1) - break; rs = (instr >> 21) & 0x1f; rb = (instr >> 11) & 0x1f; if (rs == rb) { /* mr */ diff --git a/trunk/arch/powerpc/mm/fsl_booke_mmu.c b/trunk/arch/powerpc/mm/fsl_booke_mmu.c index ea6e41e39d9f..1971e4ee3d6e 100644 --- a/trunk/arch/powerpc/mm/fsl_booke_mmu.c +++ b/trunk/arch/powerpc/mm/fsl_booke_mmu.c @@ -73,7 +73,7 @@ extern unsigned int tlbcam_index; /* * Return PA for this VA if it is mapped by a CAM, or 0 */ -phys_addr_t v_mapped_by_tlbcam(unsigned long va) +unsigned long v_mapped_by_tlbcam(unsigned long va) { int b; for (b = 0; b < tlbcam_index; ++b) @@ -85,7 +85,7 @@ phys_addr_t v_mapped_by_tlbcam(unsigned long va) /* * Return VA for a given PA or 0 if not mapped */ -unsigned long p_mapped_by_tlbcam(phys_addr_t pa) +unsigned long p_mapped_by_tlbcam(unsigned long pa) { int b; for (b = 0; b < tlbcam_index; ++b) diff --git a/trunk/arch/powerpc/mm/hash_low_32.S b/trunk/arch/powerpc/mm/hash_low_32.S index 14af8cedab70..67850ec9feb3 100644 --- a/trunk/arch/powerpc/mm/hash_low_32.S +++ b/trunk/arch/powerpc/mm/hash_low_32.S @@ -320,7 +320,7 @@ _GLOBAL(create_hpte) and r8,r8,r0 /* writable if _RW & _DIRTY */ rlwimi r5,r5,32-1,30,30 /* _PAGE_USER -> PP msb */ rlwimi r5,r5,32-2,31,31 /* _PAGE_USER -> PP lsb */ - ori r8,r8,0xe04 /* clear out reserved bits */ + ori r8,r8,0xe14 /* clear out reserved bits and M */ andc r8,r5,r8 /* PP = user? (rw&dirty? 2: 3): 0 */ BEGIN_FTR_SECTION rlwinm r8,r8,0,~_PAGE_COHERENT /* clear M (coherence not required) */ diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index 5ac08b8ab654..7393bd76d698 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -883,7 +882,7 @@ static void mark_reserved_regions_for_nid(int nid) unsigned long physbase = lmb.reserved.region[i].base; unsigned long size = lmb.reserved.region[i].size; unsigned long start_pfn = physbase >> PAGE_SHIFT; - unsigned long end_pfn = PFN_UP(physbase + size); + unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT); struct node_active_region node_ar; unsigned long node_end_pfn = node->node_start_pfn + node->node_spanned_pages; @@ -909,7 +908,7 @@ static void mark_reserved_regions_for_nid(int nid) */ if (end_pfn > node_ar.end_pfn) reserve_size = (node_ar.end_pfn << PAGE_SHIFT) - - physbase; + - (start_pfn << PAGE_SHIFT); /* * Only worry about *this* node, others may not * yet have valid NODE_DATA(). diff --git a/trunk/arch/powerpc/mm/pgtable_32.c b/trunk/arch/powerpc/mm/pgtable_32.c index 58bcaeba728d..22972cd83cc9 100644 --- a/trunk/arch/powerpc/mm/pgtable_32.c +++ b/trunk/arch/powerpc/mm/pgtable_32.c @@ -61,8 +61,8 @@ void setbat(int index, unsigned long virt, phys_addr_t phys, #ifdef HAVE_TLBCAM extern unsigned int tlbcam_index; -extern phys_addr_t v_mapped_by_tlbcam(unsigned long va); -extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa); +extern unsigned long v_mapped_by_tlbcam(unsigned long va); +extern unsigned long p_mapped_by_tlbcam(unsigned long pa); #else /* !HAVE_TLBCAM */ #define v_mapped_by_tlbcam(x) (0UL) #define p_mapped_by_tlbcam(x) (0UL) diff --git a/trunk/arch/powerpc/oprofile/cell/spu_profiler.c b/trunk/arch/powerpc/oprofile/cell/spu_profiler.c index b129d007e7fe..9305ddaac512 100644 --- a/trunk/arch/powerpc/oprofile/cell/spu_profiler.c +++ b/trunk/arch/powerpc/oprofile/cell/spu_profiler.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "pr_util.h" #define SCALE_SHIFT 14 diff --git a/trunk/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/trunk/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c index ddf0bdc0fc8b..9876d7e072f4 100644 --- a/trunk/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +++ b/trunk/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c @@ -186,7 +186,7 @@ int __init pq2ads_pci_init_irq(void) iounmap(priv->regs); out_free_bootmem: free_bootmem((unsigned long)priv, - sizeof(struct pq2ads_pci_pic)); + sizeof(sizeof(struct pq2ads_pci_pic))); of_node_put(np); out_unmap_irq: irq_dispose_mapping(irq); diff --git a/trunk/arch/powerpc/platforms/ps3/mm.c b/trunk/arch/powerpc/platforms/ps3/mm.c index d281cc0bca71..67de6bf3db3d 100644 --- a/trunk/arch/powerpc/platforms/ps3/mm.c +++ b/trunk/arch/powerpc/platforms/ps3/mm.c @@ -328,7 +328,7 @@ static int __init ps3_mm_add_memory(void) return result; } -device_initcall(ps3_mm_add_memory); +core_initcall(ps3_mm_add_memory); /*============================================================================*/ /* dma routines */ diff --git a/trunk/arch/powerpc/platforms/pseries/hotplug-memory.c b/trunk/arch/powerpc/platforms/pseries/hotplug-memory.c index 9b21ee68ea50..a623ad256e9e 100644 --- a/trunk/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/trunk/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -14,7 +14,6 @@ #include #include #include -#include static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size) { diff --git a/trunk/arch/powerpc/sysdev/cpm2_pic.c b/trunk/arch/powerpc/sysdev/cpm2_pic.c index 78f1f7cca0a0..b16ca3ed65d2 100644 --- a/trunk/arch/powerpc/sysdev/cpm2_pic.c +++ b/trunk/arch/powerpc/sysdev/cpm2_pic.c @@ -165,7 +165,7 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) edibit = (14 - (src - CPM2_IRQ_EXT1)); else if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) - edibit = (31 - (CPM2_IRQ_PORTC0 - src)); + edibit = (31 - (src - CPM2_IRQ_PORTC15)); else return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL; diff --git a/trunk/arch/powerpc/sysdev/ipic.c b/trunk/arch/powerpc/sysdev/ipic.c index 9a89cd3e80a2..88a983ece5c9 100644 --- a/trunk/arch/powerpc/sysdev/ipic.c +++ b/trunk/arch/powerpc/sysdev/ipic.c @@ -890,7 +890,7 @@ unsigned int ipic_get_irq(void) return irq_linear_revmap(primary_ipic->irqhost, irq); } -#ifdef CONFIG_SUSPEND +#ifdef CONFIG_PM static struct { u32 sicfr; u32 siprr[2]; diff --git a/trunk/arch/powerpc/sysdev/ppc4xx_pci.c b/trunk/arch/powerpc/sysdev/ppc4xx_pci.c index 5558d932b4d5..77fae5f64f2e 100644 --- a/trunk/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/trunk/arch/powerpc/sysdev/ppc4xx_pci.c @@ -204,23 +204,6 @@ static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose, { u32 ma, pcila, pciha; - /* Hack warning ! The "old" PCI 2.x cell only let us configure the low - * 32-bit of incoming PLB addresses. The top 4 bits of the 36-bit - * address are actually hard wired to a value that appears to depend - * on the specific SoC. For example, it's 0 on 440EP and 1 on 440EPx. - * - * The trick here is we just crop those top bits and ignore them when - * programming the chip. That means the device-tree has to be right - * for the specific part used (we don't print a warning if it's wrong - * but on the other hand, you'll crash quickly enough), but at least - * this code should work whatever the hard coded value is - */ - plb_addr &= 0xffffffffull; - - /* Note: Due to the above hack, the test below doesn't actually test - * if you address is above 4G, but it tests that address and - * (address + size) are both contained in the same 4G - */ if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || size < 0x1000 || (plb_addr & (size - 1)) != 0) { printk(KERN_WARNING "%s: Resource out of range\n", diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index 31e809c77790..a0e748da9909 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc4 -# Wed Feb 11 10:07:16 2009 +# Linux kernel version: 2.6.28-rc6 +# Thu Nov 27 11:00:49 2008 # CONFIG_SCHED_MC=y CONFIG_MMU=y @@ -14,14 +14,12 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_BUG=y CONFIG_NO_IOMEM=y CONFIG_NO_DMA=y CONFIG_GENERIC_LOCKBREAK=y CONFIG_PGSTE=y -CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_S390=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -41,29 +39,20 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_TASKSTATS is not set CONFIG_AUDIT=y # CONFIG_AUDITSYSCALL is not set - -# -# RCU Subsystem -# -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set CONFIG_CGROUP_NS=y # CONFIG_CGROUP_FREEZER is not set # CONFIG_CGROUP_DEVICE is not set # CONFIG_CPUSETS is not set +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set CONFIG_SYSFS_DEPRECATED=y @@ -74,7 +63,6 @@ CONFIG_UTS_NS=y CONFIG_IPC_NS=y # CONFIG_USER_NS is not set # CONFIG_PID_NS is not set -# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -103,17 +91,17 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set # CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y -CONFIG_HAVE_SYSCALL_WRAPPERS=y CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_USE_GENERIC_SMP_HELPERS=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -121,7 +109,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_INIT_ALL_POSSIBLE=y +CONFIG_KMOD=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set @@ -142,6 +130,7 @@ CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_CLASSIC_RCU=y # CONFIG_FREEZER is not set # @@ -172,7 +161,6 @@ CONFIG_S390_EXEC_PROTECT=y CONFIG_MARCH_Z900=y # CONFIG_MARCH_Z990 is not set # CONFIG_MARCH_Z9_109 is not set -# CONFIG_MARCH_Z10 is not set CONFIG_PACK_STACK=y # CONFIG_SMALL_STACK is not set CONFIG_CHECK_STACK=y @@ -186,6 +174,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y +# CONFIG_PREEMPT_RCU is not set CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y @@ -206,6 +195,7 @@ CONFIG_MEMORY_HOTREMOVE=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y +CONFIG_RESOURCES_64BIT=y CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y @@ -217,6 +207,7 @@ CONFIG_UNEVICTABLE_LRU=y # CONFIG_MACHCHK_WARNING=y CONFIG_QDIO=y +# CONFIG_QDIO_DEBUG is not set CONFIG_CHSC_SCH=m # @@ -236,13 +227,15 @@ CONFIG_PFAULT=y # CONFIG_SHARED_KERNEL is not set # CONFIG_CMM is not set # CONFIG_PAGE_STATES is not set +CONFIG_VIRT_TIMER=y +CONFIG_VIRT_CPU_ACCOUNTING=y # CONFIG_APPLDATA_BASE is not set CONFIG_HZ_100=y # CONFIG_HZ_250 is not set # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=100 -CONFIG_SCHED_HRTICK=y +# CONFIG_SCHED_HRTICK is not set CONFIG_S390_HYPFS_FS=y CONFIG_KEXEC=y # CONFIG_ZFCPDUMP is not set @@ -252,7 +245,6 @@ CONFIG_NET=y # # Networking options # -CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -391,7 +383,6 @@ CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m # CONFIG_NET_SCH_NETEM is not set -# CONFIG_NET_SCH_DRR is not set # CONFIG_NET_SCH_INGRESS is not set # @@ -409,7 +400,6 @@ CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_FLOW=m -# CONFIG_NET_CLS_CGROUP is not set # CONFIG_NET_EMATCH is not set CONFIG_NET_CLS_ACT=y CONFIG_NET_ACT_POLICE=y @@ -421,7 +411,6 @@ CONFIG_NET_ACT_NAT=m # CONFIG_NET_ACT_SKBEDIT is not set # CONFIG_NET_CLS_IND is not set CONFIG_NET_SCH_FIFO=y -# CONFIG_DCB is not set # # Network testing @@ -439,7 +428,6 @@ CONFIG_CAN_VCAN=m # CONFIG_CAN_DEBUG_DEVICES is not set # CONFIG_AF_RXRPC is not set # CONFIG_PHONET is not set -# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_PCMCIA is not set @@ -487,14 +475,10 @@ CONFIG_DASD_DIAG=y CONFIG_DASD_EER=y CONFIG_VIRTIO_BLK=m CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_C2PORT is not set -# -# EEPROM support -# -# CONFIG_EEPROM_93CX6 is not set - # # SCSI device support # @@ -536,7 +520,6 @@ CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set -# CONFIG_LIBFC is not set # CONFIG_SCSI_DEBUG is not set CONFIG_ZFCP=y CONFIG_SCSI_DH=m @@ -583,10 +566,6 @@ CONFIG_NET_ETHERNET=y CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y # CONFIG_TR is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# # CONFIG_WAN is not set # @@ -614,11 +593,9 @@ CONFIG_VIRTIO_NET=m # CONFIG_DEVKMEM=y CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 CONFIG_HVC_DRIVER=y -CONFIG_HVC_IUCV=y CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM=m CONFIG_HW_RANDOM_VIRTIO=m @@ -668,6 +645,7 @@ CONFIG_S390_VMUR=m # CONFIG_NEW_LEDS is not set CONFIG_ACCESSIBILITY=y # CONFIG_STAGING is not set +CONFIG_STAGING_EXCLUDE_BUILD=y # # File systems @@ -690,7 +668,6 @@ CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -726,7 +703,10 @@ CONFIG_TMPFS_POSIX_ACL=y # CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_CONFIGFS_FS=m -CONFIG_MISC_FILESYSTEMS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -735,7 +715,6 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -829,7 +808,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set @@ -840,19 +818,15 @@ CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_HAVE_FUNCTION_TRACER=y # # Tracers # -# CONFIG_FUNCTION_TRACER is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set # CONFIG_BOOT_TRACER is not set -# CONFIG_TRACE_BRANCH_PROFILING is not set -# CONFIG_STACK_TRACER is not set # CONFIG_DYNAMIC_PRINTK_DEBUG is not set CONFIG_SAMPLES=y # CONFIG_SAMPLE_KOBJECT is not set @@ -873,17 +847,11 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_FIPS=y CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=m -CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=m -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG=m -CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_GF128MUL=m # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set @@ -917,7 +885,7 @@ CONFIG_CRYPTO_HMAC=m # # Digest # -CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=m # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -974,7 +942,6 @@ CONFIG_S390_PRNG=m # Library routines # CONFIG_BITREVERSE=m -CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC_T10DIF=y diff --git a/trunk/arch/s390/include/asm/cputime.h b/trunk/arch/s390/include/asm/cputime.h index 95b0f7db3c69..521726430afa 100644 --- a/trunk/arch/s390/include/asm/cputime.h +++ b/trunk/arch/s390/include/asm/cputime.h @@ -145,7 +145,7 @@ cputime_to_timeval(const cputime_t cputime, struct timeval *value) value->tv_usec = rp.subreg.even / 4096; value->tv_sec = rp.subreg.odd; #else - value->tv_usec = (cputime % 4096000000ULL) / 4096; + value->tv_usec = cputime % 4096000000ULL; value->tv_sec = cputime / 4096000000ULL; #endif } diff --git a/trunk/arch/s390/include/asm/lowcore.h b/trunk/arch/s390/include/asm/lowcore.h index f3720defdd16..ffdef5fe8587 100644 --- a/trunk/arch/s390/include/asm/lowcore.h +++ b/trunk/arch/s390/include/asm/lowcore.h @@ -384,8 +384,8 @@ struct _lowcore __u32 panic_magic; /* 0xe00 */ /* Per cpu primary space access list */ - __u8 pad_0xe04[0xe38-0xe04]; /* 0xe04 */ - __u64 vdso_per_cpu_data; /* 0xe38 */ + __u8 pad_0xe04[0xe3c-0xe04]; /* 0xe04 */ + __u32 vdso_per_cpu_data; /* 0xe3c */ __u32 paste[16]; /* 0xe40 */ __u8 pad13[0x11b8-0xe80]; /* 0xe80 */ diff --git a/trunk/arch/s390/include/asm/setup.h b/trunk/arch/s390/include/asm/setup.h index e8bd6ac22c99..2bd9faeb3919 100644 --- a/trunk/arch/s390/include/asm/setup.h +++ b/trunk/arch/s390/include/asm/setup.h @@ -43,8 +43,6 @@ struct mem_chunk { extern struct mem_chunk memory_chunk[]; extern unsigned long real_memory_size; -extern int memory_end_set; -extern unsigned long memory_end; void detect_memory_layout(struct mem_chunk chunk[]); diff --git a/trunk/arch/s390/kernel/irq.c b/trunk/arch/s390/kernel/irq.c index 026a37a94fc9..e7c5bfb7c755 100644 --- a/trunk/arch/s390/kernel/irq.c +++ b/trunk/arch/s390/kernel/irq.c @@ -95,7 +95,6 @@ asmlinkage void do_softirq(void) local_irq_restore(flags); } -#ifdef CONFIG_PROC_FS void init_irq_proc(void) { struct proc_dir_entry *root_irq_dir; @@ -103,4 +102,3 @@ void init_irq_proc(void) root_irq_dir = proc_mkdir("irq", NULL); create_prof_cpu_mask(root_irq_dir); } -#endif diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index c5cfb6185eac..d825f4950e4e 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -82,9 +82,7 @@ char elf_platform[ELF_PLATFORM_SIZE]; struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ - -int __initdata memory_end_set; -unsigned long __initdata memory_end; +static unsigned long __initdata memory_end; /* * This is set up by the setup-routine at boot-time @@ -283,7 +281,6 @@ void (*pm_power_off)(void) = machine_power_off; static int __init early_parse_mem(char *p) { memory_end = memparse(p, &p); - memory_end_set = 1; return 0; } early_param("mem", early_parse_mem); @@ -511,10 +508,8 @@ static void __init setup_memory_end(void) int i; #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) - if (ipl_info.type == IPL_TYPE_FCP_DUMP) { + if (ipl_info.type == IPL_TYPE_FCP_DUMP) memory_end = ZFCPDUMP_HSA_SIZE; - memory_end_set = 1; - } #endif memory_size = 0; memory_end &= PAGE_MASK; diff --git a/trunk/arch/s390/kvm/kvm-s390.c b/trunk/arch/s390/kvm/kvm-s390.c index 0d33893e1e89..be8497186b96 100644 --- a/trunk/arch/s390/kvm/kvm-s390.c +++ b/trunk/arch/s390/kvm/kvm-s390.c @@ -212,10 +212,6 @@ static void kvm_free_vcpus(struct kvm *kvm) } } -void kvm_arch_sync_events(struct kvm *kvm) -{ -} - void kvm_arch_destroy_vm(struct kvm *kvm) { kvm_free_vcpus(kvm); diff --git a/trunk/arch/sh/boards/board-ap325rxa.c b/trunk/arch/sh/boards/board-ap325rxa.c index 72da416f6162..caf4c33f4e84 100644 --- a/trunk/arch/sh/boards/board-ap325rxa.c +++ b/trunk/arch/sh/boards/board-ap325rxa.c @@ -216,12 +216,6 @@ static struct platform_device lcdc_device = { }, }; -static void camera_power(int val) -{ - gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */ - mdelay(10); -} - #ifdef CONFIG_I2C static unsigned char camera_ncm03j_magic[] = { @@ -251,11 +245,9 @@ static int camera_set_capture(struct soc_camera_platform_info *info, int ret = 0; int i; - camera_power(0); if (!enable) return 0; /* no disable for now */ - camera_power(1); for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) { u_int8_t buf[8]; @@ -434,7 +426,7 @@ static int __init ap325rxa_devices_setup(void) gpio_request(GPIO_PTZ6, NULL); gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */ gpio_request(GPIO_PTZ5, NULL); - gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */ + gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */ gpio_request(GPIO_PTZ4, NULL); gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */ diff --git a/trunk/arch/sh/configs/ap325rxa_defconfig b/trunk/arch/sh/configs/ap325rxa_defconfig index 352f87d50fdc..5c423fa8e6b8 100644 --- a/trunk/arch/sh/configs/ap325rxa_defconfig +++ b/trunk/arch/sh/configs/ap325rxa_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc2 -# Tue Jan 27 11:45:08 2009 +# Linux kernel version: 2.6.28 +# Fri Jan 9 16:54:19 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -45,12 +45,12 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y # CONFIG_RT_GROUP_SCHED is not set CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set -# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -378,7 +378,6 @@ CONFIG_WIRELESS=y # CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # CONFIG_MAC80211 is not set -# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -401,7 +400,6 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_TESTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y # CONFIG_MTD_AR7_PARTS is not set @@ -449,7 +447,9 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_START=0xffffffff +CONFIG_MTD_PHYSMAP_LEN=0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=0 # CONFIG_MTD_PLATRAM is not set # @@ -479,12 +479,6 @@ CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_SH_FLCTL=y # CONFIG_MTD_ONENAND is not set -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set -# CONFIG_MTD_QINFO_PROBE is not set - # # UBI - Unsorted block images # @@ -613,10 +607,6 @@ CONFIG_SMSC911X=y # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set # CONFIG_IWLWIFI_LEDS is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -800,7 +790,6 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_PMIC_DA903X is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_PCF50633 is not set # CONFIG_REGULATOR is not set # @@ -848,7 +837,7 @@ CONFIG_SOC_CAMERA=y # CONFIG_SOC_CAMERA_MT9V022 is not set # CONFIG_SOC_CAMERA_TW9910 is not set CONFIG_SOC_CAMERA_PLATFORM=y -CONFIG_SOC_CAMERA_OV772X=y +# CONFIG_SOC_CAMERA_OV772X is not set CONFIG_VIDEO_SH_MOBILE_CEU=y # CONFIG_RADIO_ADAPTERS is not set # CONFIG_DAB is not set @@ -1023,7 +1012,6 @@ CONFIG_FS_POSIX_ACL=y CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1072,7 +1060,6 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_JFFS2_FS is not set # CONFIG_UBIFS_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set diff --git a/trunk/arch/sh/configs/migor_defconfig b/trunk/arch/sh/configs/migor_defconfig index 678576796bdf..7758263514bc 100644 --- a/trunk/arch/sh/configs/migor_defconfig +++ b/trunk/arch/sh/configs/migor_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc1 -# Thu Jan 22 09:16:16 2009 +# Linux kernel version: 2.6.28 +# Fri Jan 9 17:09:35 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -45,12 +45,8 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set - -# -# Control Group support -# # CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -393,7 +389,6 @@ CONFIG_WIRELESS_EXT=y CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # CONFIG_MAC80211 is not set -# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -416,7 +411,6 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_TESTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y # CONFIG_MTD_AR7_PARTS is not set @@ -464,7 +458,9 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_START=0xffffffff +CONFIG_MTD_PHYSMAP_LEN=0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=0 # CONFIG_MTD_PLATRAM is not set # @@ -491,12 +487,6 @@ CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_PLATFORM=y # CONFIG_MTD_ONENAND is not set -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set -# CONFIG_MTD_QINFO_PROBE is not set - # # UBI - Unsorted block images # @@ -597,10 +587,6 @@ CONFIG_SMC91X=y # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set # CONFIG_IWLWIFI_LEDS is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -775,7 +761,6 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_PMIC_DA903X is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_PCF50633 is not set # CONFIG_REGULATOR is not set # @@ -821,9 +806,9 @@ CONFIG_SOC_CAMERA=y # CONFIG_SOC_CAMERA_MT9M111 is not set # CONFIG_SOC_CAMERA_MT9T031 is not set # CONFIG_SOC_CAMERA_MT9V022 is not set -CONFIG_SOC_CAMERA_TW9910=y -# CONFIG_SOC_CAMERA_PLATFORM is not set -CONFIG_SOC_CAMERA_OV772X=y +# CONFIG_SOC_CAMERA_TW9910 is not set +CONFIG_SOC_CAMERA_PLATFORM=y +# CONFIG_SOC_CAMERA_OV772X is not set CONFIG_VIDEO_SH_MOBILE_CEU=y # CONFIG_RADIO_ADAPTERS is not set # CONFIG_DAB is not set @@ -881,13 +866,11 @@ CONFIG_USB_GADGET_SELECTED=y # CONFIG_USB_GADGET_PXA25X is not set # CONFIG_USB_GADGET_PXA27X is not set # CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_IMX is not set CONFIG_USB_GADGET_M66592=y CONFIG_USB_M66592=y CONFIG_SUPERH_BUILT_IN_M66592=y # CONFIG_USB_GADGET_AMD5536UDC is not set # CONFIG_USB_GADGET_FSL_QE is not set -# CONFIG_USB_GADGET_CI13XXX is not set # CONFIG_USB_GADGET_NET2280 is not set # CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set @@ -900,11 +883,6 @@ CONFIG_USB_G_SERIAL=y # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set - -# -# OTG and related infrastructure -# -# CONFIG_USB_GPIO_VBUS is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set @@ -983,7 +961,6 @@ CONFIG_UIO_PDRV_GENIRQ=y CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY is not set # CONFIG_QUOTA is not set @@ -1027,7 +1004,6 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set diff --git a/trunk/arch/sh/include/asm/mutex-llsc.h b/trunk/arch/sh/include/asm/mutex-llsc.h index 090358a7e1bb..ee839ee58ac8 100644 --- a/trunk/arch/sh/include/asm/mutex-llsc.h +++ b/trunk/arch/sh/include/asm/mutex-llsc.h @@ -21,36 +21,38 @@ static inline void __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) { - int __done, __res; + int __ex_flag, __res; __asm__ __volatile__ ( "movli.l @%2, %0 \n" "add #-1, %0 \n" "movco.l %0, @%2 \n" "movt %1 \n" - : "=&z" (__res), "=&r" (__done) + : "=&z" (__res), "=&r" (__ex_flag) : "r" (&(count)->counter) : "t"); - if (unlikely(!__done || __res != 0)) + __res |= !__ex_flag; + if (unlikely(__res != 0)) fail_fn(count); } static inline int __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) { - int __done, __res; + int __ex_flag, __res; __asm__ __volatile__ ( "movli.l @%2, %0 \n" "add #-1, %0 \n" "movco.l %0, @%2 \n" "movt %1 \n" - : "=&z" (__res), "=&r" (__done) + : "=&z" (__res), "=&r" (__ex_flag) : "r" (&(count)->counter) : "t"); - if (unlikely(!__done || __res != 0)) + __res |= !__ex_flag; + if (unlikely(__res != 0)) __res = fail_fn(count); return __res; @@ -59,18 +61,19 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) static inline void __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) { - int __done, __res; + int __ex_flag, __res; __asm__ __volatile__ ( "movli.l @%2, %0 \n\t" "add #1, %0 \n\t" "movco.l %0, @%2 \n\t" "movt %1 \n\t" - : "=&z" (__res), "=&r" (__done) + : "=&z" (__res), "=&r" (__ex_flag) : "r" (&(count)->counter) : "t"); - if (unlikely(!__done || __res <= 0)) + __res |= !__ex_flag; + if (unlikely(__res <= 0)) fail_fn(count); } diff --git a/trunk/arch/sh/include/asm/syscall_32.h b/trunk/arch/sh/include/asm/syscall_32.h index 5bc34681d994..05a868a71ef5 100644 --- a/trunk/arch/sh/include/asm/syscall_32.h +++ b/trunk/arch/sh/include/asm/syscall_32.h @@ -21,10 +21,23 @@ static inline void syscall_rollback(struct task_struct *task, */ } +static inline bool syscall_has_error(struct pt_regs *regs) +{ + return (regs->sr & 0x1) ? true : false; +} +static inline void syscall_set_error(struct pt_regs *regs) +{ + regs->sr |= 0x1; +} +static inline void syscall_clear_error(struct pt_regs *regs) +{ + regs->sr &= ~0x1; +} + static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { - return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0; + return syscall_has_error(regs) ? regs->regs[0] : 0; } static inline long syscall_get_return_value(struct task_struct *task, @@ -37,10 +50,13 @@ static inline void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, int error, long val) { - if (error) + if (error) { + syscall_set_error(regs); regs->regs[0] = -error; - else + } else { + syscall_clear_error(regs); regs->regs[0] = val; + } } static inline void syscall_get_arguments(struct task_struct *task, diff --git a/trunk/arch/sh/include/asm/syscall_64.h b/trunk/arch/sh/include/asm/syscall_64.h index c3561ca72bee..e1143b9784d6 100644 --- a/trunk/arch/sh/include/asm/syscall_64.h +++ b/trunk/arch/sh/include/asm/syscall_64.h @@ -21,10 +21,23 @@ static inline void syscall_rollback(struct task_struct *task, */ } +static inline bool syscall_has_error(struct pt_regs *regs) +{ + return (regs->sr & 0x1) ? true : false; +} +static inline void syscall_set_error(struct pt_regs *regs) +{ + regs->sr |= 0x1; +} +static inline void syscall_clear_error(struct pt_regs *regs) +{ + regs->sr &= ~0x1; +} + static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { - return IS_ERR_VALUE(regs->regs[9]) ? regs->regs[9] : 0; + return syscall_has_error(regs) ? regs->regs[9] : 0; } static inline long syscall_get_return_value(struct task_struct *task, @@ -37,10 +50,13 @@ static inline void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, int error, long val) { - if (error) + if (error) { + syscall_set_error(regs); regs->regs[9] = -error; - else + } else { + syscall_clear_error(regs); regs->regs[9] = val; + } } static inline void syscall_get_arguments(struct task_struct *task, diff --git a/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7201.c index 4a5e59732334..020a96fe961a 100644 --- a/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7201.c +++ b/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7201.c @@ -18,8 +18,8 @@ #include #include -static const int pll1rate[]={1,2,3,4,6,8}; -static const int pfc_divisors[]={1,2,3,4,6,8,12}; +const static int pll1rate[]={1,2,3,4,6,8}; +const static int pfc_divisors[]={1,2,3,4,6,8,12}; #define ifc_divisors pfc_divisors #if (CONFIG_SH_CLK_MD == 0) diff --git a/trunk/arch/sh/kernel/cpu/sh4/fpu.c b/trunk/arch/sh/kernel/cpu/sh4/fpu.c index e3ea5411da6d..2780917c0088 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/fpu.c +++ b/trunk/arch/sh/kernel/cpu/sh4/fpu.c @@ -423,7 +423,7 @@ static int ieee_fpe_handler(struct pt_regs *regs) int m; unsigned int hx; - m = (finsn >> 8) & 0x7; + m = (finsn >> 9) & 0x7; hx = tsk->thread.fpu.hard.fp_regs[m]; if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR) diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index 370d2cfa34eb..534247508572 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -262,11 +262,11 @@ void __init setup_bootmem_allocator(unsigned long free_pfn) BOOTMEM_DEFAULT); /* - * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET. + * reserve physical page 0 - it's a special BIOS page on many boxes, + * enabling clean reboots, SMP operation, laptop functions. */ - if (CONFIG_ZERO_PAGE_OFFSET != 0) - reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET, - BOOTMEM_DEFAULT); + reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET, + BOOTMEM_DEFAULT); sparse_memory_present_with_active_regions(0); diff --git a/trunk/arch/sh/kernel/signal_32.c b/trunk/arch/sh/kernel/signal_32.c index 17784e19ae34..77c21bde376a 100644 --- a/trunk/arch/sh/kernel/signal_32.c +++ b/trunk/arch/sh/kernel/signal_32.c @@ -510,6 +510,7 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs, case -ERESTARTNOHAND: no_system_call_restart: regs->regs[0] = -EINTR; + regs->sr |= 1; break; case -ERESTARTSYS: @@ -588,7 +589,8 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { - handle_syscall_restart(save_r0, regs, &ka.sa); + if (regs->sr & 1) + handle_syscall_restart(save_r0, regs, &ka.sa); /* Whee! Actually deliver the signal. */ if (handle_signal(signr, &ka, &info, oldset, diff --git a/trunk/arch/sh/kernel/signal_64.c b/trunk/arch/sh/kernel/signal_64.c index 0663a0ee6021..b22fdfaaa191 100644 --- a/trunk/arch/sh/kernel/signal_64.c +++ b/trunk/arch/sh/kernel/signal_64.c @@ -60,6 +60,7 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa) case -ERESTARTNOHAND: no_system_call_restart: regs->regs[REG_RET] = -EINTR; + regs->sr |= 1; break; case -ERESTARTSYS: @@ -108,7 +109,8 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) signr = get_signal_to_deliver(&info, &ka, regs, 0); if (signr > 0) { - handle_syscall_restart(regs, &ka.sa); + if (regs->sr & 1) + handle_syscall_restart(regs, &ka.sa); /* Whee! Actually deliver the signal. */ if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { diff --git a/trunk/arch/sh/lib/checksum.S b/trunk/arch/sh/lib/checksum.S index 356c8ec92893..cbdd0d40e545 100644 --- a/trunk/arch/sh/lib/checksum.S +++ b/trunk/arch/sh/lib/checksum.S @@ -36,7 +36,8 @@ */ /* - * asmlinkage __wsum csum_partial(const void *buf, int len, __wsum sum); + * unsigned int csum_partial(const unsigned char *buf, int len, + * unsigned int sum); */ .text @@ -48,31 +49,11 @@ ENTRY(csum_partial) * Fortunately, it is easy to convert 2-byte alignment to 4-byte * alignment for the unrolled loop. */ + mov r5, r1 mov r4, r0 - tst #3, r0 ! Check alignment. - bt/s 2f ! Jump if alignment is ok. - mov r4, r7 ! Keep a copy to check for alignment + tst #2, r0 ! Check alignment. + bt 2f ! Jump if alignment is ok. ! - tst #1, r0 ! Check alignment. - bt 21f ! Jump if alignment is boundary of 2bytes. - - ! buf is odd - tst r5, r5 - add #-1, r5 - bt 9f - mov.b @r4+, r0 - extu.b r0, r0 - addc r0, r6 ! t=0 from previous tst - mov r6, r0 - shll8 r6 - shlr16 r0 - shlr8 r0 - or r0, r6 - mov r4, r0 - tst #2, r0 - bt 2f -21: - ! buf is 2 byte aligned (len could be 0) add #-2, r5 ! Alignment uses up two bytes. cmp/pz r5 ! bt/s 1f ! Jump if we had at least two bytes. @@ -80,17 +61,16 @@ ENTRY(csum_partial) bra 6f add #2, r5 ! r5 was < 2. Deal with it. 1: + mov r5, r1 ! Save new len for later use. mov.w @r4+, r0 extu.w r0, r0 addc r0, r6 bf 2f add #1, r6 2: - ! buf is 4 byte aligned (len could be 0) - mov r5, r1 mov #-5, r0 - shld r0, r1 - tst r1, r1 + shld r0, r5 + tst r5, r5 bt/s 4f ! if it's =0, go to 4f clrt .align 2 @@ -112,31 +92,30 @@ ENTRY(csum_partial) addc r0, r6 addc r2, r6 movt r0 - dt r1 + dt r5 bf/s 3b cmp/eq #1, r0 - ! here, we know r1==0 - addc r1, r6 ! add carry to r6 + ! here, we know r5==0 + addc r5, r6 ! add carry to r6 4: - mov r5, r0 + mov r1, r0 and #0x1c, r0 tst r0, r0 - bt 6f - ! 4 bytes or more remaining - mov r0, r1 - shlr2 r1 + bt/s 6f + mov r0, r5 + shlr2 r5 mov #0, r2 5: addc r2, r6 mov.l @r4+, r2 movt r0 - dt r1 + dt r5 bf/s 5b cmp/eq #1, r0 addc r2, r6 - addc r1, r6 ! r1==0 here, so it means add carry-bit + addc r5, r6 ! r5==0 here, so it means add carry-bit 6: - ! 3 bytes or less remaining + mov r1, r5 mov #3, r0 and r0, r5 tst r5, r5 @@ -160,18 +139,8 @@ ENTRY(csum_partial) 8: addc r0, r6 mov #0, r0 - addc r0, r6 + addc r0, r6 9: - ! Check if the buffer was misaligned, if so realign sum - mov r7, r0 - tst #1, r0 - bt 10f - mov r6, r0 - shll8 r6 - shlr16 r0 - shlr8 r0 - or r0, r6 -10: rts mov r6, r0 diff --git a/trunk/arch/sparc/include/asm/compat.h b/trunk/arch/sparc/include/asm/compat.h index 0e706257918f..f260b58f5ce9 100644 --- a/trunk/arch/sparc/include/asm/compat.h +++ b/trunk/arch/sparc/include/asm/compat.h @@ -240,9 +240,4 @@ struct compat_shmid64_ds { unsigned int __unused2; }; -static inline int is_compat_task(void) -{ - return test_thread_flag(TIF_32BIT); -} - #endif /* _ASM_SPARC64_COMPAT_H */ diff --git a/trunk/arch/sparc/include/asm/cpudata_64.h b/trunk/arch/sparc/include/asm/cpudata_64.h index a11b89ee9ef8..7da7c13d23c4 100644 --- a/trunk/arch/sparc/include/asm/cpudata_64.h +++ b/trunk/arch/sparc/include/asm/cpudata_64.h @@ -17,7 +17,7 @@ typedef struct { /* Dcache line 1 */ unsigned int __softirq_pending; /* must be 1st, see rtrap.S */ - unsigned int __nmi_count; + unsigned int __pad0; unsigned long clock_tick; /* %tick's per second */ unsigned long __pad; unsigned int __pad1; diff --git a/trunk/arch/sparc/include/asm/irq_64.h b/trunk/arch/sparc/include/asm/irq_64.h index 1934f2cbf513..d47d4a1955a9 100644 --- a/trunk/arch/sparc/include/asm/irq_64.h +++ b/trunk/arch/sparc/include/asm/irq_64.h @@ -66,6 +66,9 @@ extern void virt_irq_free(unsigned int virt_irq); extern void __init init_IRQ(void); extern void fixup_irqs(void); +extern int register_perfctr_intr(void (*handler)(struct pt_regs *)); +extern void release_perfctr_intr(void (*handler)(struct pt_regs *)); + static inline void set_softint(unsigned long bits) { __asm__ __volatile__("wr %0, 0x0, %%set_softint" @@ -95,6 +98,5 @@ void __trigger_all_cpu_backtrace(void); extern void *hardirq_stack[NR_CPUS]; extern void *softirq_stack[NR_CPUS]; #define __ARCH_HAS_DO_SOFTIRQ -#define ARCH_HAS_NMI_WATCHDOG #endif diff --git a/trunk/arch/sparc/include/asm/kdebug_64.h b/trunk/arch/sparc/include/asm/kdebug_64.h index feb3578e12c4..f905b773235a 100644 --- a/trunk/arch/sparc/include/asm/kdebug_64.h +++ b/trunk/arch/sparc/include/asm/kdebug_64.h @@ -14,8 +14,6 @@ enum die_val { DIE_TRAP, DIE_TRAP_TL1, DIE_CALL, - DIE_NMI, - DIE_NMIWATCHDOG, }; #endif diff --git a/trunk/arch/sparc/include/asm/nmi.h b/trunk/arch/sparc/include/asm/nmi.h deleted file mode 100644 index fbd546dd4feb..000000000000 --- a/trunk/arch/sparc/include/asm/nmi.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __NMI_H -#define __NMI_H - -extern int __init nmi_init(void); -extern void perfctr_irq(int irq, struct pt_regs *regs); -extern void nmi_adjust_hz(unsigned int new_hz); - -extern int nmi_usable; - -#endif /* __NMI_H */ diff --git a/trunk/arch/sparc/include/asm/pcr.h b/trunk/arch/sparc/include/asm/pcr.h deleted file mode 100644 index a2f5c61f924e..000000000000 --- a/trunk/arch/sparc/include/asm/pcr.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __PCR_H -#define __PCR_H - -struct pcr_ops { - u64 (*read)(void); - void (*write)(u64); -}; -extern const struct pcr_ops *pcr_ops; - -extern void deferred_pcr_work_irq(int irq, struct pt_regs *regs); -extern void schedule_deferred_pcr_work(void); - -#define PCR_PIC_PRIV 0x00000001 /* PIC access is privileged */ -#define PCR_STRACE 0x00000002 /* Trace supervisor events */ -#define PCR_UTRACE 0x00000004 /* Trace user events */ -#define PCR_N2_HTRACE 0x00000008 /* Trace hypervisor events */ -#define PCR_N2_TOE_OV0 0x00000010 /* Trap if PIC 0 overflows */ -#define PCR_N2_TOE_OV1 0x00000020 /* Trap if PIC 1 overflows */ -#define PCR_N2_MASK0 0x00003fc0 -#define PCR_N2_MASK0_SHIFT 6 -#define PCR_N2_SL0 0x0003c000 -#define PCR_N2_SL0_SHIFT 14 -#define PCR_N2_OV0 0x00040000 -#define PCR_N2_MASK1 0x07f80000 -#define PCR_N2_MASK1_SHIFT 19 -#define PCR_N2_SL1 0x78000000 -#define PCR_N2_SL1_SHIFT 27 -#define PCR_N2_OV1 0x80000000 - -extern unsigned int picl_shift; - -/* In order to commonize as much of the implementation as - * possible, we use PICH as our counter. Mostly this is - * to accomodate Niagara-1 which can only count insn cycles - * in PICH. - */ -static inline u64 picl_value(unsigned int nmi_hz) -{ - u32 delta = local_cpu_data().clock_tick / (nmi_hz << picl_shift); - - return ((u64)((0 - delta) & 0xffffffff)) << 32; -} - -extern u64 pcr_enable; - -#endif /* __PCR_H */ diff --git a/trunk/arch/sparc/include/asm/pil.h b/trunk/arch/sparc/include/asm/pil.h index 32a7efe76d00..d573820c0ff4 100644 --- a/trunk/arch/sparc/include/asm/pil.h +++ b/trunk/arch/sparc/include/asm/pil.h @@ -23,7 +23,6 @@ #define PIL_SMP_CTX_NEW_VERSION 4 #define PIL_DEVICE_IRQ 5 #define PIL_SMP_CALL_FUNC_SNGL 6 -#define PIL_DEFERRED_PCR_WORK 7 #define PIL_NORMAL_MAX 14 #define PIL_NMI 15 diff --git a/trunk/arch/sparc/include/asm/seccomp.h b/trunk/arch/sparc/include/asm/seccomp.h index adca1bce41d4..7fcd9968192b 100644 --- a/trunk/arch/sparc/include/asm/seccomp.h +++ b/trunk/arch/sparc/include/asm/seccomp.h @@ -1,5 +1,11 @@ #ifndef _ASM_SECCOMP_H +#include /* already defines TIF_32BIT */ + +#ifndef TIF_32BIT +#error "unexpected TIF_32BIT on sparc64" +#endif + #include #define __NR_seccomp_read __NR_read diff --git a/trunk/arch/sparc/kernel/Makefile b/trunk/arch/sparc/kernel/Makefile index 54742e58831c..53adcaa0348b 100644 --- a/trunk/arch/sparc/kernel/Makefile +++ b/trunk/arch/sparc/kernel/Makefile @@ -52,8 +52,6 @@ obj-$(CONFIG_SPARC64) += visemul.o obj-$(CONFIG_SPARC64) += hvapi.o obj-$(CONFIG_SPARC64) += sstate.o obj-$(CONFIG_SPARC64) += mdesc.o -obj-$(CONFIG_SPARC64) += pcr.o -obj-$(CONFIG_SPARC64) += nmi.o # sparc32 do not use GENERIC_HARDIRQS but uses the generic devres implementation obj-$(CONFIG_SPARC32) += devres.o diff --git a/trunk/arch/sparc/kernel/chmc.c b/trunk/arch/sparc/kernel/chmc.c index e1a9598e2a4d..3b9f4d6e14a9 100644 --- a/trunk/arch/sparc/kernel/chmc.c +++ b/trunk/arch/sparc/kernel/chmc.c @@ -306,7 +306,6 @@ static int jbusmc_print_dimm(int syndrome_code, buf[1] = '?'; buf[2] = '?'; buf[3] = '\0'; - return 0; } p = dp->controller; prop = &p->layout; diff --git a/trunk/arch/sparc/kernel/cpu.c b/trunk/arch/sparc/kernel/cpu.c index d85c3dc4953a..32d32b4824f5 100644 --- a/trunk/arch/sparc/kernel/cpu.c +++ b/trunk/arch/sparc/kernel/cpu.c @@ -26,7 +26,6 @@ EXPORT_PER_CPU_SYMBOL(__cpu_data); struct cpu_info { int psr_vers; const char *name; - const char *pmu_name; }; struct fpu_info { @@ -46,9 +45,6 @@ struct manufacturer_info { #define CPU(ver, _name) \ { .psr_vers = ver, .name = _name } -#define CPU_PMU(ver, _name, _pmu_name) \ -{ .psr_vers = ver, .name = _name, .pmu_name = _pmu_name } - #define FPU(ver, _name) \ { .fp_vers = ver, .name = _name } @@ -187,10 +183,10 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { },{ 0x17, .cpu_info = { - CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"), - CPU_PMU(0x11, "TI UltraSparc II (BlackBird)", "ultra12"), - CPU_PMU(0x12, "TI UltraSparc IIi (Sabre)", "ultra12"), - CPU_PMU(0x13, "TI UltraSparc IIe (Hummingbird)", "ultra12"), + CPU(0x10, "TI UltraSparc I (SpitFire)"), + CPU(0x11, "TI UltraSparc II (BlackBird)"), + CPU(0x12, "TI UltraSparc IIi (Sabre)"), + CPU(0x13, "TI UltraSparc IIe (Hummingbird)"), CPU(-1, NULL) }, .fpu_info = { @@ -203,7 +199,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { },{ 0x22, .cpu_info = { - CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"), + CPU(0x10, "TI UltraSparc I (SpitFire)"), CPU(-1, NULL) }, .fpu_info = { @@ -213,12 +209,12 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { },{ 0x3e, .cpu_info = { - CPU_PMU(0x14, "TI UltraSparc III (Cheetah)", "ultra3"), - CPU_PMU(0x15, "TI UltraSparc III+ (Cheetah+)", "ultra3+"), - CPU_PMU(0x16, "TI UltraSparc IIIi (Jalapeno)", "ultra3i"), - CPU_PMU(0x18, "TI UltraSparc IV (Jaguar)", "ultra3+"), - CPU_PMU(0x19, "TI UltraSparc IV+ (Panther)", "ultra4+"), - CPU_PMU(0x22, "TI UltraSparc IIIi+ (Serrano)", "ultra3i"), + CPU(0x14, "TI UltraSparc III (Cheetah)"), + CPU(0x15, "TI UltraSparc III+ (Cheetah+)"), + CPU(0x16, "TI UltraSparc IIIi (Jalapeno)"), + CPU(0x18, "TI UltraSparc IV (Jaguar)"), + CPU(0x19, "TI UltraSparc IV+ (Panther)"), + CPU(0x22, "TI UltraSparc IIIi+ (Serrano)"), CPU(-1, NULL) }, .fpu_info = { @@ -238,7 +234,6 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { const char *sparc_cpu_type; const char *sparc_fpu_type; -const char *sparc_pmu_type; unsigned int fsr_storage; @@ -249,7 +244,6 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers) sparc_cpu_type = NULL; sparc_fpu_type = NULL; - sparc_pmu_type = NULL; manuf = NULL; for (i = 0; i < ARRAY_SIZE(manufacturer_info); i++) @@ -269,7 +263,6 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers) { if (cpu->psr_vers == psr_vers) { sparc_cpu_type = cpu->name; - sparc_pmu_type = cpu->pmu_name; sparc_fpu_type = "No FPU"; break; } @@ -297,8 +290,6 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers) psr_impl, fpu_vers); sparc_fpu_type = "Unknown FPU"; } - if (sparc_pmu_type == NULL) - sparc_pmu_type = "Unknown PMU"; } #ifdef CONFIG_SPARC32 @@ -324,13 +315,11 @@ static void __init sun4v_cpu_probe(void) case SUN4V_CHIP_NIAGARA1: sparc_cpu_type = "UltraSparc T1 (Niagara)"; sparc_fpu_type = "UltraSparc T1 integrated FPU"; - sparc_pmu_type = "niagara"; break; case SUN4V_CHIP_NIAGARA2: sparc_cpu_type = "UltraSparc T2 (Niagara2)"; sparc_fpu_type = "UltraSparc T2 integrated FPU"; - sparc_pmu_type = "niagara2"; break; default: diff --git a/trunk/arch/sparc/kernel/head_64.S b/trunk/arch/sparc/kernel/head_64.S index a46c3a21e26d..8ffee714f932 100644 --- a/trunk/arch/sparc/kernel/head_64.S +++ b/trunk/arch/sparc/kernel/head_64.S @@ -891,35 +891,10 @@ prom_tba: .xword 0 tlb_type: .word 0 /* Must NOT end up in BSS */ .section ".fixup",#alloc,#execinstr - .globl __ret_efault, __retl_efault, __ret_one, __retl_one -ENTRY(__ret_efault) + .globl __ret_efault, __retl_efault +__ret_efault: ret restore %g0, -EFAULT, %o0 -ENDPROC(__ret_efault) - -ENTRY(__retl_efault) +__retl_efault: retl mov -EFAULT, %o0 -ENDPROC(__retl_efault) - -ENTRY(__retl_one) - retl - mov 1, %o0 -ENDPROC(__retl_one) - -ENTRY(__ret_one_asi) - wr %g0, ASI_AIUS, %asi - ret - restore %g0, 1, %o0 -ENDPROC(__ret_one_asi) - -ENTRY(__retl_one_asi) - wr %g0, ASI_AIUS, %asi - retl - mov 1, %o0 -ENDPROC(__retl_one_asi) - -ENTRY(__retl_o1) - retl - mov %o1, %o0 -ENDPROC(__retl_o1) diff --git a/trunk/arch/sparc/kernel/irq_64.c b/trunk/arch/sparc/kernel/irq_64.c index e289376198eb..cab8e0286871 100644 --- a/trunk/arch/sparc/kernel/irq_64.c +++ b/trunk/arch/sparc/kernel/irq_64.c @@ -196,11 +196,6 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { - seq_printf(p, "NMI: "); - for_each_online_cpu(j) - seq_printf(p, "%10u ", cpu_data(j).__nmi_count); - seq_printf(p, " Non-maskable interrupts\n"); } return 0; } @@ -783,6 +778,69 @@ void do_softirq(void) local_irq_restore(flags); } +static void unhandled_perf_irq(struct pt_regs *regs) +{ + unsigned long pcr, pic; + + read_pcr(pcr); + read_pic(pic); + + write_pcr(0); + + printk(KERN_EMERG "CPU %d: Got unexpected perf counter IRQ.\n", + smp_processor_id()); + printk(KERN_EMERG "CPU %d: PCR[%016lx] PIC[%016lx]\n", + smp_processor_id(), pcr, pic); +} + +/* Almost a direct copy of the powerpc PMC code. */ +static DEFINE_SPINLOCK(perf_irq_lock); +static void *perf_irq_owner_caller; /* mostly for debugging */ +static void (*perf_irq)(struct pt_regs *regs) = unhandled_perf_irq; + +/* Invoked from level 15 PIL handler in trap table. */ +void perfctr_irq(int irq, struct pt_regs *regs) +{ + clear_softint(1 << irq); + perf_irq(regs); +} + +int register_perfctr_intr(void (*handler)(struct pt_regs *)) +{ + int ret; + + if (!handler) + return -EINVAL; + + spin_lock(&perf_irq_lock); + if (perf_irq != unhandled_perf_irq) { + printk(KERN_WARNING "register_perfctr_intr: " + "perf IRQ busy (reserved by caller %p)\n", + perf_irq_owner_caller); + ret = -EBUSY; + goto out; + } + + perf_irq_owner_caller = __builtin_return_address(0); + perf_irq = handler; + + ret = 0; +out: + spin_unlock(&perf_irq_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(register_perfctr_intr); + +void release_perfctr_intr(void (*handler)(struct pt_regs *)) +{ + spin_lock(&perf_irq_lock); + perf_irq_owner_caller = NULL; + perf_irq = unhandled_perf_irq; + spin_unlock(&perf_irq_lock); +} +EXPORT_SYMBOL_GPL(release_perfctr_intr); + #ifdef CONFIG_HOTPLUG_CPU void fixup_irqs(void) { diff --git a/trunk/arch/sparc/kernel/kernel.h b/trunk/arch/sparc/kernel/kernel.h index 15d8a3f645c9..81a972e8d8ea 100644 --- a/trunk/arch/sparc/kernel/kernel.h +++ b/trunk/arch/sparc/kernel/kernel.h @@ -5,7 +5,6 @@ /* cpu.c */ extern const char *sparc_cpu_type; -extern const char *sparc_pmu_type; extern const char *sparc_fpu_type; extern unsigned int fsr_storage; diff --git a/trunk/arch/sparc/kernel/nmi.c b/trunk/arch/sparc/kernel/nmi.c deleted file mode 100644 index f3577223c863..000000000000 --- a/trunk/arch/sparc/kernel/nmi.c +++ /dev/null @@ -1,225 +0,0 @@ -/* Pseudo NMI support on sparc64 systems. - * - * Copyright (C) 2009 David S. Miller - * - * The NMI watchdog support and infrastructure is based almost - * entirely upon the x86 NMI support code. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* We don't have a real NMI on sparc64, but we can fake one - * up using profiling counter overflow interrupts and interrupt - * levels. - * - * The profile overflow interrupts at level 15, so we use - * level 14 as our IRQ off level. - */ - -static int nmi_watchdog_active; -static int panic_on_timeout; - -int nmi_usable; -EXPORT_SYMBOL_GPL(nmi_usable); - -static unsigned int nmi_hz = HZ; - -static DEFINE_PER_CPU(unsigned int, last_irq_sum); -static DEFINE_PER_CPU(local_t, alert_counter); -static DEFINE_PER_CPU(int, nmi_touch); - -void touch_nmi_watchdog(void) -{ - if (nmi_watchdog_active) { - int cpu; - - for_each_present_cpu(cpu) { - if (per_cpu(nmi_touch, cpu) != 1) - per_cpu(nmi_touch, cpu) = 1; - } - } - - touch_softlockup_watchdog(); -} -EXPORT_SYMBOL(touch_nmi_watchdog); - -static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) -{ - if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, - pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) - return; - - console_verbose(); - bust_spinlocks(1); - - printk(KERN_EMERG "%s", str); - printk(" on CPU%d, ip %08lx, registers:\n", - smp_processor_id(), regs->tpc); - show_regs(regs); - dump_stack(); - - bust_spinlocks(0); - - if (do_panic || panic_on_oops) - panic("Non maskable interrupt"); - - local_irq_enable(); - do_exit(SIGBUS); -} - -notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) -{ - unsigned int sum, touched = 0; - int cpu = smp_processor_id(); - - clear_softint(1 << irq); - pcr_ops->write(PCR_PIC_PRIV); - - local_cpu_data().__nmi_count++; - - if (notify_die(DIE_NMI, "nmi", regs, 0, - pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) - touched = 1; - - sum = kstat_irqs_cpu(0, cpu); - if (__get_cpu_var(nmi_touch)) { - __get_cpu_var(nmi_touch) = 0; - touched = 1; - } - if (!touched && __get_cpu_var(last_irq_sum) == sum) { - local_inc(&__get_cpu_var(alert_counter)); - if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz) - die_nmi("BUG: NMI Watchdog detected LOCKUP", - regs, panic_on_timeout); - } else { - __get_cpu_var(last_irq_sum) = sum; - local_set(&__get_cpu_var(alert_counter), 0); - } - if (nmi_usable) { - write_pic(picl_value(nmi_hz)); - pcr_ops->write(pcr_enable); - } -} - -static inline unsigned int get_nmi_count(int cpu) -{ - return cpu_data(cpu).__nmi_count; -} - -static int endflag __initdata; - -static __init void nmi_cpu_busy(void *data) -{ - local_irq_enable_in_hardirq(); - while (endflag == 0) - mb(); -} - -static void report_broken_nmi(int cpu, int *prev_nmi_count) -{ - printk(KERN_CONT "\n"); - - printk(KERN_WARNING - "WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n", - cpu, prev_nmi_count[cpu], get_nmi_count(cpu)); - - printk(KERN_WARNING - "Please report this to bugzilla.kernel.org,\n"); - printk(KERN_WARNING - "and attach the output of the 'dmesg' command.\n"); - - nmi_usable = 0; -} - -static void stop_watchdog(void *unused) -{ - pcr_ops->write(PCR_PIC_PRIV); -} - -static int __init check_nmi_watchdog(void) -{ - unsigned int *prev_nmi_count; - int cpu, err; - - prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(unsigned int), GFP_KERNEL); - if (!prev_nmi_count) { - err = -ENOMEM; - goto error; - } - - printk(KERN_INFO "Testing NMI watchdog ... "); - - smp_call_function(nmi_cpu_busy, (void *)&endflag, 0); - - for_each_possible_cpu(cpu) - prev_nmi_count[cpu] = get_nmi_count(cpu); - local_irq_enable(); - mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */ - - for_each_online_cpu(cpu) { - if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5) - report_broken_nmi(cpu, prev_nmi_count); - } - endflag = 1; - if (!nmi_usable) { - kfree(prev_nmi_count); - err = -ENODEV; - goto error; - } - printk("OK.\n"); - - nmi_hz = 1; - - kfree(prev_nmi_count); - return 0; -error: - on_each_cpu(stop_watchdog, NULL, 1); - return err; -} - -static void start_watchdog(void *unused) -{ - pcr_ops->write(PCR_PIC_PRIV); - write_pic(picl_value(nmi_hz)); - - pcr_ops->write(pcr_enable); -} - -void nmi_adjust_hz(unsigned int new_hz) -{ - nmi_hz = new_hz; - on_each_cpu(start_watchdog, NULL, 1); -} -EXPORT_SYMBOL_GPL(nmi_adjust_hz); - -int __init nmi_init(void) -{ - nmi_usable = 1; - - on_each_cpu(start_watchdog, NULL, 1); - - return check_nmi_watchdog(); -} - -static int __init setup_nmi_watchdog(char *str) -{ - if (!strncmp(str, "panic", 5)) - panic_on_timeout = 1; - - return 0; -} -__setup("nmi_watchdog=", setup_nmi_watchdog); diff --git a/trunk/arch/sparc/kernel/pcr.c b/trunk/arch/sparc/kernel/pcr.c deleted file mode 100644 index 1ae8cdd7e703..000000000000 --- a/trunk/arch/sparc/kernel/pcr.c +++ /dev/null @@ -1,158 +0,0 @@ -/* pcr.c: Generic sparc64 performance counter infrastructure. - * - * Copyright (C) 2009 David S. Miller (davem@davemloft.net) - */ -#include -#include -#include -#include - -#include -#include -#include - -/* This code is shared between various users of the performance - * counters. Users will be oprofile, pseudo-NMI watchdog, and the - * perf_counter support layer. - */ - -#define PCR_SUN4U_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE) -#define PCR_N2_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE | \ - PCR_N2_TOE_OV1 | \ - (2 << PCR_N2_SL1_SHIFT) | \ - (0xff << PCR_N2_MASK1_SHIFT)) - -u64 pcr_enable; -unsigned int picl_shift; - -/* Performance counter interrupts run unmasked at PIL level 15. - * Therefore we can't do things like wakeups and other work - * that expects IRQ disabling to be adhered to in locking etc. - * - * Therefore in such situations we defer the work by signalling - * a lower level cpu IRQ. - */ -void deferred_pcr_work_irq(int irq, struct pt_regs *regs) -{ - clear_softint(1 << PIL_DEFERRED_PCR_WORK); -} - -void schedule_deferred_pcr_work(void) -{ - set_softint(1 << PIL_DEFERRED_PCR_WORK); -} - -const struct pcr_ops *pcr_ops; -EXPORT_SYMBOL_GPL(pcr_ops); - -static u64 direct_pcr_read(void) -{ - u64 val; - - read_pcr(val); - return val; -} - -static void direct_pcr_write(u64 val) -{ - write_pcr(val); -} - -static const struct pcr_ops direct_pcr_ops = { - .read = direct_pcr_read, - .write = direct_pcr_write, -}; - -static void n2_pcr_write(u64 val) -{ - unsigned long ret; - - ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); - if (val != HV_EOK) - write_pcr(val); -} - -static const struct pcr_ops n2_pcr_ops = { - .read = direct_pcr_read, - .write = n2_pcr_write, -}; - -static unsigned long perf_hsvc_group; -static unsigned long perf_hsvc_major; -static unsigned long perf_hsvc_minor; - -static int __init register_perf_hsvc(void) -{ - if (tlb_type == hypervisor) { - switch (sun4v_chip_type) { - case SUN4V_CHIP_NIAGARA1: - perf_hsvc_group = HV_GRP_NIAG_PERF; - break; - - case SUN4V_CHIP_NIAGARA2: - perf_hsvc_group = HV_GRP_N2_CPU; - break; - - default: - return -ENODEV; - } - - - perf_hsvc_major = 1; - perf_hsvc_minor = 0; - if (sun4v_hvapi_register(perf_hsvc_group, - perf_hsvc_major, - &perf_hsvc_minor)) { - printk("perfmon: Could not register hvapi.\n"); - return -ENODEV; - } - } - return 0; -} - -static void __init unregister_perf_hsvc(void) -{ - if (tlb_type != hypervisor) - return; - sun4v_hvapi_unregister(perf_hsvc_group); -} - -int __init pcr_arch_init(void) -{ - int err = register_perf_hsvc(); - - if (err) - return err; - - switch (tlb_type) { - case hypervisor: - pcr_ops = &n2_pcr_ops; - pcr_enable = PCR_N2_ENABLE; - picl_shift = 2; - break; - - case cheetah: - case cheetah_plus: - pcr_ops = &direct_pcr_ops; - pcr_enable = PCR_SUN4U_ENABLE; - break; - - case spitfire: - /* UltraSPARC-I/II and derivatives lack a profile - * counter overflow interrupt so we can't make use of - * their hardware currently. - */ - /* fallthrough */ - default: - err = -ENODEV; - goto out_unregister; - } - - return nmi_init(); - -out_unregister: - unregister_perf_hsvc(); - return err; -} - -arch_initcall(pcr_arch_init); diff --git a/trunk/arch/sparc/kernel/process_64.c b/trunk/arch/sparc/kernel/process_64.c index a73954b87f0a..cc8b5604442c 100644 --- a/trunk/arch/sparc/kernel/process_64.c +++ b/trunk/arch/sparc/kernel/process_64.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -53,10 +52,8 @@ static void sparc64_yield(int cpu) { - if (tlb_type != hypervisor) { - touch_nmi_watchdog(); + if (tlb_type != hypervisor) return; - } clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb__after_clear_bit(); diff --git a/trunk/arch/sparc/kernel/setup_64.c b/trunk/arch/sparc/kernel/setup_64.c index f2bcfd2967d7..49d061f4ae9d 100644 --- a/trunk/arch/sparc/kernel/setup_64.c +++ b/trunk/arch/sparc/kernel/setup_64.c @@ -354,7 +354,6 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) seq_printf(m, "cpu\t\t: %s\n" "fpu\t\t: %s\n" - "pmu\t\t: %s\n" "prom\t\t: %s\n" "type\t\t: %s\n" "ncpus probed\t: %d\n" @@ -367,7 +366,6 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) , sparc_cpu_type, sparc_fpu_type, - sparc_pmu_type, prom_version, ((tlb_type == hypervisor) ? "sun4v" : diff --git a/trunk/arch/sparc/kernel/ttable.S b/trunk/arch/sparc/kernel/ttable.S index d9bdfb9d5c18..ea925503b42e 100644 --- a/trunk/arch/sparc/kernel/ttable.S +++ b/trunk/arch/sparc/kernel/ttable.S @@ -63,8 +63,7 @@ tl0_irq6: TRAP_IRQ(smp_call_function_single_client, 6) #else tl0_irq6: BTRAP(0x46) #endif -tl0_irq7: TRAP_IRQ(deferred_pcr_work_irq, 7) -tl0_irq8: BTRAP(0x48) BTRAP(0x49) +tl0_irq7: BTRAP(0x47) BTRAP(0x48) BTRAP(0x49) tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d) tl0_irq14: TRAP_IRQ(timer_interrupt, 14) tl0_irq15: TRAP_NMI_IRQ(perfctr_irq, 15) diff --git a/trunk/arch/sparc/lib/GENbzero.S b/trunk/arch/sparc/lib/GENbzero.S index 8e7a843ddd88..6a4f956a2f7a 100644 --- a/trunk/arch/sparc/lib/GENbzero.S +++ b/trunk/arch/sparc/lib/GENbzero.S @@ -6,9 +6,13 @@ #define EX_ST(x,y) \ 98: x,y; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov %o1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_o1; \ + .word 98b, 99b; \ .text; \ .align 4; diff --git a/trunk/arch/sparc/lib/GENcopy_from_user.S b/trunk/arch/sparc/lib/GENcopy_from_user.S index b7d0bd6b1406..2b9df99e87f9 100644 --- a/trunk/arch/sparc/lib/GENcopy_from_user.S +++ b/trunk/arch/sparc/lib/GENcopy_from_user.S @@ -5,9 +5,13 @@ #define EX_LD(x) \ 98: x; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_one; \ + .word 98b, 99b; \ .text; \ .align 4; @@ -23,7 +27,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, memcpy_user_stub; \ nop #endif diff --git a/trunk/arch/sparc/lib/GENcopy_to_user.S b/trunk/arch/sparc/lib/GENcopy_to_user.S index 780550e1afc7..bb3f7084daf9 100644 --- a/trunk/arch/sparc/lib/GENcopy_to_user.S +++ b/trunk/arch/sparc/lib/GENcopy_to_user.S @@ -5,9 +5,13 @@ #define EX_ST(x) \ 98: x; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_one; \ + .word 98b, 99b; \ .text; \ .align 4; @@ -27,7 +31,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, memcpy_user_stub; \ nop #endif diff --git a/trunk/arch/sparc/lib/NG2copy_from_user.S b/trunk/arch/sparc/lib/NG2copy_from_user.S index 119ccb9a54f4..c77ef5f22102 100644 --- a/trunk/arch/sparc/lib/NG2copy_from_user.S +++ b/trunk/arch/sparc/lib/NG2copy_from_user.S @@ -5,9 +5,14 @@ #define EX_LD(x) \ 98: x; \ + .section .fixup; \ + .align 4; \ +99: wr %g0, ASI_AIUS, %asi;\ + retl; \ + mov 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_one_asi;\ + .word 98b, 99b; \ .text; \ .align 4; @@ -28,7 +33,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, memcpy_user_stub; \ nop #endif diff --git a/trunk/arch/sparc/lib/NG2copy_to_user.S b/trunk/arch/sparc/lib/NG2copy_to_user.S index 7fe1ccefd9d0..4bd4093acbbd 100644 --- a/trunk/arch/sparc/lib/NG2copy_to_user.S +++ b/trunk/arch/sparc/lib/NG2copy_to_user.S @@ -5,9 +5,14 @@ #define EX_ST(x) \ 98: x; \ + .section .fixup; \ + .align 4; \ +99: wr %g0, ASI_AIUS, %asi;\ + retl; \ + mov 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_one_asi;\ + .word 98b, 99b; \ .text; \ .align 4; @@ -37,7 +42,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, memcpy_user_stub; \ nop #endif diff --git a/trunk/arch/sparc/lib/NGbzero.S b/trunk/arch/sparc/lib/NGbzero.S index beab29bf419b..814d5f7a45e1 100644 --- a/trunk/arch/sparc/lib/NGbzero.S +++ b/trunk/arch/sparc/lib/NGbzero.S @@ -6,9 +6,13 @@ #define EX_ST(x,y) \ 98: x,y; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov %o1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_o1; \ + .word 98b, 99b; \ .text; \ .align 4; diff --git a/trunk/arch/sparc/lib/NGcopy_from_user.S b/trunk/arch/sparc/lib/NGcopy_from_user.S index 5d1e4d1ac21e..e7f433f71b42 100644 --- a/trunk/arch/sparc/lib/NGcopy_from_user.S +++ b/trunk/arch/sparc/lib/NGcopy_from_user.S @@ -5,9 +5,14 @@ #define EX_LD(x) \ 98: x; \ + .section .fixup; \ + .align 4; \ +99: wr %g0, ASI_AIUS, %asi;\ + ret; \ + restore %g0, 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __ret_one_asi;\ + .word 98b, 99b; \ .text; \ .align 4; @@ -25,7 +30,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, memcpy_user_stub; \ nop #endif diff --git a/trunk/arch/sparc/lib/NGcopy_to_user.S b/trunk/arch/sparc/lib/NGcopy_to_user.S index ff630dcb273c..6ea01c5532a0 100644 --- a/trunk/arch/sparc/lib/NGcopy_to_user.S +++ b/trunk/arch/sparc/lib/NGcopy_to_user.S @@ -5,9 +5,14 @@ #define EX_ST(x) \ 98: x; \ + .section .fixup; \ + .align 4; \ +99: wr %g0, ASI_AIUS, %asi;\ + ret; \ + restore %g0, 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __ret_one_asi;\ + .word 98b, 99b; \ .text; \ .align 4; @@ -28,7 +33,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, memcpy_user_stub; \ nop #endif diff --git a/trunk/arch/sparc/lib/U1copy_from_user.S b/trunk/arch/sparc/lib/U1copy_from_user.S index a6ae2ea04bf5..3192b0bf4fab 100644 --- a/trunk/arch/sparc/lib/U1copy_from_user.S +++ b/trunk/arch/sparc/lib/U1copy_from_user.S @@ -5,9 +5,13 @@ #define EX_LD(x) \ 98: x; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_one; \ + .word 98b, 99b; \ .text; \ .align 4; @@ -23,7 +27,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, memcpy_user_stub; \ nop; \ #include "U1memcpy.S" diff --git a/trunk/arch/sparc/lib/U1copy_to_user.S b/trunk/arch/sparc/lib/U1copy_to_user.S index f4b970eeb485..d1210ffb0b82 100644 --- a/trunk/arch/sparc/lib/U1copy_to_user.S +++ b/trunk/arch/sparc/lib/U1copy_to_user.S @@ -5,9 +5,13 @@ #define EX_ST(x) \ 98: x; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_one; \ + .word 98b, 99b; \ .text; \ .align 4; @@ -23,7 +27,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, memcpy_user_stub; \ nop; \ #include "U1memcpy.S" diff --git a/trunk/arch/sparc/lib/U3copy_from_user.S b/trunk/arch/sparc/lib/U3copy_from_user.S index b1acd1331c33..f5bfc8d9d216 100644 --- a/trunk/arch/sparc/lib/U3copy_from_user.S +++ b/trunk/arch/sparc/lib/U3copy_from_user.S @@ -5,9 +5,13 @@ #define EX_LD(x) \ 98: x; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_one; \ + .word 98b, 99b; \ .text; \ .align 4; diff --git a/trunk/arch/sparc/lib/U3copy_to_user.S b/trunk/arch/sparc/lib/U3copy_to_user.S index ef1e493afdfa..2334f111bb0c 100644 --- a/trunk/arch/sparc/lib/U3copy_to_user.S +++ b/trunk/arch/sparc/lib/U3copy_to_user.S @@ -5,9 +5,13 @@ #define EX_ST(x) \ 98: x; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_one; \ + .word 98b, 99b; \ .text; \ .align 4; @@ -23,7 +27,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, memcpy_user_stub; \ nop; \ #include "U3memcpy.S" diff --git a/trunk/arch/sparc/lib/bzero.S b/trunk/arch/sparc/lib/bzero.S index b6557297440f..c7bbae8c590f 100644 --- a/trunk/arch/sparc/lib/bzero.S +++ b/trunk/arch/sparc/lib/bzero.S @@ -88,9 +88,13 @@ __bzero_done: #define EX_ST(x,y) \ 98: x,y; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov %o1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_o1; \ + .word 98b, 99b; \ .text; \ .align 4; diff --git a/trunk/arch/sparc/lib/copy_in_user.S b/trunk/arch/sparc/lib/copy_in_user.S index 302c0e60dc2c..650af3f21f78 100644 --- a/trunk/arch/sparc/lib/copy_in_user.S +++ b/trunk/arch/sparc/lib/copy_in_user.S @@ -3,16 +3,19 @@ * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) */ -#include #include #define XCC xcc #define EX(x,y) \ 98: x,y; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov 1, %o0; \ .section __ex_table,"a";\ .align 4; \ - .word 98b, __retl_one; \ + .word 98b, 99b; \ .text; \ .align 4; @@ -28,7 +31,18 @@ * to copy register windows around during thread cloning. */ -ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ + .globl ___copy_in_user + .type ___copy_in_user,#function +___copy_in_user: /* %o0=dst, %o1=src, %o2=len */ + /* Writing to %asi is _expensive_ so we hardcode it. + * Reading %asi to check for KERNEL_DS is comparatively + * cheap. + */ + rd %asi, %g1 + cmp %g1, ASI_AIUS + bne,pn %icc, memcpy_user_stub + nop + cmp %o2, 0 be,pn %XCC, 85f or %o0, %o1, %o3 @@ -39,24 +53,22 @@ ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ /* 16 < len <= 64 */ andcc %o3, 0x7, %g0 bne,pn %XCC, 90f - nop + sub %o0, %o1, %o3 andn %o2, 0x7, %o4 and %o2, 0x7, %o2 1: subcc %o4, 0x8, %o4 EX(ldxa [%o1] %asi, %o5) - EX(stxa %o5, [%o0] %asi) - add %o1, 0x8, %o1 + EX(stxa %o5, [%o1 + %o3] ASI_AIUS) bgu,pt %XCC, 1b - add %o0, 0x8, %o0 + add %o1, 0x8, %o1 andcc %o2, 0x4, %g0 be,pt %XCC, 1f nop sub %o2, 0x4, %o2 EX(lduwa [%o1] %asi, %o5) - EX(stwa %o5, [%o0] %asi) + EX(stwa %o5, [%o1 + %o3] ASI_AIUS) add %o1, 0x4, %o1 - add %o0, 0x4, %o0 1: cmp %o2, 0 be,pt %XCC, 85f nop @@ -66,15 +78,14 @@ ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ 80: /* 0 < len <= 16 */ andcc %o3, 0x3, %g0 bne,pn %XCC, 90f - nop + sub %o0, %o1, %o3 82: subcc %o2, 4, %o2 EX(lduwa [%o1] %asi, %g1) - EX(stwa %g1, [%o0] %asi) - add %o1, 4, %o1 + EX(stwa %g1, [%o1 + %o3] ASI_AIUS) bgu,pt %XCC, 82b - add %o0, 4, %o0 + add %o1, 4, %o1 85: retl clr %o0 @@ -83,10 +94,26 @@ ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ 90: subcc %o2, 1, %o2 EX(lduba [%o1] %asi, %g1) - EX(stba %g1, [%o0] %asi) - add %o1, 1, %o1 + EX(stba %g1, [%o1 + %o3] ASI_AIUS) bgu,pt %XCC, 90b - add %o0, 1, %o0 + add %o1, 1, %o1 retl clr %o0 -ENDPROC(___copy_in_user) + + .size ___copy_in_user, .-___copy_in_user + + /* Act like copy_{to,in}_user(), ie. return zero instead + * of original destination pointer. This is invoked when + * copy_{to,in}_user() finds that %asi is kernel space. + */ + .globl memcpy_user_stub + .type memcpy_user_stub,#function +memcpy_user_stub: + save %sp, -192, %sp + mov %i0, %o0 + mov %i1, %o1 + call memcpy + mov %i2, %o2 + ret + restore %g0, %g0, %o0 + .size memcpy_user_stub, .-memcpy_user_stub diff --git a/trunk/arch/sparc/mm/fault_64.c b/trunk/arch/sparc/mm/fault_64.c index 4ab8993b0863..a9e474bf6385 100644 --- a/trunk/arch/sparc/mm/fault_64.c +++ b/trunk/arch/sparc/mm/fault_64.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -225,30 +224,6 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, unhandled_fault (address, current, regs); } -static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs) -{ - static int times; - - if (times++ < 10) - printk(KERN_ERR "FAULT[%s:%d]: 32-bit process reports " - "64-bit TPC [%lx]\n", - current->comm, current->pid, - regs->tpc); - show_regs(regs); -} - -static void noinline bogus_32bit_fault_address(struct pt_regs *regs, - unsigned long addr) -{ - static int times; - - if (times++ < 10) - printk(KERN_ERR "FAULT[%s:%d]: 32-bit process " - "reports 64-bit fault address [%lx]\n", - current->comm, current->pid, addr); - show_regs(regs); -} - asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) { struct mm_struct *mm = current->mm; @@ -269,19 +244,6 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) (fault_code & FAULT_CODE_DTLB)) BUG(); - if (test_thread_flag(TIF_32BIT)) { - if (!(regs->tstate & TSTATE_PRIV)) { - if (unlikely((regs->tpc >> 32) != 0)) { - bogus_32bit_fault_tpc(regs); - goto intr_or_no_mm; - } - } - if (unlikely((address >> 32) != 0)) { - bogus_32bit_fault_address(regs, address); - goto intr_or_no_mm; - } - } - if (regs->tstate & TSTATE_PRIV) { unsigned long tpc = regs->tpc; @@ -302,6 +264,12 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) if (in_atomic() || !mm) goto intr_or_no_mm; + if (test_thread_flag(TIF_32BIT)) { + if (!(regs->tstate & TSTATE_PRIV)) + regs->tpc &= 0xffffffff; + address &= 0xffffffff; + } + if (!down_read_trylock(&mm->mmap_sem)) { if ((regs->tstate & TSTATE_PRIV) && !search_exception_tables(regs->tpc)) { diff --git a/trunk/arch/sparc/oprofile/init.c b/trunk/arch/sparc/oprofile/init.c index d172f86439b1..d6e170c074fc 100644 --- a/trunk/arch/sparc/oprofile/init.c +++ b/trunk/arch/sparc/oprofile/init.c @@ -13,57 +13,217 @@ #include #ifdef CONFIG_SPARC64 -#include -#include -#include -#include +#include +#include +#include +#include -static int profile_timer_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) +static int nmi_enabled; + +struct pcr_ops { + u64 (*read)(void); + void (*write)(u64); +}; +static const struct pcr_ops *pcr_ops; + +static u64 direct_pcr_read(void) { - struct die_args *args = (struct die_args *)data; - int ret = NOTIFY_DONE; + u64 val; - switch (val) { - case DIE_NMI: - oprofile_add_sample(args->regs, 0); - ret = NOTIFY_STOP; - break; - default: - break; - } - return ret; + read_pcr(val); + return val; +} + +static void direct_pcr_write(u64 val) +{ + write_pcr(val); } -static struct notifier_block profile_timer_exceptions_nb = { - .notifier_call = profile_timer_exceptions_notify, +static const struct pcr_ops direct_pcr_ops = { + .read = direct_pcr_read, + .write = direct_pcr_write, }; -static int timer_start(void) +static void n2_pcr_write(u64 val) { - if (register_die_notifier(&profile_timer_exceptions_nb)) - return 1; - nmi_adjust_hz(HZ); - return 0; + unsigned long ret; + + ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); + if (val != HV_EOK) + write_pcr(val); } +static const struct pcr_ops n2_pcr_ops = { + .read = direct_pcr_read, + .write = n2_pcr_write, +}; -static void timer_stop(void) +/* In order to commonize as much of the implementation as + * possible, we use PICH as our counter. Mostly this is + * to accomodate Niagara-1 which can only count insn cycles + * in PICH. + */ +static u64 picl_value(void) { - nmi_adjust_hz(1); - unregister_die_notifier(&profile_timer_exceptions_nb); - synchronize_sched(); /* Allow already-started NMIs to complete. */ + u32 delta = local_cpu_data().clock_tick / HZ; + + return ((u64)((0 - delta) & 0xffffffff)) << 32; } -static int op_nmi_timer_init(struct oprofile_operations *ops) +#define PCR_PIC_PRIV 0x00000001 /* PIC access is privileged */ +#define PCR_STRACE 0x00000002 /* Trace supervisor events */ +#define PCR_UTRACE 0x00000004 /* Trace user events */ +#define PCR_N2_HTRACE 0x00000008 /* Trace hypervisor events */ +#define PCR_N2_TOE_OV0 0x00000010 /* Trap if PIC 0 overflows */ +#define PCR_N2_TOE_OV1 0x00000020 /* Trap if PIC 1 overflows */ +#define PCR_N2_MASK0 0x00003fc0 +#define PCR_N2_MASK0_SHIFT 6 +#define PCR_N2_SL0 0x0003c000 +#define PCR_N2_SL0_SHIFT 14 +#define PCR_N2_OV0 0x00040000 +#define PCR_N2_MASK1 0x07f80000 +#define PCR_N2_MASK1_SHIFT 19 +#define PCR_N2_SL1 0x78000000 +#define PCR_N2_SL1_SHIFT 27 +#define PCR_N2_OV1 0x80000000 + +#define PCR_SUN4U_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE) +#define PCR_N2_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE | \ + PCR_N2_TOE_OV1 | \ + (2 << PCR_N2_SL1_SHIFT) | \ + (0xff << PCR_N2_MASK1_SHIFT)) + +static u64 pcr_enable = PCR_SUN4U_ENABLE; + +static void nmi_handler(struct pt_regs *regs) { - if (!nmi_usable) + pcr_ops->write(PCR_PIC_PRIV); + + if (nmi_enabled) { + oprofile_add_sample(regs, 0); + + write_pic(picl_value()); + pcr_ops->write(pcr_enable); + } +} + +/* We count "clock cycle" events in the lower 32-bit PIC. + * Then configure it such that it overflows every HZ, and thus + * generates a level 15 interrupt at that frequency. + */ +static void cpu_nmi_start(void *_unused) +{ + pcr_ops->write(PCR_PIC_PRIV); + write_pic(picl_value()); + + pcr_ops->write(pcr_enable); +} + +static void cpu_nmi_stop(void *_unused) +{ + pcr_ops->write(PCR_PIC_PRIV); +} + +static int nmi_start(void) +{ + int err = register_perfctr_intr(nmi_handler); + + if (!err) { + nmi_enabled = 1; + wmb(); + err = on_each_cpu(cpu_nmi_start, NULL, 1); + if (err) { + nmi_enabled = 0; + wmb(); + on_each_cpu(cpu_nmi_stop, NULL, 1); + release_perfctr_intr(nmi_handler); + } + } + + return err; +} + +static void nmi_stop(void) +{ + nmi_enabled = 0; + wmb(); + + on_each_cpu(cpu_nmi_stop, NULL, 1); + release_perfctr_intr(nmi_handler); + synchronize_sched(); +} + +static unsigned long perf_hsvc_group; +static unsigned long perf_hsvc_major; +static unsigned long perf_hsvc_minor; + +static int __init register_perf_hsvc(void) +{ + if (tlb_type == hypervisor) { + switch (sun4v_chip_type) { + case SUN4V_CHIP_NIAGARA1: + perf_hsvc_group = HV_GRP_NIAG_PERF; + break; + + case SUN4V_CHIP_NIAGARA2: + perf_hsvc_group = HV_GRP_N2_CPU; + break; + + default: + return -ENODEV; + } + + + perf_hsvc_major = 1; + perf_hsvc_minor = 0; + if (sun4v_hvapi_register(perf_hsvc_group, + perf_hsvc_major, + &perf_hsvc_minor)) { + printk("perfmon: Could not register N2 hvapi.\n"); + return -ENODEV; + } + } + return 0; +} + +static void unregister_perf_hsvc(void) +{ + if (tlb_type != hypervisor) + return; + sun4v_hvapi_unregister(perf_hsvc_group); +} + +static int oprofile_nmi_init(struct oprofile_operations *ops) +{ + int err = register_perf_hsvc(); + + if (err) + return err; + + switch (tlb_type) { + case hypervisor: + pcr_ops = &n2_pcr_ops; + pcr_enable = PCR_N2_ENABLE; + break; + + case cheetah: + case cheetah_plus: + pcr_ops = &direct_pcr_ops; + break; + + default: return -ENODEV; + } - ops->start = timer_start; - ops->stop = timer_stop; + ops->create_files = NULL; + ops->setup = NULL; + ops->shutdown = NULL; + ops->start = nmi_start; + ops->stop = nmi_stop; ops->cpu_type = "timer"; - printk(KERN_INFO "oprofile: Using perfctr NMI timer interrupt.\n"); + + printk(KERN_INFO "oprofile: Using perfctr based NMI timer interrupt.\n"); + return 0; } #endif @@ -73,7 +233,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) int ret = -ENODEV; #ifdef CONFIG_SPARC64 - ret = op_nmi_timer_init(ops); + ret = oprofile_nmi_init(ops); if (!ret) return ret; #endif @@ -81,6 +241,10 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) return ret; } + void oprofile_arch_exit(void) { +#ifdef CONFIG_SPARC64 + unregister_perf_hsvc(); +#endif } diff --git a/trunk/arch/um/drivers/vde_user.c b/trunk/arch/um/drivers/vde_user.c index c5c43253e6ce..56533db25343 100644 --- a/trunk/arch/um/drivers/vde_user.c +++ b/trunk/arch/um/drivers/vde_user.c @@ -78,7 +78,7 @@ void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init) { struct vde_open_args *args; - vpri->args = uml_kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL); + vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL); if (vpri->args == NULL) { printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args " "allocation failed"); @@ -91,8 +91,8 @@ void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init) args->group = init->group; args->mode = init->mode ? init->mode : 0700; - args->port ? printk("port %d", args->port) : - printk("undefined port"); + args->port ? printk(UM_KERN_INFO "port %d", args->port) : + printk(UM_KERN_INFO "undefined port"); } int vde_user_read(void *conn, void *buf, int len) diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index bc2fbadff9f9..73f7fe8fd4d1 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -1802,17 +1802,6 @@ config DMAR and include PCI device scope covered by these DMA remapping devices. -config DMAR_DEFAULT_ON - def_bool y - prompt "Enable DMA Remapping Devices by default" - depends on DMAR - help - Selecting this option will enable a DMAR device at boot time if - one is found. If this option is not selected, DMAR support can - be enabled by passing intel_iommu=on to the kernel. It is - recommended you say N here while the DMAR code remains - experimental. - config DMAR_GFX_WA def_bool y prompt "Support for Graphics workaround" diff --git a/trunk/arch/x86/Kconfig.cpu b/trunk/arch/x86/Kconfig.cpu index c98d52e82966..8078955845ae 100644 --- a/trunk/arch/x86/Kconfig.cpu +++ b/trunk/arch/x86/Kconfig.cpu @@ -167,9 +167,9 @@ config MK7 config MK8 bool "Opteron/Athlon64/Hammer/K8" help - Select this for an AMD Opteron or Athlon64 Hammer-family processor. - Enables use of some extended instructions, and passes appropriate - optimization flags to GCC. + Select this for an AMD Opteron or Athlon64 Hammer-family processor. Enables + use of some extended instructions, and passes appropriate optimization + flags to GCC. config MCRUSOE bool "Crusoe" @@ -256,11 +256,9 @@ config MPSC config MCORE2 bool "Core 2/newer Xeon" help - - Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and - 53xx) CPUs. You can distinguish newer from older Xeons by the CPU - family in /proc/cpuinfo. Newer ones have 6 and older ones 15 - (not a typo) + Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx) + CPUs. You can distinguish newer from older Xeons by the CPU family + in /proc/cpuinfo. Newer ones have 6 and older ones 15 (not a typo) config GENERIC_CPU bool "Generic-x86-64" @@ -322,14 +320,14 @@ config X86_PPRO_FENCE bool "PentiumPro memory ordering errata workaround" depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1 help - Old PentiumPro multiprocessor systems had errata that could cause - memory operations to violate the x86 ordering standard in rare cases. - Enabling this option will attempt to work around some (but not all) - occurances of this problem, at the cost of much heavier spinlock and - memory barrier operations. + Old PentiumPro multiprocessor systems had errata that could cause memory + operations to violate the x86 ordering standard in rare cases. Enabling this + option will attempt to work around some (but not all) occurances of + this problem, at the cost of much heavier spinlock and memory barrier + operations. - If unsure, say n here. Even distro kernels should think twice before - enabling this: there are few systems, and an unlikely bug. + If unsure, say n here. Even distro kernels should think twice before enabling + this: there are few systems, and an unlikely bug. config X86_F00F_BUG def_bool y diff --git a/trunk/arch/x86/Kconfig.debug b/trunk/arch/x86/Kconfig.debug index e1983fa025d2..10d6cc3fd052 100644 --- a/trunk/arch/x86/Kconfig.debug +++ b/trunk/arch/x86/Kconfig.debug @@ -174,8 +174,28 @@ config IOMMU_LEAK Add a simple leak tracer to the IOMMU code. This is useful when you are debugging a buggy device driver that leaks IOMMU mappings. -config HAVE_MMIOTRACE_SUPPORT - def_bool y +config MMIOTRACE + bool "Memory mapped IO tracing" + depends on DEBUG_KERNEL && PCI + select TRACING + help + Mmiotrace traces Memory Mapped I/O access and is meant for + debugging and reverse engineering. It is called from the ioremap + implementation and works via page faults. Tracing is disabled by + default and can be enabled at run-time. + + See Documentation/tracers/mmiotrace.txt. + If you are not helping to develop drivers, say N. + +config MMIOTRACE_TEST + tristate "Test module for mmiotrace" + depends on MMIOTRACE && m + help + This is a dumb module for testing mmiotrace. It is very dangerous + as it will write garbage to IO memory starting at a given address. + However, it should be safe to use on e.g. unused portion of VRAM. + + Say N, unless you absolutely know what you are doing. # # IO delay types: diff --git a/trunk/arch/x86/ia32/ia32entry.S b/trunk/arch/x86/ia32/ia32entry.S index 5a0d76dc56a4..256b00b61892 100644 --- a/trunk/arch/x86/ia32/ia32entry.S +++ b/trunk/arch/x86/ia32/ia32entry.S @@ -418,9 +418,9 @@ ENTRY(ia32_syscall) orl $TS_COMPAT,TI_status(%r10) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) jnz ia32_tracesys +ia32_do_syscall: cmpl $(IA32_NR_syscalls-1),%eax - ja ia32_badsys -ia32_do_call: + ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ IA32_ARG_FIXUP call *ia32_sys_call_table(,%rax,8) # xxx: rip relative ia32_sysret: @@ -435,9 +435,7 @@ ia32_tracesys: call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST - cmpl $(IA32_NR_syscalls-1),%eax - ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ - jmp ia32_do_call + jmp ia32_do_syscall END(ia32_syscall) ia32_badsys: diff --git a/trunk/arch/x86/include/asm/a.out-core.h b/trunk/arch/x86/include/asm/a.out-core.h index 3c601f8224be..37822206083e 100644 --- a/trunk/arch/x86/include/asm/a.out-core.h +++ b/trunk/arch/x86/include/asm/a.out-core.h @@ -23,6 +23,8 @@ */ static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump) { + u16 gs; + /* changed the size calculations - should hopefully work better. lbt */ dump->magic = CMAGIC; dump->start_code = 0; @@ -55,7 +57,7 @@ static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump) dump->regs.ds = (u16)regs->ds; dump->regs.es = (u16)regs->es; dump->regs.fs = (u16)regs->fs; - savesegment(gs, dump->regs.gs); + savesegment(gs, gs); dump->regs.orig_ax = regs->orig_ax; dump->regs.ip = regs->ip; dump->regs.cs = (u16)regs->cs; diff --git a/trunk/arch/x86/include/asm/cpufeature.h b/trunk/arch/x86/include/asm/cpufeature.h index 7301e60dc4a8..ea408dcba513 100644 --- a/trunk/arch/x86/include/asm/cpufeature.h +++ b/trunk/arch/x86/include/asm/cpufeature.h @@ -93,7 +93,6 @@ #define X86_FEATURE_XTOPOLOGY (3*32+22) /* cpu topology enum extensions */ #define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */ #define X86_FEATURE_NONSTOP_TSC (3*32+24) /* TSC does not stop in C states */ -#define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ diff --git a/trunk/arch/x86/include/asm/iomap.h b/trunk/arch/x86/include/asm/iomap.h index 86af26091d6c..c1f06289b14b 100644 --- a/trunk/arch/x86/include/asm/iomap.h +++ b/trunk/arch/x86/include/asm/iomap.h @@ -23,9 +23,6 @@ #include #include -int -is_io_mapping_possible(resource_size_t base, unsigned long size); - void * iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); diff --git a/trunk/arch/x86/include/asm/kvm.h b/trunk/arch/x86/include/asm/kvm.h index 886c9402ec45..d2e3bf3608af 100644 --- a/trunk/arch/x86/include/asm/kvm.h +++ b/trunk/arch/x86/include/asm/kvm.h @@ -9,13 +9,6 @@ #include #include -/* Select x86 specific features in */ -#define __KVM_HAVE_PIT -#define __KVM_HAVE_IOAPIC -#define __KVM_HAVE_DEVICE_ASSIGNMENT -#define __KVM_HAVE_MSI -#define __KVM_HAVE_USER_NMI - /* Architectural interrupt line count. */ #define KVM_NR_INTERRUPTS 256 diff --git a/trunk/arch/x86/include/asm/math_emu.h b/trunk/arch/x86/include/asm/math_emu.h index 031f6266f425..5a65b107ad58 100644 --- a/trunk/arch/x86/include/asm/math_emu.h +++ b/trunk/arch/x86/include/asm/math_emu.h @@ -1,18 +1,31 @@ #ifndef _ASM_X86_MATH_EMU_H #define _ASM_X86_MATH_EMU_H -#include -#include - /* This structure matches the layout of the data saved to the stack following a device-not-present interrupt, part of it saved automatically by the 80386/80486. */ -struct math_emu_info { +struct info { long ___orig_eip; - union { - struct pt_regs *regs; - struct kernel_vm86_regs *vm86; - }; + long ___ebx; + long ___ecx; + long ___edx; + long ___esi; + long ___edi; + long ___ebp; + long ___eax; + long ___ds; + long ___es; + long ___fs; + long ___orig_eax; + long ___eip; + long ___cs; + long ___eflags; + long ___esp; + long ___ss; + long ___vm86_es; /* This and the following only in vm86 mode */ + long ___vm86_ds; + long ___vm86_fs; + long ___vm86_gs; }; #endif /* _ASM_X86_MATH_EMU_H */ diff --git a/trunk/arch/x86/include/asm/mmzone_32.h b/trunk/arch/x86/include/asm/mmzone_32.h index 105fb90a0635..07f1af494ca5 100644 --- a/trunk/arch/x86/include/asm/mmzone_32.h +++ b/trunk/arch/x86/include/asm/mmzone_32.h @@ -32,6 +32,8 @@ static inline void get_memcfg_numa(void) get_memcfg_numa_flat(); } +extern int early_pfn_to_nid(unsigned long pfn); + extern void resume_map_numa_kva(pgd_t *pgd); #else /* !CONFIG_NUMA */ diff --git a/trunk/arch/x86/include/asm/mmzone_64.h b/trunk/arch/x86/include/asm/mmzone_64.h index a29f48c2a322..a5b3817d4b9e 100644 --- a/trunk/arch/x86/include/asm/mmzone_64.h +++ b/trunk/arch/x86/include/asm/mmzone_64.h @@ -40,6 +40,8 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr) #define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \ NODE_DATA(nid)->node_spanned_pages) +extern int early_pfn_to_nid(unsigned long pfn); + #ifdef CONFIG_NUMA_EMU #define FAKE_NODE_MIN_SIZE (64 * 1024 * 1024) #define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL)) diff --git a/trunk/arch/x86/include/asm/mpspec.h b/trunk/arch/x86/include/asm/mpspec.h index bd22f2a3713f..62d14ce3cd00 100644 --- a/trunk/arch/x86/include/asm/mpspec.h +++ b/trunk/arch/x86/include/asm/mpspec.h @@ -60,7 +60,6 @@ extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi); extern void mp_config_acpi_legacy_irqs(void); extern int mp_register_gsi(u32 gsi, int edge_level, int active_high_low); -extern int acpi_probe_gsi(void); #ifdef CONFIG_X86_IO_APIC extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin, u32 gsi, int triggering, int polarity); @@ -72,11 +71,6 @@ mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin, return 0; } #endif -#else /* !CONFIG_ACPI: */ -static inline int acpi_probe_gsi(void) -{ - return 0; -} #endif /* CONFIG_ACPI */ #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) diff --git a/trunk/arch/x86/include/asm/page.h b/trunk/arch/x86/include/asm/page.h index 776579119a00..e9873a2e8695 100644 --- a/trunk/arch/x86/include/asm/page.h +++ b/trunk/arch/x86/include/asm/page.h @@ -57,6 +57,7 @@ typedef struct { pgdval_t pgd; } pgd_t; typedef struct { pgprotval_t pgprot; } pgprot_t; extern int page_is_ram(unsigned long pagenr); +extern int pagerange_is_ram(unsigned long start, unsigned long end); extern int devmem_is_allowed(unsigned long pagenr); extern void map_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot); diff --git a/trunk/arch/x86/include/asm/paravirt.h b/trunk/arch/x86/include/asm/paravirt.h index e299287e8e33..ba3e2ff6aedc 100644 --- a/trunk/arch/x86/include/asm/paravirt.h +++ b/trunk/arch/x86/include/asm/paravirt.h @@ -1352,7 +1352,14 @@ static inline void arch_leave_lazy_cpu_mode(void) PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave); } -void arch_flush_lazy_cpu_mode(void); +static inline void arch_flush_lazy_cpu_mode(void) +{ + if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)) { + arch_leave_lazy_cpu_mode(); + arch_enter_lazy_cpu_mode(); + } +} + #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE static inline void arch_enter_lazy_mmu_mode(void) @@ -1365,7 +1372,13 @@ static inline void arch_leave_lazy_mmu_mode(void) PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); } -void arch_flush_lazy_mmu_mode(void); +static inline void arch_flush_lazy_mmu_mode(void) +{ + if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU)) { + arch_leave_lazy_mmu_mode(); + arch_enter_lazy_mmu_mode(); + } +} static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, unsigned long phys, pgprot_t flags) @@ -1389,7 +1402,6 @@ static inline int __raw_spin_is_contended(struct raw_spinlock *lock) { return PVOP_CALL1(int, pv_lock_ops.spin_is_contended, lock); } -#define __raw_spin_is_contended __raw_spin_is_contended static __always_inline void __raw_spin_lock(struct raw_spinlock *lock) { diff --git a/trunk/arch/x86/include/asm/pgtable.h b/trunk/arch/x86/include/asm/pgtable.h index 4f5af8447d54..06bbcbd66e9c 100644 --- a/trunk/arch/x86/include/asm/pgtable.h +++ b/trunk/arch/x86/include/asm/pgtable.h @@ -302,30 +302,16 @@ static inline pte_t pte_mkspecial(pte_t pte) extern pteval_t __supported_pte_mask; -/* - * Mask out unsupported bits in a present pgprot. Non-present pgprots - * can use those bits for other purposes, so leave them be. - */ -static inline pgprotval_t massage_pgprot(pgprot_t pgprot) -{ - pgprotval_t protval = pgprot_val(pgprot); - - if (protval & _PAGE_PRESENT) - protval &= __supported_pte_mask; - - return protval; -} - static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) { - return __pte(((phys_addr_t)page_nr << PAGE_SHIFT) | - massage_pgprot(pgprot)); + return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) | + pgprot_val(pgprot)) & __supported_pte_mask); } static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) { - return __pmd(((phys_addr_t)page_nr << PAGE_SHIFT) | - massage_pgprot(pgprot)); + return __pmd((((phys_addr_t)page_nr << PAGE_SHIFT) | + pgprot_val(pgprot)) & __supported_pte_mask); } static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) @@ -337,7 +323,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) * the newprot (if present): */ val &= _PAGE_CHG_MASK; - val |= massage_pgprot(newprot) & ~_PAGE_CHG_MASK; + val |= pgprot_val(newprot) & (~_PAGE_CHG_MASK) & __supported_pte_mask; return __pte(val); } @@ -353,7 +339,7 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) #define pte_pgprot(x) __pgprot(pte_flags(x) & PTE_FLAGS_MASK) -#define canon_pgprot(p) __pgprot(massage_pgprot(p)) +#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask) static inline int is_new_memtype_allowed(unsigned long flags, unsigned long new_flags) diff --git a/trunk/arch/x86/include/asm/processor.h b/trunk/arch/x86/include/asm/processor.h index 3bfd5235a9eb..091cd8855f2e 100644 --- a/trunk/arch/x86/include/asm/processor.h +++ b/trunk/arch/x86/include/asm/processor.h @@ -353,7 +353,7 @@ struct i387_soft_struct { u8 no_update; u8 rm; u8 alimit; - struct math_emu_info *info; + struct info *info; u32 entry_eip; }; diff --git a/trunk/arch/x86/include/asm/seccomp_32.h b/trunk/arch/x86/include/asm/seccomp_32.h index b811d6f5780c..a6ad87b352c4 100644 --- a/trunk/arch/x86/include/asm/seccomp_32.h +++ b/trunk/arch/x86/include/asm/seccomp_32.h @@ -1,6 +1,12 @@ #ifndef _ASM_X86_SECCOMP_32_H #define _ASM_X86_SECCOMP_32_H +#include + +#ifdef TIF_32BIT +#error "unexpected TIF_32BIT on i386" +#endif + #include #define __NR_seccomp_read __NR_read diff --git a/trunk/arch/x86/include/asm/seccomp_64.h b/trunk/arch/x86/include/asm/seccomp_64.h index 84ec1bd161a5..4171bb794e9e 100644 --- a/trunk/arch/x86/include/asm/seccomp_64.h +++ b/trunk/arch/x86/include/asm/seccomp_64.h @@ -1,6 +1,14 @@ #ifndef _ASM_X86_SECCOMP_64_H #define _ASM_X86_SECCOMP_64_H +#include + +#ifdef TIF_32BIT +#error "unexpected TIF_32BIT on x86_64" +#else +#define TIF_32BIT TIF_IA32 +#endif + #include #include diff --git a/trunk/arch/x86/include/asm/spinlock.h b/trunk/arch/x86/include/asm/spinlock.h index 8247e94ac6b1..d17c91981da2 100644 --- a/trunk/arch/x86/include/asm/spinlock.h +++ b/trunk/arch/x86/include/asm/spinlock.h @@ -245,7 +245,6 @@ static inline int __raw_spin_is_contended(raw_spinlock_t *lock) { return __ticket_spin_is_contended(lock); } -#define __raw_spin_is_contended __raw_spin_is_contended static __always_inline void __raw_spin_lock(raw_spinlock_t *lock) { diff --git a/trunk/arch/x86/include/asm/traps.h b/trunk/arch/x86/include/asm/traps.h index cf3bb053da0b..2ee0a3bceedf 100644 --- a/trunk/arch/x86/include/asm/traps.h +++ b/trunk/arch/x86/include/asm/traps.h @@ -41,7 +41,7 @@ dotraplinkage void do_int3(struct pt_regs *, long); dotraplinkage void do_overflow(struct pt_regs *, long); dotraplinkage void do_bounds(struct pt_regs *, long); dotraplinkage void do_invalid_op(struct pt_regs *, long); -dotraplinkage void do_device_not_available(struct pt_regs); +dotraplinkage void do_device_not_available(struct pt_regs *, long); dotraplinkage void do_coprocessor_segment_overrun(struct pt_regs *, long); dotraplinkage void do_invalid_TSS(struct pt_regs *, long); dotraplinkage void do_segment_not_present(struct pt_regs *, long); @@ -77,7 +77,7 @@ extern int panic_on_unrecovered_nmi; extern int kstack_depth_to_print; void math_error(void __user *); -void math_emulate(struct math_emu_info *); +asmlinkage void math_emulate(long); #ifdef CONFIG_X86_32 unsigned long patch_espfix_desc(unsigned long, unsigned long); #else diff --git a/trunk/arch/x86/include/asm/xen/page.h b/trunk/arch/x86/include/asm/xen/page.h index 4bd990ee43df..7ef617ef1df3 100644 --- a/trunk/arch/x86/include/asm/xen/page.h +++ b/trunk/arch/x86/include/asm/xen/page.h @@ -137,7 +137,7 @@ static inline pte_t mfn_pte(unsigned long page_nr, pgprot_t pgprot) pte_t pte; pte.pte = ((phys_addr_t)page_nr << PAGE_SHIFT) | - massage_pgprot(pgprot); + (pgprot_val(pgprot) & __supported_pte_mask); return pte; } diff --git a/trunk/arch/x86/kernel/acpi/boot.c b/trunk/arch/x86/kernel/acpi/boot.c index 7678f10c4568..d37593c2f438 100644 --- a/trunk/arch/x86/kernel/acpi/boot.c +++ b/trunk/arch/x86/kernel/acpi/boot.c @@ -973,29 +973,6 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) nr_ioapics++; } -int __init acpi_probe_gsi(void) -{ - int idx; - int gsi; - int max_gsi = 0; - - if (acpi_disabled) - return 0; - - if (!acpi_ioapic) - return 0; - - max_gsi = 0; - for (idx = 0; idx < nr_ioapics; idx++) { - gsi = mp_ioapic_routing[idx].gsi_end; - - if (gsi > max_gsi) - max_gsi = gsi; - } - - return max_gsi + 1; -} - static void assign_to_mp_irq(struct mp_config_intsrc *m, struct mp_config_intsrc *mp_irq) { diff --git a/trunk/arch/x86/kernel/acpi/sleep.c b/trunk/arch/x86/kernel/acpi/sleep.c index a60c1f3bcb87..707c1f6f95fa 100644 --- a/trunk/arch/x86/kernel/acpi/sleep.c +++ b/trunk/arch/x86/kernel/acpi/sleep.c @@ -156,11 +156,11 @@ static int __init acpi_sleep_setup(char *str) #ifdef CONFIG_HIBERNATION if (strncmp(str, "s4_nohwsig", 10) == 0) acpi_no_s4_hw_signature(); - if (strncmp(str, "s4_nonvs", 8) == 0) - acpi_s4_no_nvs(); #endif if (strncmp(str, "old_ordering", 12) == 0) acpi_old_suspend_ordering(); + if (strncmp(str, "s4_nonvs", 8) == 0) + acpi_s4_no_nvs(); str = strchr(str, ','); if (str != NULL) str += strspn(str, ", \t"); diff --git a/trunk/arch/x86/kernel/acpi/wakeup_64.S b/trunk/arch/x86/kernel/acpi/wakeup_64.S index 96258d9dc974..bcc293423a70 100644 --- a/trunk/arch/x86/kernel/acpi/wakeup_64.S +++ b/trunk/arch/x86/kernel/acpi/wakeup_64.S @@ -13,6 +13,7 @@ * Hooray, we are in Long 64-bit mode (but still running in low memory) */ ENTRY(wakeup_long64) +wakeup_long64: movq saved_magic, %rax movq $0x123456789abcdef0, %rdx cmpq %rdx, %rax @@ -33,12 +34,16 @@ ENTRY(wakeup_long64) movq saved_rip, %rax jmp *%rax -ENDPROC(wakeup_long64) bogus_64_magic: jmp bogus_64_magic -ENTRY(do_suspend_lowlevel) + .align 2 + .p2align 4,,15 +.globl do_suspend_lowlevel + .type do_suspend_lowlevel,@function +do_suspend_lowlevel: +.LFB5: subq $8, %rsp xorl %eax, %eax call save_processor_state @@ -62,7 +67,7 @@ ENTRY(do_suspend_lowlevel) pushfq popq pt_regs_flags(%rax) - movq $resume_point, saved_rip(%rip) + movq $.L97, saved_rip(%rip) movq %rsp, saved_rsp movq %rbp, saved_rbp @@ -73,12 +78,14 @@ ENTRY(do_suspend_lowlevel) addq $8, %rsp movl $3, %edi xorl %eax, %eax - call acpi_enter_sleep_state - /* in case something went wrong, restore the machine status and go on */ - jmp resume_point - + jmp acpi_enter_sleep_state +.L97: + .p2align 4,,7 +.L99: .align 4 -resume_point: + movl $24, %eax + movw %ax, %ds + /* We don't restore %rax, it must be 0 anyway */ movq $saved_context, %rax movq saved_context_cr4(%rax), %rbx @@ -110,9 +117,12 @@ resume_point: xorl %eax, %eax addq $8, %rsp jmp restore_processor_state -ENDPROC(do_suspend_lowlevel) - +.LFE5: +.Lfe5: + .size do_suspend_lowlevel, .Lfe5-do_suspend_lowlevel + .data +ALIGN ENTRY(saved_rbp) .quad 0 ENTRY(saved_rsi) .quad 0 ENTRY(saved_rdi) .quad 0 diff --git a/trunk/arch/x86/kernel/apic.c b/trunk/arch/x86/kernel/apic.c index 570f36e44e59..4b6df2469fe3 100644 --- a/trunk/arch/x86/kernel/apic.c +++ b/trunk/arch/x86/kernel/apic.c @@ -862,7 +862,7 @@ void clear_local_APIC(void) } /* lets not touch this if we didn't frob it */ -#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) +#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(X86_MCE_INTEL) if (maxlvt >= 5) { v = apic_read(APIC_LVTTHMR); apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); @@ -1436,7 +1436,7 @@ static int __init detect_init_APIC(void) switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) || - (boot_cpu_data.x86 >= 15)) + (boot_cpu_data.x86 == 15)) break; goto no_apic; case X86_VENDOR_INTEL: diff --git a/trunk/arch/x86/kernel/apm_32.c b/trunk/arch/x86/kernel/apm_32.c index 266ec6c18b6c..98807bb095ad 100644 --- a/trunk/arch/x86/kernel/apm_32.c +++ b/trunk/arch/x86/kernel/apm_32.c @@ -1192,7 +1192,6 @@ static int suspend(int vetoable) device_suspend(PMSG_SUSPEND); local_irq_disable(); device_power_down(PMSG_SUSPEND); - sysdev_suspend(PMSG_SUSPEND); local_irq_enable(); @@ -1209,7 +1208,6 @@ static int suspend(int vetoable) if (err != APM_SUCCESS) apm_error("suspend", err); err = (err == APM_SUCCESS) ? 0 : -EIO; - sysdev_resume(); device_power_up(PMSG_RESUME); local_irq_enable(); device_resume(PMSG_RESUME); @@ -1230,7 +1228,6 @@ static void standby(void) local_irq_disable(); device_power_down(PMSG_SUSPEND); - sysdev_suspend(PMSG_SUSPEND); local_irq_enable(); err = set_system_power_state(APM_STATE_STANDBY); @@ -1238,7 +1235,6 @@ static void standby(void) apm_error("standby", err); local_irq_disable(); - sysdev_resume(); device_power_up(PMSG_RESUME); local_irq_enable(); } diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig b/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig index 65792c2cc462..efae3b22a0ff 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig +++ b/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig @@ -245,6 +245,17 @@ config X86_E_POWERSAVER comment "shared options" +config X86_ACPI_CPUFREQ_PROC_INTF + bool "/proc/acpi/processor/../performance interface (deprecated)" + depends on PROC_FS + depends on X86_ACPI_CPUFREQ || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI + help + This enables the deprecated /proc/acpi/processor/../performance + interface. While it is helpful for debugging, the generic, + cross-architecture cpufreq interfaces should be used. + + If in doubt, say N. + config X86_SPEEDSTEP_LIB tristate default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 6428aa17b40e..5c28b37dea11 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -939,25 +939,10 @@ static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) free_cpumask_var(data->acpi_data.shared_cpu_map); } -static int get_transition_latency(struct powernow_k8_data *data) -{ - int max_latency = 0; - int i; - for (i = 0; i < data->acpi_data.state_count; i++) { - int cur_latency = data->acpi_data.states[i].transition_latency - + data->acpi_data.states[i].bus_master_latency; - if (cur_latency > max_latency) - max_latency = cur_latency; - } - /* value in usecs, needs to be in nanoseconds */ - return 1000 * max_latency; -} - #else static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; } static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; } static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; } -static int get_transition_latency(struct powernow_k8_data *data) { return 0; } #endif /* CONFIG_X86_POWERNOW_K8_ACPI */ /* Take a frequency, and issue the fid/vid transition command */ @@ -1157,7 +1142,8 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) data->cpu = pol->cpu; data->currpstate = HW_PSTATE_INVALID; - if (powernow_k8_cpu_init_acpi(data)) { + rc = powernow_k8_cpu_init_acpi(data); + if (rc) { /* * Use the PSB BIOS structure. This is only availabe on * an UP version, and is deprecated by AMD. @@ -1175,28 +1161,19 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) "ACPI maintainers and complain to your BIOS " "vendor.\n"); #endif - kfree(data); - return -ENODEV; + goto err_out; } if (pol->cpu != 0) { printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " "CPU other than CPU0. Complain to your BIOS " "vendor.\n"); - kfree(data); - return -ENODEV; + goto err_out; } rc = find_psb_table(data); if (rc) { - kfree(data); - return -ENODEV; + goto err_out; } - /* Take a crude guess here. - * That guess was in microseconds, so multiply with 1000 */ - pol->cpuinfo.transition_latency = ( - ((data->rvo + 8) * data->vstable * VST_UNITS_20US) + - ((1 << data->irt) * 30)) * 1000; - } else /* ACPI _PSS objects available */ - pol->cpuinfo.transition_latency = get_transition_latency(data); + } /* only run on specific CPU from here on */ oldmask = current->cpus_allowed; @@ -1227,6 +1204,11 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu)); data->available_cores = pol->cpus; + /* Take a crude guess here. + * That guess was in microseconds, so multiply with 1000 */ + pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) + + (3 * (1 << data->irt) * 10)) * 1000; + if (cpu_family == CPU_HW_PSTATE) pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); else diff --git a/trunk/arch/x86/kernel/cpu/intel.c b/trunk/arch/x86/kernel/cpu/intel.c index 24ff26a38ade..430e5c38a544 100644 --- a/trunk/arch/x86/kernel/cpu/intel.c +++ b/trunk/arch/x86/kernel/cpu/intel.c @@ -291,9 +291,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) ds_init_intel(c); } - if (c->x86 == 6 && c->x86_model == 29 && cpu_has_clflush) - set_cpu_cap(c, X86_FEATURE_CLFLUSH_MONITOR); - #ifdef CONFIG_X86_64 if (c->x86 == 15) c->x86_cache_alignment = c->x86_clflush_size * 2; diff --git a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c index da299eb85fc0..48533d77be78 100644 --- a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -36,11 +36,8 @@ static struct _cache_table cache_table[] __cpuinitdata = { { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ - { 0x09, LVL_1_INST, 32 }, /* 4-way set assoc, 64 byte line size */ { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */ { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */ - { 0x0d, LVL_1_DATA, 16 }, /* 4-way set assoc, 64 byte line size */ - { 0x21, LVL_2, 256 }, /* 8-way set assoc, 64 byte line size */ { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */ { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */ @@ -88,18 +85,6 @@ static struct _cache_table cache_table[] __cpuinitdata = { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */ { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */ { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */ - { 0xd0, LVL_3, 512 }, /* 4-way set assoc, 64 byte line size */ - { 0xd1, LVL_3, 1024 }, /* 4-way set assoc, 64 byte line size */ - { 0xd2, LVL_3, 2048 }, /* 4-way set assoc, 64 byte line size */ - { 0xd6, LVL_3, 1024 }, /* 8-way set assoc, 64 byte line size */ - { 0xd7, LVL_3, 2038 }, /* 8-way set assoc, 64 byte line size */ - { 0xd8, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */ - { 0xdc, LVL_3, 2048 }, /* 12-way set assoc, 64 byte line size */ - { 0xdd, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */ - { 0xde, LVL_3, 8192 }, /* 12-way set assoc, 64 byte line size */ - { 0xe2, LVL_3, 2048 }, /* 16-way set assoc, 64 byte line size */ - { 0xe3, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */ - { 0xe4, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */ { 0x00, 0, 0} }; diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c index fe79985ce0f2..1c838032fd37 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -295,11 +295,11 @@ void do_machine_check(struct pt_regs * regs, long error_code) * If we know that the error was in user space, send a * SIGBUS. Otherwise, panic if tolerance is low. * - * force_sig() takes an awful lot of locks and has a slight + * do_exit() takes an awful lot of locks and has a slight * risk of deadlocking. */ if (user_space) { - force_sig(SIGBUS, current); + do_exit(SIGBUS); } else if (panic_on_oops || tolerant < 2) { mce_panic("Uncorrected machine check", &panicm, mcestart); @@ -490,7 +490,7 @@ static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) } -static void mce_cpu_features(struct cpuinfo_x86 *c) +static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) { switch (c->x86_vendor) { case X86_VENDOR_INTEL: @@ -734,7 +734,6 @@ __setup("mce=", mcheck_enable); static int mce_resume(struct sys_device *dev) { mce_init(NULL); - mce_cpu_features(¤t_cpu_data); return 0; } diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index f2ee0ae29bd6..8ae8c4ff094d 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_amd_64.c @@ -121,7 +121,7 @@ static long threshold_restart_bank(void *_tr) } /* cpu init entry point, called from mce.c with preempt off */ -void mce_amd_feature_init(struct cpuinfo_x86 *c) +void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) { unsigned int bank, block; unsigned int cpu = smp_processor_id(); diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index f44c36624360..4b48f251fd39 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c @@ -30,7 +30,7 @@ asmlinkage void smp_thermal_interrupt(void) irq_exit(); } -static void intel_init_thermal(struct cpuinfo_x86 *c) +static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) { u32 l, h; int tm2 = 0; @@ -84,7 +84,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) return; } -void mce_intel_feature_init(struct cpuinfo_x86 *c) +void __cpuinit mce_intel_feature_init(struct cpuinfo_x86 *c) { intel_init_thermal(c); } diff --git a/trunk/arch/x86/kernel/entry_64.S b/trunk/arch/x86/kernel/entry_64.S index a1346217e43c..e28c7a987793 100644 --- a/trunk/arch/x86/kernel/entry_64.S +++ b/trunk/arch/x86/kernel/entry_64.S @@ -346,7 +346,6 @@ ENTRY(save_args) popq_cfi %rax /* move return address... */ mov %gs:pda_irqstackptr,%rsp EMPTY_FRAME 0 - pushq_cfi %rbp /* backlink for unwinder */ pushq_cfi %rax /* ... to the new stack */ /* * We entered an interrupt context - irqs are off: diff --git a/trunk/arch/x86/kernel/ftrace.c b/trunk/arch/x86/kernel/ftrace.c index 231bdd3c5b1c..1b43086b097a 100644 --- a/trunk/arch/x86/kernel/ftrace.c +++ b/trunk/arch/x86/kernel/ftrace.c @@ -488,21 +488,20 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) * ignore such a protection. */ asm volatile( - "1: " _ASM_MOV " (%[parent]), %[old]\n" - "2: " _ASM_MOV " %[return_hooker], (%[parent])\n" + "1: " _ASM_MOV " (%[parent_old]), %[old]\n" + "2: " _ASM_MOV " %[return_hooker], (%[parent_replaced])\n" " movl $0, %[faulted]\n" - "3:\n" ".section .fixup, \"ax\"\n" - "4: movl $1, %[faulted]\n" - " jmp 3b\n" + "3: movl $1, %[faulted]\n" ".previous\n" - _ASM_EXTABLE(1b, 4b) - _ASM_EXTABLE(2b, 4b) + _ASM_EXTABLE(1b, 3b) + _ASM_EXTABLE(2b, 3b) - : [old] "=r" (old), [faulted] "=r" (faulted) - : [parent] "r" (parent), [return_hooker] "r" (return_hooker) + : [parent_replaced] "=r" (parent), [old] "=r" (old), + [faulted] "=r" (faulted) + : [parent_old] "0" (parent), [return_hooker] "r" (return_hooker) : "memory" ); diff --git a/trunk/arch/x86/kernel/hpet.c b/trunk/arch/x86/kernel/hpet.c index a00545fe5cdd..64d5ad0b8add 100644 --- a/trunk/arch/x86/kernel/hpet.c +++ b/trunk/arch/x86/kernel/hpet.c @@ -269,8 +269,6 @@ static void hpet_set_mode(enum clock_event_mode mode, now = hpet_readl(HPET_COUNTER); cmp = now + (unsigned long) delta; cfg = hpet_readl(HPET_Tn_CFG(timer)); - /* Make sure we use edge triggered interrupts */ - cfg &= ~HPET_TN_LEVEL; cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | HPET_TN_32BIT; hpet_writel(cfg, HPET_Tn_CFG(timer)); @@ -899,21 +897,13 @@ static unsigned long hpet_rtc_flags; static int hpet_prev_update_sec; static struct rtc_time hpet_alarm_time; static unsigned long hpet_pie_count; -static u32 hpet_t1_cmp; +static unsigned long hpet_t1_cmp; static unsigned long hpet_default_delta; static unsigned long hpet_pie_delta; static unsigned long hpet_pie_limit; static rtc_irq_handler irq_handler; -/* - * Check that the hpet counter c1 is ahead of the c2 - */ -static inline int hpet_cnt_ahead(u32 c1, u32 c2) -{ - return (s32)(c2 - c1) < 0; -} - /* * Registers a IRQ handler. */ @@ -1085,7 +1075,7 @@ static void hpet_rtc_timer_reinit(void) hpet_t1_cmp += delta; hpet_writel(hpet_t1_cmp, HPET_T1_CMP); lost_ints++; - } while (!hpet_cnt_ahead(hpet_t1_cmp, hpet_readl(HPET_COUNTER))); + } while ((long)(hpet_readl(HPET_COUNTER) - hpet_t1_cmp) > 0); if (lost_ints) { if (hpet_rtc_flags & RTC_PIE) diff --git a/trunk/arch/x86/kernel/i8237.c b/trunk/arch/x86/kernel/i8237.c index b42ca694dc68..dbd6c1d1b638 100644 --- a/trunk/arch/x86/kernel/i8237.c +++ b/trunk/arch/x86/kernel/i8237.c @@ -28,10 +28,10 @@ static int i8237A_resume(struct sys_device *dev) flags = claim_dma_lock(); - dma_outb(0, DMA1_RESET_REG); - dma_outb(0, DMA2_RESET_REG); + dma_outb(DMA1_RESET_REG, 0); + dma_outb(DMA2_RESET_REG, 0); - for (i = 0; i < 8; i++) { + for (i = 0;i < 8;i++) { set_dma_addr(i, 0x000000); /* DMA count is a bit weird so this is not 0 */ set_dma_count(i, 1); @@ -51,14 +51,14 @@ static int i8237A_suspend(struct sys_device *dev, pm_message_t state) } static struct sysdev_class i8237_sysdev_class = { - .name = "i8237", - .suspend = i8237A_suspend, - .resume = i8237A_resume, + .name = "i8237", + .suspend = i8237A_suspend, + .resume = i8237A_resume, }; static struct sys_device device_i8237A = { - .id = 0, - .cls = &i8237_sysdev_class, + .id = 0, + .cls = &i8237_sysdev_class, }; static int __init i8237A_init_sysfs(void) @@ -68,4 +68,5 @@ static int __init i8237A_init_sysfs(void) error = sysdev_register(&device_i8237A); return error; } + device_initcall(i8237A_init_sysfs); diff --git a/trunk/arch/x86/kernel/io_apic.c b/trunk/arch/x86/kernel/io_apic.c index bc7ac4da90d7..1c4a1302536c 100644 --- a/trunk/arch/x86/kernel/io_apic.c +++ b/trunk/arch/x86/kernel/io_apic.c @@ -2528,15 +2528,14 @@ static void irq_complete_move(struct irq_desc **descp) vector = ~get_irq_regs()->orig_ax; me = smp_processor_id(); - - if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) { #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC *descp = desc = move_irq_desc(desc, me); /* get the new one */ cfg = desc->chip_data; #endif + + if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) send_cleanup_vector(cfg); - } } #else static inline void irq_complete_move(struct irq_desc **descp) {} @@ -3841,24 +3840,14 @@ int __init io_apic_get_redir_entries (int ioapic) void __init probe_nr_irqs_gsi(void) { + int idx; int nr = 0; - nr = acpi_probe_gsi(); - if (nr > nr_irqs_gsi) { - nr_irqs_gsi = nr; - } else { - /* for acpi=off or acpi is not compiled in */ - int idx; + for (idx = 0; idx < nr_ioapics; idx++) + nr += io_apic_get_redir_entries(idx) + 1; - nr = 0; - for (idx = 0; idx < nr_ioapics; idx++) - nr += io_apic_get_redir_entries(idx) + 1; - - if (nr > nr_irqs_gsi) - nr_irqs_gsi = nr; - } - - printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); + if (nr > nr_irqs_gsi) + nr_irqs_gsi = nr; } /* -------------------------------------------------------------------------- diff --git a/trunk/arch/x86/kernel/irqinit_32.c b/trunk/arch/x86/kernel/irqinit_32.c index 10a09c2f1828..1507ad4e674d 100644 --- a/trunk/arch/x86/kernel/irqinit_32.c +++ b/trunk/arch/x86/kernel/irqinit_32.c @@ -78,6 +78,15 @@ void __init init_ISA_irqs(void) } } +/* + * IRQ2 is cascade interrupt to second interrupt controller + */ +static struct irqaction irq2 = { + .handler = no_action, + .mask = CPU_MASK_NONE, + .name = "cascade", +}; + DEFINE_PER_CPU(vector_irq_t, vector_irq) = { [0 ... IRQ0_VECTOR - 1] = -1, [IRQ0_VECTOR] = 0, @@ -169,6 +178,9 @@ void __init native_init_IRQ(void) alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); #endif + if (!acpi_ioapic) + setup_irq(2, &irq2); + /* setup after call gates are initialised (usually add in * the architecture specific gates) */ diff --git a/trunk/arch/x86/kernel/olpc.c b/trunk/arch/x86/kernel/olpc.c index 4006c522adc7..7a13fac63a1f 100644 --- a/trunk/arch/x86/kernel/olpc.c +++ b/trunk/arch/x86/kernel/olpc.c @@ -203,7 +203,7 @@ static void __init platform_detect(void) static void __init platform_detect(void) { /* stopgap until OFW support is added to the kernel */ - olpc_platform_info.boardrev = olpc_board(0xc2); + olpc_platform_info.boardrev = 0xc2; } #endif diff --git a/trunk/arch/x86/kernel/paravirt.c b/trunk/arch/x86/kernel/paravirt.c index c6520a4e85d4..e4c8fb608873 100644 --- a/trunk/arch/x86/kernel/paravirt.c +++ b/trunk/arch/x86/kernel/paravirt.c @@ -268,32 +268,6 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void) return __get_cpu_var(paravirt_lazy_mode); } -void arch_flush_lazy_mmu_mode(void) -{ - preempt_disable(); - - if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { - WARN_ON(preempt_count() == 1); - arch_leave_lazy_mmu_mode(); - arch_enter_lazy_mmu_mode(); - } - - preempt_enable(); -} - -void arch_flush_lazy_cpu_mode(void) -{ - preempt_disable(); - - if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) { - WARN_ON(preempt_count() == 1); - arch_leave_lazy_cpu_mode(); - arch_enter_lazy_cpu_mode(); - } - - preempt_enable(); -} - struct pv_info pv_info = { .name = "bare hardware", .paravirt_enabled = 0, diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c index 6d12f7e37f8c..e68bb9e30864 100644 --- a/trunk/arch/x86/kernel/process.c +++ b/trunk/arch/x86/kernel/process.c @@ -180,9 +180,6 @@ void mwait_idle_with_hints(unsigned long ax, unsigned long cx) trace_power_start(&it, POWER_CSTATE, (ax>>4)+1); if (!need_resched()) { - if (cpu_has(¤t_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) - clflush((void *)¤t_thread_info()->flags); - __monitor((void *)¤t_thread_info()->flags, 0, 0); smp_mb(); if (!need_resched()) @@ -197,9 +194,6 @@ static void mwait_idle(void) struct power_trace it; if (!need_resched()) { trace_power_start(&it, POWER_CSTATE, 1); - if (cpu_has(¤t_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) - clflush((void *)¤t_thread_info()->flags); - __monitor((void *)¤t_thread_info()->flags, 0, 0); smp_mb(); if (!need_resched()) diff --git a/trunk/arch/x86/kernel/process_32.c b/trunk/arch/x86/kernel/process_32.c index bd4da2af08ae..a546f55c77b4 100644 --- a/trunk/arch/x86/kernel/process_32.c +++ b/trunk/arch/x86/kernel/process_32.c @@ -104,6 +104,9 @@ void cpu_idle(void) check_pgt_cache(); rmb(); + if (rcu_pending(cpu)) + rcu_check_callbacks(cpu, 0); + if (cpu_is_offline(cpu)) play_dead(); diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c index 85b4cb5c1980..416fb9282f4f 100644 --- a/trunk/arch/x86/kernel/process_64.c +++ b/trunk/arch/x86/kernel/process_64.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -152,18 +151,14 @@ void __show_regs(struct pt_regs *regs, int all) unsigned long d0, d1, d2, d3, d6, d7; unsigned int fsindex, gsindex; unsigned int ds, cs, es; - const char *board; printk("\n"); print_modules(); - board = dmi_get_system_info(DMI_PRODUCT_NAME); - if (!board) - board = ""; - printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n", + printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s\n", current->pid, current->comm, print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), - init_utsname()->version, board); + init_utsname()->version); printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); printk_address(regs->ip, 1); printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c index 06ca07f6ad86..0a5df5f82fb9 100644 --- a/trunk/arch/x86/kernel/ptrace.c +++ b/trunk/arch/x86/kernel/ptrace.c @@ -810,16 +810,12 @@ static void ptrace_bts_untrace(struct task_struct *child) static void ptrace_bts_detach(struct task_struct *child) { - /* - * Ptrace_detach() races with ptrace_untrace() in case - * the child dies and is reaped by another thread. - * - * We only do the memory accounting at this point and - * leave the buffer deallocation and the bts tracer - * release to ptrace_bts_untrace() which will be called - * later on with tasklist_lock held. - */ - release_locked_buffer(child->bts_buffer, child->bts_size); + if (unlikely(child->bts)) { + ds_release_bts(child->bts); + child->bts = NULL; + + ptrace_bts_free_buffer(child); + } } #else static inline void ptrace_bts_fork(struct task_struct *tsk) {} @@ -1388,7 +1384,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, #ifdef CONFIG_X86_32 # define IS_IA32 1 #elif defined CONFIG_IA32_EMULATION -# define IS_IA32 is_compat_task() +# define IS_IA32 test_thread_flag(TIF_IA32) #else # define IS_IA32 0 #endif diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index c461f6d69074..ae0d8042cf69 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -607,7 +607,7 @@ struct x86_quirks *x86_quirks __initdata = &default_x86_quirks; static int __init dmi_low_memory_corruption(const struct dmi_system_id *d) { printk(KERN_NOTICE - "%s detected: BIOS may corrupt low RAM, working around it.\n", + "%s detected: BIOS may corrupt low RAM, working it around.\n", d->ident); e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED); diff --git a/trunk/arch/x86/kernel/time_64.c b/trunk/arch/x86/kernel/time_64.c index 241ec3923f61..e6e695acd725 100644 --- a/trunk/arch/x86/kernel/time_64.c +++ b/trunk/arch/x86/kernel/time_64.c @@ -115,7 +115,7 @@ unsigned long __init calibrate_cpu(void) static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING, .mask = CPU_MASK_NONE, .name = "timer" }; diff --git a/trunk/arch/x86/kernel/traps.c b/trunk/arch/x86/kernel/traps.c index a9e7548e1790..98c2d055284b 100644 --- a/trunk/arch/x86/kernel/traps.c +++ b/trunk/arch/x86/kernel/traps.c @@ -99,12 +99,6 @@ static inline void preempt_conditional_sti(struct pt_regs *regs) local_irq_enable(); } -static inline void conditional_cli(struct pt_regs *regs) -{ - if (regs->flags & X86_EFLAGS_IF) - local_irq_disable(); -} - static inline void preempt_conditional_cli(struct pt_regs *regs) { if (regs->flags & X86_EFLAGS_IF) @@ -632,10 +626,8 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) #ifdef CONFIG_X86_32 debug_vm86: - /* reenable preemption: handle_vm86_trap() might sleep */ - dec_preempt_count(); handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); - conditional_cli(regs); + preempt_conditional_cli(regs); return; #endif @@ -904,7 +896,7 @@ asmlinkage void math_state_restore(void) EXPORT_SYMBOL_GPL(math_state_restore); #ifndef CONFIG_MATH_EMULATION -void math_emulate(struct math_emu_info *info) +asmlinkage void math_emulate(long arg) { printk(KERN_EMERG "math-emulation not enabled and no coprocessor found.\n"); @@ -914,19 +906,16 @@ void math_emulate(struct math_emu_info *info) } #endif /* CONFIG_MATH_EMULATION */ -dotraplinkage void __kprobes do_device_not_available(struct pt_regs regs) +dotraplinkage void __kprobes +do_device_not_available(struct pt_regs *regs, long error) { #ifdef CONFIG_X86_32 if (read_cr0() & X86_CR0_EM) { - struct math_emu_info info = { }; - - conditional_sti(®s); - - info.regs = ®s; - math_emulate(&info); + conditional_sti(regs); + math_emulate(0); } else { math_state_restore(); /* interrupts still off */ - conditional_sti(®s); + conditional_sti(regs); } #else math_state_restore(); diff --git a/trunk/arch/x86/kernel/vmi_32.c b/trunk/arch/x86/kernel/vmi_32.c index bef58b4982db..1d3302cc2ddf 100644 --- a/trunk/arch/x86/kernel/vmi_32.c +++ b/trunk/arch/x86/kernel/vmi_32.c @@ -320,16 +320,6 @@ static void vmi_release_pmd(unsigned long pfn) vmi_ops.release_page(pfn, VMI_PAGE_L2); } -/* - * We use the pgd_free hook for releasing the pgd page: - */ -static void vmi_pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - unsigned long pfn = __pa(pgd) >> PAGE_SHIFT; - - vmi_ops.release_page(pfn, VMI_PAGE_L2); -} - /* * Helper macros for MMU update flags. We can defer updates until a flush * or page invalidation only if the update is to the current address space @@ -772,7 +762,6 @@ static inline int __init activate_vmi(void) if (vmi_ops.release_page) { pv_mmu_ops.release_pte = vmi_release_pte; pv_mmu_ops.release_pmd = vmi_release_pmd; - pv_mmu_ops.pgd_free = vmi_pgd_free; } /* Set linear is needed in all cases */ diff --git a/trunk/arch/x86/kernel/vmiclock_32.c b/trunk/arch/x86/kernel/vmiclock_32.c index e5b088fffa40..c4c1f9e09402 100644 --- a/trunk/arch/x86/kernel/vmiclock_32.c +++ b/trunk/arch/x86/kernel/vmiclock_32.c @@ -202,7 +202,7 @@ static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id) static struct irqaction vmi_clock_action = { .name = "vmi-timer", .handler = vmi_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_NOBALANCING, .mask = CPU_MASK_ALL, }; @@ -283,13 +283,10 @@ void __devinit vmi_time_ap_init(void) #endif /** vmi clocksource */ -static struct clocksource clocksource_vmi; static cycle_t read_real_cycles(void) { - cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); - return ret >= clocksource_vmi.cycle_last ? - ret : clocksource_vmi.cycle_last; + return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); } static struct clocksource clocksource_vmi = { diff --git a/trunk/arch/x86/kvm/i8254.c b/trunk/arch/x86/kvm/i8254.c index 72bd275a9b5c..e665d1c623ca 100644 --- a/trunk/arch/x86/kvm/i8254.c +++ b/trunk/arch/x86/kvm/i8254.c @@ -207,7 +207,7 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps) hrtimer_add_expires_ns(&pt->timer, pt->period); pt->scheduled = hrtimer_get_expires_ns(&pt->timer); if (pt->period) - ps->channels[0].count_load_time = ktime_get(); + ps->channels[0].count_load_time = hrtimer_get_expires(&pt->timer); return (pt->period == 0 ? 0 : 1); } diff --git a/trunk/arch/x86/kvm/irq.c b/trunk/arch/x86/kvm/irq.c index cf17ed52f6fb..c019b8edcdb7 100644 --- a/trunk/arch/x86/kvm/irq.c +++ b/trunk/arch/x86/kvm/irq.c @@ -87,6 +87,13 @@ void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu) } EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs); +void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec) +{ + kvm_apic_timer_intr_post(vcpu, vec); + /* TODO: PIT, RTC etc. */ +} +EXPORT_SYMBOL_GPL(kvm_timer_intr_post); + void __kvm_migrate_timers(struct kvm_vcpu *vcpu) { __kvm_migrate_apic_timer(vcpu); diff --git a/trunk/arch/x86/kvm/irq.h b/trunk/arch/x86/kvm/irq.h index 82579ee538d0..2bf32a03ceec 100644 --- a/trunk/arch/x86/kvm/irq.h +++ b/trunk/arch/x86/kvm/irq.h @@ -89,6 +89,7 @@ static inline int irqchip_in_kernel(struct kvm *kvm) void kvm_pic_reset(struct kvm_kpic_state *s); +void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec); void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu); void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu); diff --git a/trunk/arch/x86/kvm/lapic.c b/trunk/arch/x86/kvm/lapic.c index f0b67f2cdd69..afac68c0815c 100644 --- a/trunk/arch/x86/kvm/lapic.c +++ b/trunk/arch/x86/kvm/lapic.c @@ -35,12 +35,6 @@ #include "kvm_cache_regs.h" #include "irq.h" -#ifndef CONFIG_X86_64 -#define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) -#else -#define mod_64(x, y) ((x) % (y)) -#endif - #define PRId64 "d" #define PRIx64 "llx" #define PRIu64 "u" @@ -517,22 +511,52 @@ static void apic_send_ipi(struct kvm_lapic *apic) static u32 apic_get_tmcct(struct kvm_lapic *apic) { - ktime_t remaining; - s64 ns; + u64 counter_passed; + ktime_t passed, now; u32 tmcct; ASSERT(apic != NULL); + now = apic->timer.dev.base->get_time(); + tmcct = apic_get_reg(apic, APIC_TMICT); + /* if initial count is 0, current count should also be 0 */ - if (apic_get_reg(apic, APIC_TMICT) == 0) + if (tmcct == 0) return 0; - remaining = hrtimer_expires_remaining(&apic->timer.dev); - if (ktime_to_ns(remaining) < 0) - remaining = ktime_set(0, 0); - - ns = mod_64(ktime_to_ns(remaining), apic->timer.period); - tmcct = div64_u64(ns, (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); + if (unlikely(ktime_to_ns(now) <= + ktime_to_ns(apic->timer.last_update))) { + /* Wrap around */ + passed = ktime_add(( { + (ktime_t) { + .tv64 = KTIME_MAX - + (apic->timer.last_update).tv64}; } + ), now); + apic_debug("time elapsed\n"); + } else + passed = ktime_sub(now, apic->timer.last_update); + + counter_passed = div64_u64(ktime_to_ns(passed), + (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); + + if (counter_passed > tmcct) { + if (unlikely(!apic_lvtt_period(apic))) { + /* one-shot timers stick at 0 until reset */ + tmcct = 0; + } else { + /* + * periodic timers reset to APIC_TMICT when they + * hit 0. The while loop simulates this happening N + * times. (counter_passed %= tmcct) would also work, + * but might be slower or not work on 32-bit?? + */ + while (counter_passed > tmcct) + counter_passed -= tmcct; + tmcct -= counter_passed; + } + } else { + tmcct -= counter_passed; + } return tmcct; } @@ -629,6 +653,8 @@ static void start_apic_timer(struct kvm_lapic *apic) { ktime_t now = apic->timer.dev.base->get_time(); + apic->timer.last_update = now; + apic->timer.period = apic_get_reg(apic, APIC_TMICT) * APIC_BUS_CYCLE_NS * apic->timer.divide_count; atomic_set(&apic->timer.pending, 0); @@ -1084,6 +1110,16 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu) } } +void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + if (apic && apic_lvt_vector(apic, APIC_LVTT) == vec) + apic->timer.last_update = ktime_add_ns( + apic->timer.last_update, + apic->timer.period); +} + int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu) { int vector = kvm_apic_has_interrupt(vcpu); diff --git a/trunk/arch/x86/kvm/lapic.h b/trunk/arch/x86/kvm/lapic.h index 45ab6ee71209..81858881287e 100644 --- a/trunk/arch/x86/kvm/lapic.h +++ b/trunk/arch/x86/kvm/lapic.h @@ -12,6 +12,7 @@ struct kvm_lapic { atomic_t pending; s64 period; /* unit: ns */ u32 divide_count; + ktime_t last_update; struct hrtimer dev; } timer; struct kvm_vcpu *vcpu; @@ -41,6 +42,7 @@ void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); int kvm_lapic_enabled(struct kvm_vcpu *vcpu); int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); +void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec); void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index 2d4477c71473..83f11c7474a1 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -1698,13 +1698,8 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, if (largepage) spte |= PT_PAGE_SIZE_MASK; if (mt_mask) { - if (!kvm_is_mmio_pfn(pfn)) { - mt_mask = get_memory_type(vcpu, gfn) << - kvm_x86_ops->get_mt_mask_shift(); - mt_mask |= VMX_EPT_IGMT_BIT; - } else - mt_mask = MTRR_TYPE_UNCACHABLE << - kvm_x86_ops->get_mt_mask_shift(); + mt_mask = get_memory_type(vcpu, gfn) << + kvm_x86_ops->get_mt_mask_shift(); spte |= mt_mask; } diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c index a9e769e4e251..1452851ae258 100644 --- a/trunk/arch/x86/kvm/svm.c +++ b/trunk/arch/x86/kvm/svm.c @@ -1600,6 +1600,7 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu) /* Okay, we can deliver the interrupt: grab it and update PIC state. */ intr_vector = kvm_cpu_get_interrupt(vcpu); svm_inject_irq(svm, intr_vector); + kvm_timer_intr_post(vcpu, intr_vector); out: update_cr8_intercept(vcpu); } diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 7611af576829..6259d7467648 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -903,7 +903,6 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) data = vmcs_readl(GUEST_SYSENTER_ESP); break; default: - vmx_load_host_state(to_vmx(vcpu)); msr = find_msr_entry(to_vmx(vcpu), msr_index); if (msr) { data = msr->data; @@ -3286,6 +3285,7 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu) } if (vcpu->arch.interrupt.pending) { vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr); + kvm_timer_intr_post(vcpu, vcpu->arch.interrupt.nr); if (kvm_cpu_has_interrupt(vcpu)) enable_irq_window(vcpu); } @@ -3687,7 +3687,8 @@ static int __init vmx_init(void) if (vm_need_ept()) { bypass_guest_pf = 0; kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | - VMX_EPT_WRITABLE_MASK); + VMX_EPT_WRITABLE_MASK | + VMX_EPT_IGMT_BIT); kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull, VMX_EPT_EXECUTABLE_MASK, VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 758b7a155ae9..cc17546a2406 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -967,6 +967,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_MMU_SHADOW_CACHE_CONTROL: case KVM_CAP_SET_TSS_ADDR: case KVM_CAP_EXT_CPUID: + case KVM_CAP_CLOCKSOURCE: case KVM_CAP_PIT: case KVM_CAP_NOP_IO_DELAY: case KVM_CAP_MP_STATE: @@ -991,9 +992,6 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_IOMMU: r = iommu_found(); break; - case KVM_CAP_CLOCKSOURCE: - r = boot_cpu_has(X86_FEATURE_CONSTANT_TSC); - break; default: r = 0; break; @@ -4129,13 +4127,9 @@ static void kvm_free_vcpus(struct kvm *kvm) } -void kvm_arch_sync_events(struct kvm *kvm) -{ - kvm_free_all_assigned_devices(kvm); -} - void kvm_arch_destroy_vm(struct kvm *kvm) { + kvm_free_all_assigned_devices(kvm); kvm_iommu_unmap_guest(kvm); kvm_free_pit(kvm); kfree(kvm->arch.vpic); diff --git a/trunk/arch/x86/mach-default/setup.c b/trunk/arch/x86/mach-default/setup.c index 50b591871128..df167f265622 100644 --- a/trunk/arch/x86/mach-default/setup.c +++ b/trunk/arch/x86/mach-default/setup.c @@ -38,15 +38,6 @@ void __init pre_intr_init_hook(void) init_ISA_irqs(); } -/* - * IRQ2 is cascade interrupt to second interrupt controller - */ -static struct irqaction irq2 = { - .handler = no_action, - .mask = CPU_MASK_NONE, - .name = "cascade", -}; - /** * intr_init_hook - post gate setup interrupt initialisation * @@ -62,9 +53,6 @@ void __init intr_init_hook(void) if (x86_quirks->arch_intr_init()) return; } - if (!acpi_ioapic) - setup_irq(2, &irq2); - } /** @@ -96,7 +84,7 @@ void __init trap_init_hook(void) static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, .mask = CPU_MASK_NONE, .name = "timer" }; diff --git a/trunk/arch/x86/mach-voyager/setup.c b/trunk/arch/x86/mach-voyager/setup.c index 8e5118371f0f..a580b9562e76 100644 --- a/trunk/arch/x86/mach-voyager/setup.c +++ b/trunk/arch/x86/mach-voyager/setup.c @@ -33,30 +33,20 @@ void __init intr_init_hook(void) setup_irq(2, &irq2); } -static void voyager_disable_tsc(void) +void __init pre_setup_arch_hook(void) { /* Voyagers run their CPUs from independent clocks, so disable * the TSC code because we can't sync them */ setup_clear_cpu_cap(X86_FEATURE_TSC); } -void __init pre_setup_arch_hook(void) -{ - voyager_disable_tsc(); -} - -void __init pre_time_init_hook(void) -{ - voyager_disable_tsc(); -} - void __init trap_init_hook(void) { } static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, .mask = CPU_MASK_NONE, .name = "timer" }; diff --git a/trunk/arch/x86/mach-voyager/voyager_smp.c b/trunk/arch/x86/mach-voyager/voyager_smp.c index b9cc84a2a4fc..9840b7ec749a 100644 --- a/trunk/arch/x86/mach-voyager/voyager_smp.c +++ b/trunk/arch/x86/mach-voyager/voyager_smp.c @@ -65,7 +65,7 @@ static volatile unsigned long smp_invalidate_needed; /* Bitmask of CPUs present in the system - exported by i386_syms.c, used * by scheduler but indexed physically */ -static cpumask_t voyager_phys_cpu_present_map = CPU_MASK_NONE; +cpumask_t phys_cpu_present_map = CPU_MASK_NONE; /* The internal functions */ static void send_CPI(__u32 cpuset, __u8 cpi); @@ -81,7 +81,7 @@ static void enable_local_vic_irq(unsigned int irq); static void disable_local_vic_irq(unsigned int irq); static void before_handle_vic_irq(unsigned int irq); static void after_handle_vic_irq(unsigned int irq); -static void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask); +static void set_vic_irq_affinity(unsigned int irq, cpumask_t mask); static void ack_vic_irq(unsigned int irq); static void vic_enable_cpi(void); static void do_boot_cpu(__u8 cpuid); @@ -211,6 +211,8 @@ static __u32 cpu_booted_map; static cpumask_t smp_commenced_mask = CPU_MASK_NONE; /* This is for the new dynamic CPU boot code */ +cpumask_t cpu_callin_map = CPU_MASK_NONE; +cpumask_t cpu_callout_map = CPU_MASK_NONE; /* The per processor IRQ masks (these are usually kept in sync) */ static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; @@ -366,19 +368,19 @@ void __init find_smp_config(void) /* set up everything for just this CPU, we can alter * this as we start the other CPUs later */ /* now get the CPU disposition from the extended CMOS */ - cpus_addr(voyager_phys_cpu_present_map)[0] = + cpus_addr(phys_cpu_present_map)[0] = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK); - cpus_addr(voyager_phys_cpu_present_map)[0] |= + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; - cpus_addr(voyager_phys_cpu_present_map)[0] |= + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16; - cpus_addr(voyager_phys_cpu_present_map)[0] |= + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24; - init_cpu_possible(&voyager_phys_cpu_present_map); - printk("VOYAGER SMP: voyager_phys_cpu_present_map = 0x%lx\n", - cpus_addr(voyager_phys_cpu_present_map)[0]); + cpu_possible_map = phys_cpu_present_map; + printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", + cpus_addr(phys_cpu_present_map)[0]); /* Here we set up the VIC to enable SMP */ /* enable the CPIs by writing the base vector to their register */ outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER); @@ -628,15 +630,15 @@ void __init smp_boot_cpus(void) /* now that the cat has probed the Voyager System Bus, sanity * check the cpu map */ if (((voyager_quad_processors | voyager_extended_vic_processors) - & cpus_addr(voyager_phys_cpu_present_map)[0]) != - cpus_addr(voyager_phys_cpu_present_map)[0]) { + & cpus_addr(phys_cpu_present_map)[0]) != + cpus_addr(phys_cpu_present_map)[0]) { /* should panic */ printk("\n\n***WARNING*** " "Sanity check of CPU present map FAILED\n"); } } else if (voyager_level == 4) voyager_extended_vic_processors = - cpus_addr(voyager_phys_cpu_present_map)[0]; + cpus_addr(phys_cpu_present_map)[0]; /* this sets up the idle task to run on the current cpu */ voyager_extended_cpus = 1; @@ -670,7 +672,7 @@ void __init smp_boot_cpus(void) /* loop over all the extended VIC CPUs and boot them. The * Quad CPUs must be bootstrapped by their extended VIC cpu */ for (i = 0; i < nr_cpu_ids; i++) { - if (i == boot_cpu_id || !cpu_isset(i, voyager_phys_cpu_present_map)) + if (i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map)) continue; do_boot_cpu(i); /* This udelay seems to be needed for the Quad boots @@ -1597,16 +1599,16 @@ static void after_handle_vic_irq(unsigned int irq) * change the mask and then do an interrupt enable CPI to re-enable on * the selected processors */ -void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask) +void set_vic_irq_affinity(unsigned int irq, cpumask_t mask) { /* Only extended processors handle interrupts */ unsigned long real_mask; unsigned long irq_mask = 1 << irq; int cpu; - real_mask = cpus_addr(*mask)[0] & voyager_extended_vic_processors; + real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors; - if (cpus_addr(*mask)[0] == 0) + if (cpus_addr(mask)[0] == 0) /* can't have no CPUs to accept the interrupt -- extremely * bad things will happen */ return; @@ -1748,11 +1750,10 @@ static void __cpuinit voyager_smp_prepare_boot_cpu(void) init_gdt(smp_processor_id()); switch_to_new_gdt(); - cpu_online_map = cpumask_of_cpu(smp_processor_id()); - cpu_callout_map = cpumask_of_cpu(smp_processor_id()); - cpu_callin_map = CPU_MASK_NONE; - cpu_present_map = cpumask_of_cpu(smp_processor_id()); - + cpu_set(smp_processor_id(), cpu_online_map); + cpu_set(smp_processor_id(), cpu_callout_map); + cpu_set(smp_processor_id(), cpu_possible_map); + cpu_set(smp_processor_id(), cpu_present_map); } static int __cpuinit voyager_cpu_up(unsigned int cpu) @@ -1782,9 +1783,9 @@ void __init smp_setup_processor_id(void) x86_write_percpu(cpu_number, hard_smp_processor_id()); } -static void voyager_send_call_func(const struct cpumask *callmask) +static void voyager_send_call_func(cpumask_t callmask) { - __u32 mask = cpus_addr(*callmask)[0] & ~(1 << smp_processor_id()); + __u32 mask = cpus_addr(callmask)[0] & ~(1 << smp_processor_id()); send_CPI(mask, VIC_CALL_FUNCTION_CPI); } diff --git a/trunk/arch/x86/math-emu/fpu_entry.c b/trunk/arch/x86/math-emu/fpu_entry.c index 5d87f586f8d7..c7b06feb139b 100644 --- a/trunk/arch/x86/math-emu/fpu_entry.c +++ b/trunk/arch/x86/math-emu/fpu_entry.c @@ -131,7 +131,7 @@ u_char emulating = 0; static int valid_prefix(u_char *Byte, u_char __user ** fpu_eip, overrides * override); -void math_emulate(struct math_emu_info *info) +asmlinkage void math_emulate(long arg) { u_char FPU_modrm, byte1; unsigned short code; @@ -161,7 +161,7 @@ void math_emulate(struct math_emu_info *info) RE_ENTRANT_CHECK_ON; #endif /* RE_ENTRANT_CHECKING */ - FPU_info = info; + SETUP_DATA_AREA(arg); FPU_ORIG_EIP = FPU_EIP; @@ -659,7 +659,7 @@ static int valid_prefix(u_char *Byte, u_char __user **fpu_eip, } } -void math_abort(struct math_emu_info *info, unsigned int signal) +void math_abort(struct info *info, unsigned int signal) { FPU_EIP = FPU_ORIG_EIP; current->thread.trap_no = 16; diff --git a/trunk/arch/x86/math-emu/fpu_proto.h b/trunk/arch/x86/math-emu/fpu_proto.h index 9779df436b7d..aa49b6a0d850 100644 --- a/trunk/arch/x86/math-emu/fpu_proto.h +++ b/trunk/arch/x86/math-emu/fpu_proto.h @@ -51,8 +51,8 @@ extern void ffreep(void); extern void fst_i_(void); extern void fstp_i(void); /* fpu_entry.c */ -extern void math_emulate(struct math_emu_info *info); -extern void math_abort(struct math_emu_info *info, unsigned int signal); +asmlinkage extern void math_emulate(long arg); +extern void math_abort(struct info *info, unsigned int signal); /* fpu_etc.c */ extern void FPU_etc(void); /* fpu_tags.c */ diff --git a/trunk/arch/x86/math-emu/fpu_system.h b/trunk/arch/x86/math-emu/fpu_system.h index 50fa0ec2c8a5..13488fa153e0 100644 --- a/trunk/arch/x86/math-emu/fpu_system.h +++ b/trunk/arch/x86/math-emu/fpu_system.h @@ -16,6 +16,10 @@ #include #include +/* This sets the pointer FPU_info to point to the argument part + of the stack frame of math_emulate() */ +#define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg + /* s is always from a cpu register, and the cpu does bounds checking * during register load --> no further bounds checks needed */ #define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3]) @@ -34,12 +38,12 @@ #define I387 (current->thread.xstate) #define FPU_info (I387->soft.info) -#define FPU_CS (*(unsigned short *) &(FPU_info->regs->cs)) -#define FPU_SS (*(unsigned short *) &(FPU_info->regs->ss)) -#define FPU_DS (*(unsigned short *) &(FPU_info->regs->ds)) -#define FPU_EAX (FPU_info->regs->ax) -#define FPU_EFLAGS (FPU_info->regs->flags) -#define FPU_EIP (FPU_info->regs->ip) +#define FPU_CS (*(unsigned short *) &(FPU_info->___cs)) +#define FPU_SS (*(unsigned short *) &(FPU_info->___ss)) +#define FPU_DS (*(unsigned short *) &(FPU_info->___ds)) +#define FPU_EAX (FPU_info->___eax) +#define FPU_EFLAGS (FPU_info->___eflags) +#define FPU_EIP (FPU_info->___eip) #define FPU_ORIG_EIP (FPU_info->___orig_eip) #define FPU_lookahead (I387->soft.lookahead) diff --git a/trunk/arch/x86/math-emu/get_address.c b/trunk/arch/x86/math-emu/get_address.c index 420b3b6e3915..d701e2b39e44 100644 --- a/trunk/arch/x86/math-emu/get_address.c +++ b/trunk/arch/x86/math-emu/get_address.c @@ -29,43 +29,46 @@ #define FPU_WRITE_BIT 0x10 static int reg_offset[] = { - offsetof(struct pt_regs, ax), - offsetof(struct pt_regs, cx), - offsetof(struct pt_regs, dx), - offsetof(struct pt_regs, bx), - offsetof(struct pt_regs, sp), - offsetof(struct pt_regs, bp), - offsetof(struct pt_regs, si), - offsetof(struct pt_regs, di) + offsetof(struct info, ___eax), + offsetof(struct info, ___ecx), + offsetof(struct info, ___edx), + offsetof(struct info, ___ebx), + offsetof(struct info, ___esp), + offsetof(struct info, ___ebp), + offsetof(struct info, ___esi), + offsetof(struct info, ___edi) }; -#define REG_(x) (*(long *)(reg_offset[(x)] + (u_char *)FPU_info->regs)) +#define REG_(x) (*(long *)(reg_offset[(x)]+(u_char *) FPU_info)) static int reg_offset_vm86[] = { - offsetof(struct pt_regs, cs), - offsetof(struct kernel_vm86_regs, ds), - offsetof(struct kernel_vm86_regs, es), - offsetof(struct kernel_vm86_regs, fs), - offsetof(struct kernel_vm86_regs, gs), - offsetof(struct pt_regs, ss), - offsetof(struct kernel_vm86_regs, ds) + offsetof(struct info, ___cs), + offsetof(struct info, ___vm86_ds), + offsetof(struct info, ___vm86_es), + offsetof(struct info, ___vm86_fs), + offsetof(struct info, ___vm86_gs), + offsetof(struct info, ___ss), + offsetof(struct info, ___vm86_ds) }; #define VM86_REG_(x) (*(unsigned short *) \ - (reg_offset_vm86[((unsigned)x)] + (u_char *)FPU_info->regs)) + (reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info)) + +/* This dummy, gs is not saved on the stack. */ +#define ___GS ___ds static int reg_offset_pm[] = { - offsetof(struct pt_regs, cs), - offsetof(struct pt_regs, ds), - offsetof(struct pt_regs, es), - offsetof(struct pt_regs, fs), - offsetof(struct pt_regs, ds), /* dummy, not saved on stack */ - offsetof(struct pt_regs, ss), - offsetof(struct pt_regs, ds) + offsetof(struct info, ___cs), + offsetof(struct info, ___ds), + offsetof(struct info, ___es), + offsetof(struct info, ___fs), + offsetof(struct info, ___GS), + offsetof(struct info, ___ss), + offsetof(struct info, ___ds) }; #define PM_REG_(x) (*(unsigned short *) \ - (reg_offset_pm[((unsigned)x)] + (u_char *)FPU_info->regs)) + (reg_offset_pm[((unsigned)x)]+(u_char *) FPU_info)) /* Decode the SIB byte. This function assumes mod != 0 */ static int sib(int mod, unsigned long *fpu_eip) @@ -346,34 +349,34 @@ void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip, } switch (rm) { case 0: - address += FPU_info->regs->bx + FPU_info->regs->si; + address += FPU_info->___ebx + FPU_info->___esi; break; case 1: - address += FPU_info->regs->bx + FPU_info->regs->di; + address += FPU_info->___ebx + FPU_info->___edi; break; case 2: - address += FPU_info->regs->bp + FPU_info->regs->si; + address += FPU_info->___ebp + FPU_info->___esi; if (addr_modes.override.segment == PREFIX_DEFAULT) addr_modes.override.segment = PREFIX_SS_; break; case 3: - address += FPU_info->regs->bp + FPU_info->regs->di; + address += FPU_info->___ebp + FPU_info->___edi; if (addr_modes.override.segment == PREFIX_DEFAULT) addr_modes.override.segment = PREFIX_SS_; break; case 4: - address += FPU_info->regs->si; + address += FPU_info->___esi; break; case 5: - address += FPU_info->regs->di; + address += FPU_info->___edi; break; case 6: - address += FPU_info->regs->bp; + address += FPU_info->___ebp; if (addr_modes.override.segment == PREFIX_DEFAULT) addr_modes.override.segment = PREFIX_SS_; break; case 7: - address += FPU_info->regs->bx; + address += FPU_info->___ebx; break; } diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index c76ef1d701c9..90dfae511a41 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -603,6 +603,8 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) si_code = SEGV_MAPERR; + if (notify_page_fault(regs)) + return; if (unlikely(kmmio_fault(regs, address))) return; @@ -632,9 +634,6 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) if (spurious_fault(address, error_code)) return; - /* kprobes don't want to hook the spurious faults. */ - if (notify_page_fault(regs)) - return; /* * Don't take the mm semaphore here. If we fixup a prefetch * fault we could otherwise deadlock. @@ -642,9 +641,6 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) goto bad_area_nosemaphore; } - /* kprobes don't want to hook the spurious faults. */ - if (notify_page_fault(regs)) - return; /* * It's safe to allow irq's after cr2 has been saved and the diff --git a/trunk/arch/x86/mm/iomap_32.c b/trunk/arch/x86/mm/iomap_32.c index 6c2b1af16926..ca53224fc56c 100644 --- a/trunk/arch/x86/mm/iomap_32.c +++ b/trunk/arch/x86/mm/iomap_32.c @@ -20,24 +20,6 @@ #include #include -#ifdef CONFIG_X86_PAE -int -is_io_mapping_possible(resource_size_t base, unsigned long size) -{ - return 1; -} -#else -int -is_io_mapping_possible(resource_size_t base, unsigned long size) -{ - /* There is no way to map greater than 1 << 32 address without PAE */ - if (base + size > 0x100000000ULL) - return 0; - - return 1; -} -#endif - /* Map 'pfn' using fixed map 'type' and protections 'prot' */ void * diff --git a/trunk/arch/x86/mm/ioremap.c b/trunk/arch/x86/mm/ioremap.c index f45d5e29a72e..af750ab973b6 100644 --- a/trunk/arch/x86/mm/ioremap.c +++ b/trunk/arch/x86/mm/ioremap.c @@ -134,6 +134,25 @@ int page_is_ram(unsigned long pagenr) return 0; } +int pagerange_is_ram(unsigned long start, unsigned long end) +{ + int ram_page = 0, not_rampage = 0; + unsigned long page_nr; + + for (page_nr = (start >> PAGE_SHIFT); page_nr < (end >> PAGE_SHIFT); + ++page_nr) { + if (page_is_ram(page_nr)) + ram_page = 1; + else + not_rampage = 1; + + if (ram_page == not_rampage) + return -1; + } + + return ram_page; +} + /* * Fix up the linear direct mapping of the kernel to avoid cache attribute * conflicts. diff --git a/trunk/arch/x86/mm/numa_64.c b/trunk/arch/x86/mm/numa_64.c index f3516da035d1..71a14f89f89e 100644 --- a/trunk/arch/x86/mm/numa_64.c +++ b/trunk/arch/x86/mm/numa_64.c @@ -145,7 +145,7 @@ int __init compute_hash_shift(struct bootnode *nodes, int numnodes, return shift; } -int __meminit __early_pfn_to_nid(unsigned long pfn) +int early_pfn_to_nid(unsigned long pfn) { return phys_to_nid(pfn << PAGE_SHIFT); } diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c index 7be47d1a97e4..84ba74820ad6 100644 --- a/trunk/arch/x86/mm/pageattr.c +++ b/trunk/arch/x86/mm/pageattr.c @@ -508,13 +508,18 @@ static int split_large_page(pte_t *kpte, unsigned long address) #endif /* - * Install the new, split up pagetable. + * Install the new, split up pagetable. Important details here: * - * We use the standard kernel pagetable protections for the new - * pagetable protections, the actual ptes set above control the - * primary protection behavior: + * On Intel the NX bit of all levels must be cleared to make a + * page executable. See section 4.13.2 of Intel 64 and IA-32 + * Architectures Software Developer's Manual). + * + * Mark the entry present. The current mapping might be + * set to not present, which we preserved above. */ - __set_pmd_pte(kpte, address, mk_pte(base, __pgprot(_KERNPG_TABLE))); + ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte))); + pgprot_val(ref_prot) |= _PAGE_PRESENT; + __set_pmd_pte(kpte, address, mk_pte(base, ref_prot)); base = NULL; out_unlock: @@ -570,6 +575,7 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) address = cpa->vaddr[cpa->curpage]; else address = *cpa->vaddr; + repeat: kpte = lookup_address(address, &level); if (!kpte) @@ -806,13 +812,6 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, vm_unmap_aliases(); - /* - * If we're called with lazy mmu updates enabled, the - * in-memory pte state may be stale. Flush pending updates to - * bring them up to date. - */ - arch_flush_lazy_mmu_mode(); - cpa.vaddr = addr; cpa.numpages = numpages; cpa.mask_set = mask_set; @@ -855,13 +854,6 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, } else cpa_flush_all(cache); - /* - * If we've been called with lazy mmu updates enabled, then - * make sure that everything gets flushed out before we - * return. - */ - arch_flush_lazy_mmu_mode(); - out: return ret; } diff --git a/trunk/arch/x86/mm/pat.c b/trunk/arch/x86/mm/pat.c index aebbf67a79d0..7b61036427df 100644 --- a/trunk/arch/x86/mm/pat.c +++ b/trunk/arch/x86/mm/pat.c @@ -211,33 +211,6 @@ chk_conflict(struct memtype *new, struct memtype *entry, unsigned long *type) static struct memtype *cached_entry; static u64 cached_start; -static int pat_pagerange_is_ram(unsigned long start, unsigned long end) -{ - int ram_page = 0, not_rampage = 0; - unsigned long page_nr; - - for (page_nr = (start >> PAGE_SHIFT); page_nr < (end >> PAGE_SHIFT); - ++page_nr) { - /* - * For legacy reasons, physical address range in the legacy ISA - * region is tracked as non-RAM. This will allow users of - * /dev/mem to map portions of legacy ISA region, even when - * some of those portions are listed(or not even listed) with - * different e820 types(RAM/reserved/..) - */ - if (page_nr >= (ISA_END_ADDRESS >> PAGE_SHIFT) && - page_is_ram(page_nr)) - ram_page = 1; - else - not_rampage = 1; - - if (ram_page == not_rampage) - return -1; - } - - return ram_page; -} - /* * For RAM pages, mark the pages as non WB memory type using * PageNonWB (PG_arch_1). We allow only one set_memory_uc() or @@ -363,12 +336,20 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, if (new_type) *new_type = actual_type; - is_range_ram = pat_pagerange_is_ram(start, end); - if (is_range_ram == 1) - return reserve_ram_pages_type(start, end, req_type, - new_type); - else if (is_range_ram < 0) - return -EINVAL; + /* + * For legacy reasons, some parts of the physical address range in the + * legacy 1MB region is treated as non-RAM (even when listed as RAM in + * the e820 tables). So we will track the memory attributes of this + * legacy 1MB region using the linear memtype_list always. + */ + if (end >= ISA_END_ADDRESS) { + is_range_ram = pagerange_is_ram(start, end); + if (is_range_ram == 1) + return reserve_ram_pages_type(start, end, req_type, + new_type); + else if (is_range_ram < 0) + return -EINVAL; + } new = kmalloc(sizeof(struct memtype), GFP_KERNEL); if (!new) @@ -465,11 +446,19 @@ int free_memtype(u64 start, u64 end) if (is_ISA_range(start, end - 1)) return 0; - is_range_ram = pat_pagerange_is_ram(start, end); - if (is_range_ram == 1) - return free_ram_pages_type(start, end); - else if (is_range_ram < 0) - return -EINVAL; + /* + * For legacy reasons, some parts of the physical address range in the + * legacy 1MB region is treated as non-RAM (even when listed as RAM in + * the e820 tables). So we will track the memory attributes of this + * legacy 1MB region using the linear memtype_list always. + */ + if (end >= ISA_END_ADDRESS) { + is_range_ram = pagerange_is_ram(start, end); + if (is_range_ram == 1) + return free_ram_pages_type(start, end); + else if (is_range_ram < 0) + return -EINVAL; + } spin_lock(&memtype_lock); list_for_each_entry(entry, &memtype_list, nd) { @@ -637,13 +626,17 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, unsigned long flags; unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK); - is_ram = pat_pagerange_is_ram(paddr, paddr + size); + is_ram = pagerange_is_ram(paddr, paddr + size); - /* - * reserve_pfn_range() doesn't support RAM pages. - */ - if (is_ram != 0) - return -EINVAL; + if (is_ram != 0) { + /* + * For mapping RAM pages, drivers need to call + * set_memory_[uc|wc|wb] directly, for reserve and free, before + * setting up the PTE. + */ + WARN_ON_ONCE(1); + return 0; + } ret = reserve_memtype(paddr, paddr + size, want_flags, &flags); if (ret) @@ -700,7 +693,7 @@ static void free_pfn_range(u64 paddr, unsigned long size) { int is_ram; - is_ram = pat_pagerange_is_ram(paddr, paddr + size); + is_ram = pagerange_is_ram(paddr, paddr + size); if (is_ram == 0) free_memtype(paddr, paddr + size); } diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index b58e96338149..bea215230b20 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -1672,9 +1672,6 @@ asmlinkage void __init xen_start_kernel(void) possible map and a non-dummy shared_info. */ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; - local_irq_disable(); - early_boot_irqs_off(); - xen_raw_console_write("mapping kernel into physical memory\n"); pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); diff --git a/trunk/arch/x86/xen/multicalls.h b/trunk/arch/x86/xen/multicalls.h index fa3e10725d98..858938241616 100644 --- a/trunk/arch/x86/xen/multicalls.h +++ b/trunk/arch/x86/xen/multicalls.h @@ -19,10 +19,8 @@ DECLARE_PER_CPU(unsigned long, xen_mc_irq_flags); paired with xen_mc_issue() */ static inline void xen_mc_batch(void) { - unsigned long flags; /* need to disable interrupts until this entry is complete */ - local_irq_save(flags); - __get_cpu_var(xen_mc_irq_flags) = flags; + local_irq_save(__get_cpu_var(xen_mc_irq_flags)); } static inline struct multicall_space xen_mc_entry(size_t args) diff --git a/trunk/block/blk-merge.c b/trunk/block/blk-merge.c index a104593e70c3..b92f5b0866b0 100644 --- a/trunk/block/blk-merge.c +++ b/trunk/block/blk-merge.c @@ -38,84 +38,72 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect) } } -static unsigned int __blk_recalc_rq_segments(struct request_queue *q, - struct bio *bio, - unsigned int *seg_size_ptr) +void blk_recalc_rq_segments(struct request *rq) { + int nr_phys_segs; unsigned int phys_size; struct bio_vec *bv, *bvprv = NULL; - int cluster, i, high, highprv = 1; - unsigned int seg_size, nr_phys_segs; - struct bio *fbio; + int seg_size; + int cluster; + struct req_iterator iter; + int high, highprv = 1; + struct request_queue *q = rq->q; - if (!bio) - return 0; + if (!rq->bio) + return; - fbio = bio; cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); seg_size = 0; phys_size = nr_phys_segs = 0; - for_each_bio(bio) { - bio_for_each_segment(bv, bio, i) { - /* - * the trick here is making sure that a high page is - * never considered part of another segment, since that - * might change with the bounce page. - */ - high = page_to_pfn(bv->bv_page) > q->bounce_pfn; - if (high || highprv) + rq_for_each_segment(bv, rq, iter) { + /* + * the trick here is making sure that a high page is never + * considered part of another segment, since that might + * change with the bounce page. + */ + high = page_to_pfn(bv->bv_page) > q->bounce_pfn; + if (high || highprv) + goto new_segment; + if (cluster) { + if (seg_size + bv->bv_len > q->max_segment_size) + goto new_segment; + if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv)) + goto new_segment; + if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv)) goto new_segment; - if (cluster) { - if (seg_size + bv->bv_len > q->max_segment_size) - goto new_segment; - if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv)) - goto new_segment; - if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv)) - goto new_segment; - - seg_size += bv->bv_len; - bvprv = bv; - continue; - } -new_segment: - if (nr_phys_segs == 1 && seg_size > - fbio->bi_seg_front_size) - fbio->bi_seg_front_size = seg_size; - nr_phys_segs++; + seg_size += bv->bv_len; bvprv = bv; - seg_size = bv->bv_len; - highprv = high; + continue; } - } - - if (seg_size_ptr) - *seg_size_ptr = seg_size; - - return nr_phys_segs; -} - -void blk_recalc_rq_segments(struct request *rq) -{ - unsigned int seg_size = 0, phys_segs; +new_segment: + if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) + rq->bio->bi_seg_front_size = seg_size; - phys_segs = __blk_recalc_rq_segments(rq->q, rq->bio, &seg_size); + nr_phys_segs++; + bvprv = bv; + seg_size = bv->bv_len; + highprv = high; + } - if (phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) + if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) rq->bio->bi_seg_front_size = seg_size; if (seg_size > rq->biotail->bi_seg_back_size) rq->biotail->bi_seg_back_size = seg_size; - rq->nr_phys_segments = phys_segs; + rq->nr_phys_segments = nr_phys_segs; } void blk_recount_segments(struct request_queue *q, struct bio *bio) { + struct request rq; struct bio *nxt = bio->bi_next; - + rq.q = q; + rq.bio = rq.biotail = bio; bio->bi_next = NULL; - bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, NULL); + blk_recalc_rq_segments(&rq); bio->bi_next = nxt; + bio->bi_phys_segments = rq.nr_phys_segments; bio->bi_flags |= (1 << BIO_SEG_VALID); } EXPORT_SYMBOL(blk_recount_segments); diff --git a/trunk/block/blk-timeout.c b/trunk/block/blk-timeout.c index bbbdc4b8ccf2..a09535377a94 100644 --- a/trunk/block/blk-timeout.c +++ b/trunk/block/blk-timeout.c @@ -209,19 +209,12 @@ void blk_abort_queue(struct request_queue *q) { unsigned long flags; struct request *rq, *tmp; - LIST_HEAD(list); spin_lock_irqsave(q->queue_lock, flags); elv_abort_queue(q); - /* - * Splice entries to local list, to avoid deadlocking if entries - * get readded to the timeout list by error handling - */ - list_splice_init(&q->timeout_list, &list); - - list_for_each_entry_safe(rq, tmp, &list, timeout_list) + list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list) blk_abort_request(rq); spin_unlock_irqrestore(q->queue_lock, flags); diff --git a/trunk/block/blktrace.c b/trunk/block/blktrace.c index 7cf9d1ff45a0..39cc3bfe56e4 100644 --- a/trunk/block/blktrace.c +++ b/trunk/block/blktrace.c @@ -142,7 +142,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, what |= ddir_act[rw & WRITE]; what |= MASK_TC_BIT(rw, BARRIER); - what |= MASK_TC_BIT(rw, SYNCIO); + what |= MASK_TC_BIT(rw, SYNC); what |= MASK_TC_BIT(rw, AHEAD); what |= MASK_TC_BIT(rw, META); what |= MASK_TC_BIT(rw, DISCARD); diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c index 0ce8806dd0c1..d414bb5607e8 100644 --- a/trunk/block/bsg.c +++ b/trunk/block/bsg.c @@ -244,8 +244,7 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw) * map sg_io_v4 to a request. */ static struct request * -bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, - u8 *sense) +bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm) { struct request_queue *q = bd->queue; struct request *rq, *next_rq = NULL; @@ -307,10 +306,6 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, if (ret) goto out; } - - rq->sense = sense; - rq->sense_len = 0; - return rq; out: if (rq->cmd != rq->__cmd) @@ -353,6 +348,9 @@ static void bsg_rq_end_io(struct request *rq, int uptodate) static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, struct bsg_command *bc, struct request *rq) { + rq->sense = bc->sense; + rq->sense_len = 0; + /* * add bc command to busy queue and submit rq for io */ @@ -421,7 +419,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, { int ret = 0; - dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors); + dprintk("rq %p bio %p %u\n", rq, bio, rq->errors); /* * fill in all the output members */ @@ -637,7 +635,7 @@ static int __bsg_write(struct bsg_device *bd, const char __user *buf, /* * get a request, fill in the blanks, and add to request queue */ - rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm, bc->sense); + rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm); if (IS_ERR(rq)) { ret = PTR_ERR(rq); rq = NULL; @@ -924,12 +922,11 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct request *rq; struct bio *bio, *bidi_bio = NULL; struct sg_io_v4 hdr; - u8 sense[SCSI_SENSE_BUFFERSIZE]; if (copy_from_user(&hdr, uarg, sizeof(hdr))) return -EFAULT; - rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE, sense); + rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE); if (IS_ERR(rq)) return PTR_ERR(rq); diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index a9ec910974c1..397960cf26af 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -256,22 +256,6 @@ void blkdev_show(struct seq_file *seqf, off_t offset) } #endif /* CONFIG_PROC_FS */ -/** - * register_blkdev - register a new block device - * - * @major: the requested major device number [1..255]. If @major=0, try to - * allocate any unused major number. - * @name: the name of the new block device as a zero terminated string - * - * The @name must be unique within the system. - * - * The return value depends on the @major input parameter. - * - if a major device number was requested in range [1..255] then the - * function returns zero on success, or a negative error code - * - if any unused major number was requested with @major=0 parameter - * then the return value is the allocated major number in range - * [1..255] or a negative error code otherwise - */ int register_blkdev(unsigned int major, const char *name) { struct blk_major_name **n, *p; @@ -1103,14 +1087,6 @@ dev_t blk_lookup_devt(const char *name, int partno) if (strcmp(dev_name(dev), name)) continue; - if (partno < disk->minors) { - /* We need to return the right devno, even - * if the partition doesn't exist yet. - */ - devt = MKDEV(MAJOR(dev->devt), - MINOR(dev->devt) + partno); - break; - } part = disk_get_part(disk, partno); if (part) { devt = part_devt(part); diff --git a/trunk/crypto/ahash.c b/trunk/crypto/ahash.c index b2d1ee32cfe8..ba5292d69ebd 100644 --- a/trunk/crypto/ahash.c +++ b/trunk/crypto/ahash.c @@ -214,7 +214,7 @@ static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? "yes" : "no"); seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); - seq_printf(m, "digestsize : %u\n", alg->cra_ahash.digestsize); + seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize); } const struct crypto_type crypto_ahash_type = { diff --git a/trunk/crypto/algapi.c b/trunk/crypto/algapi.c index 56c62e2858d5..7c41e7405c41 100644 --- a/trunk/crypto/algapi.c +++ b/trunk/crypto/algapi.c @@ -149,9 +149,6 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg) if (q == alg) goto err; - if (crypto_is_moribund(q)) - continue; - if (crypto_is_larval(q)) { if (!strcmp(alg->cra_driver_name, q->cra_driver_name)) goto err; @@ -200,7 +197,7 @@ void crypto_alg_tested(const char *name, int err) down_write(&crypto_alg_sem); list_for_each_entry(q, &crypto_alg_list, cra_list) { - if (crypto_is_moribund(q) || !crypto_is_larval(q)) + if (!crypto_is_larval(q)) continue; test = (struct crypto_larval *)q; @@ -213,7 +210,6 @@ void crypto_alg_tested(const char *name, int err) goto unlock; found: - q->cra_flags |= CRYPTO_ALG_DEAD; alg = test->adult; if (err || list_empty(&alg->cra_list)) goto complete; diff --git a/trunk/crypto/api.c b/trunk/crypto/api.c index efe77df6863f..9975a7bd246c 100644 --- a/trunk/crypto/api.c +++ b/trunk/crypto/api.c @@ -557,34 +557,34 @@ struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, return ERR_PTR(err); } EXPORT_SYMBOL_GPL(crypto_alloc_tfm); - + /* - * crypto_destroy_tfm - Free crypto transform - * @mem: Start of tfm slab + * crypto_free_tfm - Free crypto transform * @tfm: Transform to free * - * This function frees up the transform and any associated resources, + * crypto_free_tfm() frees up the transform and any associated resources, * then drops the refcount on the associated algorithm. */ -void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm) +void crypto_free_tfm(struct crypto_tfm *tfm) { struct crypto_alg *alg; int size; - if (unlikely(!mem)) + if (unlikely(!tfm)) return; alg = tfm->__crt_alg; - size = ksize(mem); + size = sizeof(*tfm) + alg->cra_ctxsize; if (!tfm->exit && alg->cra_exit) alg->cra_exit(tfm); crypto_exit_ops(tfm); crypto_mod_put(alg); - memset(mem, 0, size); - kfree(mem); + memset(tfm, 0, size); + kfree(tfm); } -EXPORT_SYMBOL_GPL(crypto_destroy_tfm); + +EXPORT_SYMBOL_GPL(crypto_free_tfm); int crypto_has_alg(const char *name, u32 type, u32 mask) { diff --git a/trunk/crypto/lrw.c b/trunk/crypto/lrw.c index 358f80be2bf9..8ef664e3bcd9 100644 --- a/trunk/crypto/lrw.c +++ b/trunk/crypto/lrw.c @@ -45,13 +45,7 @@ struct priv { static inline void setbit128_bbe(void *b, int bit) { - __set_bit(bit ^ (0x80 - -#ifdef __BIG_ENDIAN - BITS_PER_LONG -#else - BITS_PER_BYTE -#endif - ), b); + __set_bit(bit ^ 0x78, b); } static int setkey(struct crypto_tfm *parent, const u8 *key, diff --git a/trunk/crypto/scatterwalk.c b/trunk/crypto/scatterwalk.c index 3de89a424401..9aeeb52004a5 100644 --- a/trunk/crypto/scatterwalk.c +++ b/trunk/crypto/scatterwalk.c @@ -54,8 +54,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out, struct page *page; page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT); - if (!PageSlab(page)) - flush_dcache_page(page); + flush_dcache_page(page); } if (more) { diff --git a/trunk/crypto/shash.c b/trunk/crypto/shash.c index d5a2b619c55f..c9df367332ff 100644 --- a/trunk/crypto/shash.c +++ b/trunk/crypto/shash.c @@ -388,15 +388,10 @@ static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm) struct shash_desc *desc = crypto_tfm_ctx(tfm); struct crypto_shash *shash; - if (!crypto_mod_get(calg)) - return -EAGAIN; - shash = __crypto_shash_cast(crypto_create_tfm( calg, &crypto_shash_type)); - if (IS_ERR(shash)) { - crypto_mod_put(calg); + if (IS_ERR(shash)) return PTR_ERR(shash); - } desc->tfm = shash; tfm->exit = crypto_exit_shash_ops_compat; diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 8a851d0f4384..d7f9839ba264 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -9,7 +9,6 @@ menuconfig ACPI depends on PCI depends on PM select PNP - select CPU_IDLE default y ---help--- Advanced Configuration and Power Interface (ACPI) support for @@ -254,6 +253,13 @@ config ACPI_PCI_SLOT help you correlate PCI bus addresses with the physical geography of your slots. If you are unsure, say N. +config ACPI_SYSTEM + bool + default y + help + This driver will enable your system to shut down using ACPI, and + dump your ACPI DSDT table using /proc/acpi/dsdt. + config X86_PM_TIMER bool "Power Management Timer Support" if EMBEDDED depends on X86 @@ -281,7 +287,7 @@ config ACPI_CONTAINER support physical cpu/memory hot-plug. If one selects "m", this driver can be loaded with - "modprobe container". + "modprobe acpi_container". config ACPI_HOTPLUG_MEMORY tristate "Memory Hotplug" diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile index b130ea0d0759..65d90c720b5a 100644 --- a/trunk/drivers/acpi/Makefile +++ b/trunk/drivers/acpi/Makefile @@ -52,7 +52,7 @@ obj-$(CONFIG_ACPI_PROCESSOR) += processor.o obj-$(CONFIG_ACPI_CONTAINER) += container.o obj-$(CONFIG_ACPI_THERMAL) += thermal.o obj-y += power.o -obj-y += system.o event.o +obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o obj-$(CONFIG_ACPI_DEBUG) += debug.o obj-$(CONFIG_ACPI_NUMA) += numa.o obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o diff --git a/trunk/drivers/acpi/acpica/tbutils.c b/trunk/drivers/acpi/acpica/tbutils.c index 22ce48985720..9684cc827930 100644 --- a/trunk/drivers/acpi/acpica/tbutils.c +++ b/trunk/drivers/acpi/acpica/tbutils.c @@ -538,9 +538,10 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) if (ACPI_FAILURE(status)) { ACPI_WARNING((AE_INFO, "Truncating %u table entries!", - (unsigned) (table_count - - (acpi_gbl_root_table_list. - count - 2)))); + (unsigned) + (acpi_gbl_root_table_list.size - + acpi_gbl_root_table_list. + count))); break; } } diff --git a/trunk/drivers/acpi/acpica/uteval.c b/trunk/drivers/acpi/acpica/uteval.c index 9c9897dbe907..da9450bc60f7 100644 --- a/trunk/drivers/acpi/acpica/uteval.c +++ b/trunk/drivers/acpi/acpica/uteval.c @@ -116,9 +116,9 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) return_ACPI_STATUS(AE_NO_MEMORY); } - /* Default return value is 0, NOT-SUPPORTED */ + /* Default return value is SUPPORTED */ - return_desc->integer.value = 0; + return_desc->integer.value = ACPI_UINT32_MAX; walk_state->return_desc = return_desc; /* Compare input string to static table of supported interfaces */ @@ -127,8 +127,10 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) if (!ACPI_STRCMP (string_desc->string.pointer, acpi_interfaces_supported[i])) { - return_desc->integer.value = ACPI_UINT32_MAX; - goto done; + + /* The interface is supported */ + + return_ACPI_STATUS(AE_OK); } } @@ -139,14 +141,15 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) */ status = acpi_os_validate_interface(string_desc->string.pointer); if (ACPI_SUCCESS(status)) { - return_desc->integer.value = ACPI_UINT32_MAX; + + /* The interface is supported */ + + return_ACPI_STATUS(AE_OK); } -done: - ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n", - string_desc->string.pointer, - return_desc->integer.value == 0 ? "not-" : "")); + /* The interface is not supported */ + return_desc->integer.value = 0; return_ACPI_STATUS(AE_OK); } diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 69cbc57c2d1c..65132f920459 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -138,29 +138,6 @@ static int acpi_battery_technology(struct acpi_battery *battery) static int acpi_battery_get_state(struct acpi_battery *battery); -static int acpi_battery_is_charged(struct acpi_battery *battery) -{ - /* either charging or discharging */ - if (battery->state != 0) - return 0; - - /* battery not reporting charge */ - if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || - battery->capacity_now == 0) - return 0; - - /* good batteries update full_charge as the batteries degrade */ - if (battery->full_charge_capacity == battery->capacity_now) - return 1; - - /* fallback to using design values for broken batteries */ - if (battery->design_capacity == battery->capacity_now) - return 1; - - /* we don't do any sort of metric based on percentages */ - return 0; -} - static int acpi_battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -178,7 +155,7 @@ static int acpi_battery_get_property(struct power_supply *psy, val->intval = POWER_SUPPLY_STATUS_DISCHARGING; else if (battery->state & 0x02) val->intval = POWER_SUPPLY_STATUS_CHARGING; - else if (acpi_battery_is_charged(battery)) + else if (battery->state == 0) val->intval = POWER_SUPPLY_STATUS_FULL; else val->intval = POWER_SUPPLY_STATUS_UNKNOWN; diff --git a/trunk/drivers/acpi/container.c b/trunk/drivers/acpi/container.c index fe0cdf83641a..17020c12623c 100644 --- a/trunk/drivers/acpi/container.c +++ b/trunk/drivers/acpi/container.c @@ -163,7 +163,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) case ACPI_NOTIFY_BUS_CHECK: /* Fall through */ case ACPI_NOTIFY_DEVICE_CHECK: - printk(KERN_WARNING "Container driver received %s event\n", + printk("Container driver received %s event\n", (type == ACPI_NOTIFY_BUS_CHECK) ? "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"); status = acpi_bus_get_device(handle, &device); @@ -174,8 +174,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); else - printk(KERN_WARNING - "Failed to add container\n"); + printk("Failed to add container\n"); } } else { if (ACPI_SUCCESS(status)) { diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index 35094f230b1e..5b30b8d91d71 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -855,14 +855,10 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) static ssize_t show_docked(struct device *dev, struct device_attribute *attr, char *buf) { - struct acpi_device *tmp; - struct dock_station *dock_station = *((struct dock_station **) dev->platform_data); + return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station)); - if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp))) - return snprintf(buf, PAGE_SIZE, "1\n"); - return snprintf(buf, PAGE_SIZE, "0\n"); } static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); @@ -988,7 +984,7 @@ static int dock_add(acpi_handle handle) ret = device_create_file(&dock_device->dev, &dev_attr_docked); if (ret) { - printk(KERN_ERR "Error %d adding sysfs file\n", ret); + printk("Error %d adding sysfs file\n", ret); platform_device_unregister(dock_device); kfree(dock_station); dock_station = NULL; @@ -996,7 +992,7 @@ static int dock_add(acpi_handle handle) } ret = device_create_file(&dock_device->dev, &dev_attr_undock); if (ret) { - printk(KERN_ERR "Error %d adding sysfs file\n", ret); + printk("Error %d adding sysfs file\n", ret); device_remove_file(&dock_device->dev, &dev_attr_docked); platform_device_unregister(dock_device); kfree(dock_station); @@ -1005,7 +1001,7 @@ static int dock_add(acpi_handle handle) } ret = device_create_file(&dock_device->dev, &dev_attr_uid); if (ret) { - printk(KERN_ERR "Error %d adding sysfs file\n", ret); + printk("Error %d adding sysfs file\n", ret); device_remove_file(&dock_device->dev, &dev_attr_docked); device_remove_file(&dock_device->dev, &dev_attr_undock); platform_device_unregister(dock_device); @@ -1015,7 +1011,7 @@ static int dock_add(acpi_handle handle) } ret = device_create_file(&dock_device->dev, &dev_attr_flags); if (ret) { - printk(KERN_ERR "Error %d adding sysfs file\n", ret); + printk("Error %d adding sysfs file\n", ret); device_remove_file(&dock_device->dev, &dev_attr_docked); device_remove_file(&dock_device->dev, &dev_attr_undock); device_remove_file(&dock_device->dev, &dev_attr_uid); diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index 2fe15060dcdc..a2b82c90a683 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -120,8 +120,6 @@ static struct acpi_ec { spinlock_t curr_lock; } *boot_ec, *first_ec; -static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ - /* -------------------------------------------------------------------------- Transaction Management -------------------------------------------------------------------------- */ @@ -261,8 +259,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); acpi_disable_gpe(NULL, ec->gpe); } - if (EC_FLAGS_MSI) - udelay(ACPI_EC_DELAY); /* start transaction */ spin_lock_irqsave(&ec->curr_lock, tmp); /* following two actions should be kept atomic */ @@ -971,11 +967,6 @@ int __init acpi_ec_ecdt_probe(void) /* * Generate a boot ec context */ - if (dmi_name_in_vendors("Micro-Star") || - dmi_name_in_vendors("Notebook")) { - pr_info(PREFIX "Enabling special treatment for EC from MSI.\n"); - EC_FLAGS_MSI = 1; - } status = acpi_get_table(ACPI_SIG_ECDT, 1, (struct acpi_table_header **)&ecdt_ptr); if (ACPI_SUCCESS(status)) { @@ -991,7 +982,7 @@ int __init acpi_ec_ecdt_probe(void) saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); if (!saved_ec) return -ENOMEM; - memcpy(saved_ec, boot_ec, sizeof(*saved_ec)); + memcpy(&saved_ec, boot_ec, sizeof(saved_ec)); /* fall through */ } /* This workaround is needed only on some broken machines, diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 5479b9f42513..adec3d15810a 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -255,12 +255,12 @@ static int acpi_platform_notify(struct device *dev) } type = acpi_get_bus_type(dev->bus); if (!type) { - DBG("No ACPI bus support for %s\n", dev_name(dev)); + DBG("No ACPI bus support for %s\n", dev->bus_id); ret = -EINVAL; goto end; } if ((ret = type->find_device(dev, &handle)) != 0) - DBG("Can't get handler for %s\n", dev_name(dev)); + DBG("Can't get handler for %s\n", dev->bus_id); end: if (!ret) acpi_bind_one(dev, handle); @@ -271,10 +271,10 @@ static int acpi_platform_notify(struct device *dev) acpi_get_name(dev->archdata.acpi_handle, ACPI_FULL_PATHNAME, &buffer); - DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer); + DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); kfree(buffer.pointer); } else - DBG("Device %s -> No ACPI support\n", dev_name(dev)); + DBG("Device %s -> No ACPI support\n", dev->bus_id); #endif return ret; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index b3193ec0a2ef..6729a4992f2b 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -228,10 +228,10 @@ void acpi_os_vprintf(const char *fmt, va_list args) if (acpi_in_debugger) { kdb_printf("%s", buffer); } else { - printk(KERN_CONT "%s", buffer); + printk("%s", buffer); } #else - printk(KERN_CONT "%s", buffer); + printk("%s", buffer); #endif } @@ -1317,54 +1317,6 @@ acpi_os_validate_interface (char *interface) return AE_SUPPORT; } -#ifdef CONFIG_X86 - -struct aml_port_desc { - uint start; - uint end; - char* name; - char warned; -}; - -static struct aml_port_desc aml_invalid_port_list[] = { - {0x20, 0x21, "PIC0", 0}, - {0xA0, 0xA1, "PIC1", 0}, - {0x4D0, 0x4D1, "ELCR", 0} -}; - -/* - * valid_aml_io_address() - * - * if valid, return true - * else invalid, warn once, return false - */ -static bool valid_aml_io_address(uint address, uint length) -{ - int i; - int entries = sizeof(aml_invalid_port_list) / sizeof(struct aml_port_desc); - - for (i = 0; i < entries; ++i) { - if ((address >= aml_invalid_port_list[i].start && - address <= aml_invalid_port_list[i].end) || - (address + length >= aml_invalid_port_list[i].start && - address + length <= aml_invalid_port_list[i].end)) - { - if (!aml_invalid_port_list[i].warned) - { - printk(KERN_ERR "ACPI: Denied BIOS AML access" - " to invalid port 0x%x+0x%x (%s)\n", - address, length, - aml_invalid_port_list[i].name); - aml_invalid_port_list[i].warned = 1; - } - return false; /* invalid */ - } - } - return true; /* valid */ -} -#else -static inline bool valid_aml_io_address(uint address, uint length) { return true; } -#endif /****************************************************************************** * * FUNCTION: acpi_os_validate_address @@ -1394,8 +1346,6 @@ acpi_os_validate_address ( switch (space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: - if (!valid_aml_io_address(address, length)) - return AE_AML_ILLEGAL_ADDRESS; case ACPI_ADR_SPACE_SYSTEM_MEMORY: /* Only interference checks against SystemIO and SytemMemory are needed */ diff --git a/trunk/drivers/acpi/pci_link.c b/trunk/drivers/acpi/pci_link.c index 6c772ca76bd1..1c6e73c7865e 100644 --- a/trunk/drivers/acpi/pci_link.c +++ b/trunk/drivers/acpi/pci_link.c @@ -593,7 +593,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) return -ENODEV; } else { acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING; - printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n", + printk(PREFIX "%s [%s] enabled at IRQ %d\n", acpi_device_name(link->device), acpi_device_bid(link->device), link->irq.active); } diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 7bc22a471fe3..66a9d8145562 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -66,17 +66,43 @@ ACPI_MODULE_NAME("processor_idle"); #define ACPI_PROCESSOR_FILE_POWER "power" #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) #define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) +#ifndef CONFIG_CPU_IDLE +#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ +#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ +static void (*pm_idle_save) (void) __read_mostly; +#else #define C2_OVERHEAD 1 /* 1us */ #define C3_OVERHEAD 1 /* 1us */ +#endif #define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000)) static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; +#ifdef CONFIG_CPU_IDLE module_param(max_cstate, uint, 0000); +#else +module_param(max_cstate, uint, 0644); +#endif static unsigned int nocst __read_mostly; module_param(nocst, uint, 0000); +#ifndef CONFIG_CPU_IDLE +/* + * bm_history -- bit-mask with a bit per jiffy of bus-master activity + * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms + * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms + * 100 HZ: 0x0000000F: 4 jiffies = 40ms + * reduce history for more aggressive entry into C3 + */ +static unsigned int bm_history __read_mostly = + (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); +module_param(bm_history, uint, 0644); + +static int acpi_processor_set_power_policy(struct acpi_processor *pr); + +#else /* CONFIG_CPU_IDLE */ static unsigned int latency_factor __read_mostly = 2; module_param(latency_factor, uint, 0644); +#endif /* * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. @@ -198,6 +224,71 @@ static void acpi_safe_halt(void) current_thread_info()->status |= TS_POLLING; } +#ifndef CONFIG_CPU_IDLE + +static void +acpi_processor_power_activate(struct acpi_processor *pr, + struct acpi_processor_cx *new) +{ + struct acpi_processor_cx *old; + + if (!pr || !new) + return; + + old = pr->power.state; + + if (old) + old->promotion.count = 0; + new->demotion.count = 0; + + /* Cleanup from old state. */ + if (old) { + switch (old->type) { + case ACPI_STATE_C3: + /* Disable bus master reload */ + if (new->type != ACPI_STATE_C3 && pr->flags.bm_check) + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + break; + } + } + + /* Prepare to use new state. */ + switch (new->type) { + case ACPI_STATE_C3: + /* Enable bus master reload */ + if (old->type != ACPI_STATE_C3 && pr->flags.bm_check) + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); + break; + } + + pr->power.state = new; + + return; +} + +static atomic_t c3_cpu_count; + +/* Common C-state entry for C2, C3, .. */ +static void acpi_cstate_enter(struct acpi_processor_cx *cstate) +{ + /* Don't trace irqs off for idle */ + stop_critical_timings(); + if (cstate->entry_method == ACPI_CSTATE_FFH) { + /* Call into architectural FFH based C-state */ + acpi_processor_ffh_cstate_enter(cstate); + } else { + int unused; + /* IO port based C-state */ + inb(cstate->address); + /* Dummy wait op - must do something useless after P_LVL2 read + because chipsets cannot guarantee that STPCLK# signal + gets asserted in time to freeze execution properly. */ + unused = inl(acpi_gbl_FADT.xpm_timer_block.address); + } + start_critical_timings(); +} +#endif /* !CONFIG_CPU_IDLE */ + #ifdef ARCH_APICTIMER_STOPS_ON_C3 /* @@ -299,6 +390,421 @@ static int tsc_halts_in_c(int state) } #endif +#ifndef CONFIG_CPU_IDLE +static void acpi_processor_idle(void) +{ + struct acpi_processor *pr = NULL; + struct acpi_processor_cx *cx = NULL; + struct acpi_processor_cx *next_state = NULL; + int sleep_ticks = 0; + u32 t1, t2 = 0; + + /* + * Interrupts must be disabled during bus mastering calculations and + * for C2/C3 transitions. + */ + local_irq_disable(); + + pr = __get_cpu_var(processors); + if (!pr) { + local_irq_enable(); + return; + } + + /* + * Check whether we truly need to go idle, or should + * reschedule: + */ + if (unlikely(need_resched())) { + local_irq_enable(); + return; + } + + cx = pr->power.state; + if (!cx || acpi_idle_suspend) { + if (pm_idle_save) { + pm_idle_save(); /* enables IRQs */ + } else { + acpi_safe_halt(); + local_irq_enable(); + } + + return; + } + + /* + * Check BM Activity + * ----------------- + * Check for bus mastering activity (if required), record, and check + * for demotion. + */ + if (pr->flags.bm_check) { + u32 bm_status = 0; + unsigned long diff = jiffies - pr->power.bm_check_timestamp; + + if (diff > 31) + diff = 31; + + pr->power.bm_activity <<= diff; + + acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); + if (bm_status) { + pr->power.bm_activity |= 0x1; + acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); + } + /* + * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect + * the true state of bus mastering activity; forcing us to + * manually check the BMIDEA bit of each IDE channel. + */ + else if (errata.piix4.bmisx) { + if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01) + || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01)) + pr->power.bm_activity |= 0x1; + } + + pr->power.bm_check_timestamp = jiffies; + + /* + * If bus mastering is or was active this jiffy, demote + * to avoid a faulty transition. Note that the processor + * won't enter a low-power state during this call (to this + * function) but should upon the next. + * + * TBD: A better policy might be to fallback to the demotion + * state (use it for this quantum only) istead of + * demoting -- and rely on duration as our sole demotion + * qualification. This may, however, introduce DMA + * issues (e.g. floppy DMA transfer overrun/underrun). + */ + if ((pr->power.bm_activity & 0x1) && + cx->demotion.threshold.bm) { + local_irq_enable(); + next_state = cx->demotion.state; + goto end; + } + } + +#ifdef CONFIG_HOTPLUG_CPU + /* + * Check for P_LVL2_UP flag before entering C2 and above on + * an SMP system. We do it here instead of doing it at _CST/P_LVL + * detection phase, to work cleanly with logical CPU hotplug. + */ + if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && + !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) + cx = &pr->power.states[ACPI_STATE_C1]; +#endif + + /* + * Sleep: + * ------ + * Invoke the current Cx state to put the processor to sleep. + */ + if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { + current_thread_info()->status &= ~TS_POLLING; + /* + * TS_POLLING-cleared state must be visible before we + * test NEED_RESCHED: + */ + smp_mb(); + if (need_resched()) { + current_thread_info()->status |= TS_POLLING; + local_irq_enable(); + return; + } + } + + switch (cx->type) { + + case ACPI_STATE_C1: + /* + * Invoke C1. + * Use the appropriate idle routine, the one that would + * be used without acpi C-states. + */ + if (pm_idle_save) { + pm_idle_save(); /* enables IRQs */ + } else { + acpi_safe_halt(); + local_irq_enable(); + } + + /* + * TBD: Can't get time duration while in C1, as resumes + * go to an ISR rather than here. Need to instrument + * base interrupt handler. + * + * Note: the TSC better not stop in C1, sched_clock() will + * skew otherwise. + */ + sleep_ticks = 0xFFFFFFFF; + + break; + + case ACPI_STATE_C2: + /* Get start time (ticks) */ + t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + /* Tell the scheduler that we are going deep-idle: */ + sched_clock_idle_sleep_event(); + /* Invoke C2 */ + acpi_state_timer_broadcast(pr, cx, 1); + acpi_cstate_enter(cx); + /* Get end time (ticks) */ + t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); + +#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) + /* TSC halts in C2, so notify users */ + if (tsc_halts_in_c(ACPI_STATE_C2)) + mark_tsc_unstable("possible TSC halt in C2"); +#endif + /* Compute time (ticks) that we were actually asleep */ + sleep_ticks = ticks_elapsed(t1, t2); + + /* Tell the scheduler how much we idled: */ + sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + + /* Re-enable interrupts */ + local_irq_enable(); + /* Do not account our idle-switching overhead: */ + sleep_ticks -= cx->latency_ticks + C2_OVERHEAD; + + current_thread_info()->status |= TS_POLLING; + acpi_state_timer_broadcast(pr, cx, 0); + break; + + case ACPI_STATE_C3: + acpi_unlazy_tlb(smp_processor_id()); + /* + * Must be done before busmaster disable as we might + * need to access HPET ! + */ + acpi_state_timer_broadcast(pr, cx, 1); + /* + * disable bus master + * bm_check implies we need ARB_DIS + * !bm_check implies we need cache flush + * bm_control implies whether we can do ARB_DIS + * + * That leaves a case where bm_check is set and bm_control is + * not set. In that case we cannot do much, we enter C3 + * without doing anything. + */ + if (pr->flags.bm_check && pr->flags.bm_control) { + if (atomic_inc_return(&c3_cpu_count) == + num_online_cpus()) { + /* + * All CPUs are trying to go to C3 + * Disable bus master arbitration + */ + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); + } + } else if (!pr->flags.bm_check) { + /* SMP with no shared cache... Invalidate cache */ + ACPI_FLUSH_CPU_CACHE(); + } + + /* Get start time (ticks) */ + t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + /* Invoke C3 */ + /* Tell the scheduler that we are going deep-idle: */ + sched_clock_idle_sleep_event(); + acpi_cstate_enter(cx); + /* Get end time (ticks) */ + t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); + if (pr->flags.bm_check && pr->flags.bm_control) { + /* Enable bus master arbitration */ + atomic_dec(&c3_cpu_count); + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); + } + +#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) + /* TSC halts in C3, so notify users */ + if (tsc_halts_in_c(ACPI_STATE_C3)) + mark_tsc_unstable("TSC halts in C3"); +#endif + /* Compute time (ticks) that we were actually asleep */ + sleep_ticks = ticks_elapsed(t1, t2); + /* Tell the scheduler how much we idled: */ + sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + + /* Re-enable interrupts */ + local_irq_enable(); + /* Do not account our idle-switching overhead: */ + sleep_ticks -= cx->latency_ticks + C3_OVERHEAD; + + current_thread_info()->status |= TS_POLLING; + acpi_state_timer_broadcast(pr, cx, 0); + break; + + default: + local_irq_enable(); + return; + } + cx->usage++; + if ((cx->type != ACPI_STATE_C1) && (sleep_ticks > 0)) + cx->time += sleep_ticks; + + next_state = pr->power.state; + +#ifdef CONFIG_HOTPLUG_CPU + /* Don't do promotion/demotion */ + if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && + !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) { + next_state = cx; + goto end; + } +#endif + + /* + * Promotion? + * ---------- + * Track the number of longs (time asleep is greater than threshold) + * and promote when the count threshold is reached. Note that bus + * mastering activity may prevent promotions. + * Do not promote above max_cstate. + */ + if (cx->promotion.state && + ((cx->promotion.state - pr->power.states) <= max_cstate)) { + if (sleep_ticks > cx->promotion.threshold.ticks && + cx->promotion.state->latency <= + pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) { + cx->promotion.count++; + cx->demotion.count = 0; + if (cx->promotion.count >= + cx->promotion.threshold.count) { + if (pr->flags.bm_check) { + if (! + (pr->power.bm_activity & cx-> + promotion.threshold.bm)) { + next_state = + cx->promotion.state; + goto end; + } + } else { + next_state = cx->promotion.state; + goto end; + } + } + } + } + + /* + * Demotion? + * --------- + * Track the number of shorts (time asleep is less than time threshold) + * and demote when the usage threshold is reached. + */ + if (cx->demotion.state) { + if (sleep_ticks < cx->demotion.threshold.ticks) { + cx->demotion.count++; + cx->promotion.count = 0; + if (cx->demotion.count >= cx->demotion.threshold.count) { + next_state = cx->demotion.state; + goto end; + } + } + } + + end: + /* + * Demote if current state exceeds max_cstate + * or if the latency of the current state is unacceptable + */ + if ((pr->power.state - pr->power.states) > max_cstate || + pr->power.state->latency > + pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) { + if (cx->demotion.state) + next_state = cx->demotion.state; + } + + /* + * New Cx State? + * ------------- + * If we're going to start using a new Cx state we must clean up + * from the previous and prepare to use the new. + */ + if (next_state != pr->power.state) + acpi_processor_power_activate(pr, next_state); +} + +static int acpi_processor_set_power_policy(struct acpi_processor *pr) +{ + unsigned int i; + unsigned int state_is_set = 0; + struct acpi_processor_cx *lower = NULL; + struct acpi_processor_cx *higher = NULL; + struct acpi_processor_cx *cx; + + + if (!pr) + return -EINVAL; + + /* + * This function sets the default Cx state policy (OS idle handler). + * Our scheme is to promote quickly to C2 but more conservatively + * to C3. We're favoring C2 for its characteristics of low latency + * (quick response), good power savings, and ability to allow bus + * mastering activity. Note that the Cx state policy is completely + * customizable and can be altered dynamically. + */ + + /* startup state */ + for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { + cx = &pr->power.states[i]; + if (!cx->valid) + continue; + + if (!state_is_set) + pr->power.state = cx; + state_is_set++; + break; + } + + if (!state_is_set) + return -ENODEV; + + /* demotion */ + for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { + cx = &pr->power.states[i]; + if (!cx->valid) + continue; + + if (lower) { + cx->demotion.state = lower; + cx->demotion.threshold.ticks = cx->latency_ticks; + cx->demotion.threshold.count = 1; + if (cx->type == ACPI_STATE_C3) + cx->demotion.threshold.bm = bm_history; + } + + lower = cx; + } + + /* promotion */ + for (i = (ACPI_PROCESSOR_MAX_POWER - 1); i > 0; i--) { + cx = &pr->power.states[i]; + if (!cx->valid) + continue; + + if (higher) { + cx->promotion.state = higher; + cx->promotion.threshold.ticks = cx->latency_ticks; + if (cx->type >= ACPI_STATE_C2) + cx->promotion.threshold.count = 4; + else + cx->promotion.threshold.count = 10; + if (higher->type == ACPI_STATE_C3) + cx->promotion.threshold.bm = bm_history; + } + + higher = cx; + } + + return 0; +} +#endif /* !CONFIG_CPU_IDLE */ + static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) { @@ -541,7 +1047,11 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx) */ cx->valid = 1; +#ifndef CONFIG_CPU_IDLE + cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); +#else cx->latency_ticks = cx->latency; +#endif return; } @@ -611,6 +1121,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, " for C3 to be enabled on SMP systems\n")); return; } + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); } /* @@ -621,16 +1132,11 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, */ cx->valid = 1; +#ifndef CONFIG_CPU_IDLE + cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); +#else cx->latency_ticks = cx->latency; - /* - * On older chipsets, BM_RLD needs to be set - * in order for Bus Master activity to wake the - * system from C3. Newer chipsets handle DMA - * during C3 automatically and BM_RLD is a NOP. - * In either case, the proper way to - * handle BM_RLD is to set it and leave it set. - */ - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); +#endif return; } @@ -695,6 +1201,20 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) pr->power.count = acpi_processor_power_verify(pr); +#ifndef CONFIG_CPU_IDLE + /* + * Set Default Policy + * ------------------ + * Now that we know which states are supported, set the default + * policy. Note that this policy can be changed dynamically + * (e.g. encourage deeper sleeps to conserve battery life when + * not on AC). + */ + result = acpi_processor_set_power_policy(pr); + if (result) + return result; +#endif + /* * if one state of type C2 or C3 is available, mark this * CPU as being "idle manageable" @@ -792,6 +1312,69 @@ static const struct file_operations acpi_processor_power_fops = { .release = single_release, }; +#ifndef CONFIG_CPU_IDLE + +int acpi_processor_cst_has_changed(struct acpi_processor *pr) +{ + int result = 0; + + if (boot_option_idle_override) + return 0; + + if (!pr) + return -EINVAL; + + if (nocst) { + return -ENODEV; + } + + if (!pr->flags.power_setup_done) + return -ENODEV; + + /* + * Fall back to the default idle loop, when pm_idle_save had + * been initialized. + */ + if (pm_idle_save) { + pm_idle = pm_idle_save; + /* Relies on interrupts forcing exit from idle. */ + synchronize_sched(); + } + + pr->flags.power = 0; + result = acpi_processor_get_power_info(pr); + if ((pr->flags.power == 1) && (pr->flags.power_setup_done)) + pm_idle = acpi_processor_idle; + + return result; +} + +#ifdef CONFIG_SMP +static void smp_callback(void *v) +{ + /* we already woke the CPU up, nothing more to do */ +} + +/* + * This function gets called when a part of the kernel has a new latency + * requirement. This means we need to get all processors out of their C-state, + * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that + * wakes them all right up. + */ +static int acpi_processor_latency_notify(struct notifier_block *b, + unsigned long l, void *v) +{ + smp_call_function(smp_callback, NULL, 1); + return NOTIFY_OK; +} + +static struct notifier_block acpi_processor_latency_notifier = { + .notifier_call = acpi_processor_latency_notify, +}; + +#endif + +#else /* CONFIG_CPU_IDLE */ /** * acpi_idle_bm_check - checks if bus master activity was detected @@ -800,7 +1383,7 @@ static int acpi_idle_bm_check(void) { u32 bm_status = 0; - acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); + acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); if (bm_status) acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); /* @@ -816,6 +1399,25 @@ static int acpi_idle_bm_check(void) return bm_status; } +/** + * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state + * @pr: the processor + * @target: the new target state + */ +static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr, + struct acpi_processor_cx *target) +{ + if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) { + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + pr->flags.bm_rld_set = 0; + } + + if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) { + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); + pr->flags.bm_rld_set = 1; + } +} + /** * acpi_idle_do_entry - a helper function that does C2 and C3 type entry * @cx: cstate data @@ -871,6 +1473,9 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, return 0; } + if (pr->flags.bm_check) + acpi_idle_update_bm_rld(pr, cx); + t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); acpi_idle_do_entry(cx); t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); @@ -922,6 +1527,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, */ acpi_state_timer_broadcast(pr, cx, 1); + if (pr->flags.bm_check) + acpi_idle_update_bm_rld(pr, cx); + if (cx->type == ACPI_STATE_C3) ACPI_FLUSH_CPU_CACHE(); @@ -1013,6 +1621,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, */ acpi_state_timer_broadcast(pr, cx, 1); + acpi_idle_update_bm_rld(pr, cx); + /* * disable bus master * bm_check implies we need ARB_DIS @@ -1185,6 +1795,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) return ret; } +#endif /* CONFIG_CPU_IDLE */ + int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device) { @@ -1213,6 +1825,10 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, "ACPI: processor limited to max C-state %d\n", max_cstate); first_run++; +#if !defined(CONFIG_CPU_IDLE) && defined(CONFIG_SMP) + pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY, + &acpi_processor_latency_notifier); +#endif } if (!pr) @@ -1236,9 +1852,11 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, * platforms that only support C1. */ if (pr->flags.power) { +#ifdef CONFIG_CPU_IDLE acpi_processor_setup_cpuidle(pr); if (cpuidle_register_device(&pr->power.dev)) return -EIO; +#endif printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id); for (i = 1; i <= pr->power.count; i++) @@ -1246,6 +1864,13 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, printk(" C%d[C%d]", i, pr->power.states[i].type); printk(")\n"); + +#ifndef CONFIG_CPU_IDLE + if (pr->id == 0) { + pm_idle_save = pm_idle; + pm_idle = acpi_processor_idle; + } +#endif } /* 'power' [R] */ @@ -1264,12 +1889,34 @@ int acpi_processor_power_exit(struct acpi_processor *pr, if (boot_option_idle_override) return 0; +#ifdef CONFIG_CPU_IDLE cpuidle_unregister_device(&pr->power.dev); +#endif pr->flags.power_setup_done = 0; if (acpi_device_dir(device)) remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, acpi_device_dir(device)); +#ifndef CONFIG_CPU_IDLE + + /* Unregister the idle handler when processor #0 is removed. */ + if (pr->id == 0) { + if (pm_idle_save) + pm_idle = pm_idle_save; + + /* + * We are about to unload the current idle thread pm callback + * (pm_idle), Wait for all processors to update cached/local + * copies of pm_idle before proceeding. + */ + cpu_idle_wait(); +#ifdef CONFIG_SMP + pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY, + &acpi_processor_latency_notifier); +#endif + } +#endif + return 0; } diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index 9cc769b587ff..846e227592d4 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -31,6 +31,14 @@ #include #include +#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF +#include +#include +#include + +#include +#endif + #ifdef CONFIG_X86 #include #endif @@ -426,6 +434,96 @@ int acpi_processor_notify_smm(struct module *calling_module) EXPORT_SYMBOL(acpi_processor_notify_smm); +#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF +/* /proc/acpi/processor/../performance interface (DEPRECATED) */ + +static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_processor_perf_fops = { + .owner = THIS_MODULE, + .open = acpi_processor_perf_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_processor *pr = seq->private; + int i; + + + if (!pr) + goto end; + + if (!pr->performance) { + seq_puts(seq, "\n"); + goto end; + } + + seq_printf(seq, "state count: %d\n" + "active state: P%d\n", + pr->performance->state_count, pr->performance->state); + + seq_puts(seq, "states:\n"); + for (i = 0; i < pr->performance->state_count; i++) + seq_printf(seq, + " %cP%d: %d MHz, %d mW, %d uS\n", + (i == pr->performance->state ? '*' : ' '), i, + (u32) pr->performance->states[i].core_frequency, + (u32) pr->performance->states[i].power, + (u32) pr->performance->states[i].transition_latency); + + end: + return 0; +} + +static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_processor_perf_seq_show, + PDE(inode)->data); +} + +static void acpi_cpufreq_add_file(struct acpi_processor *pr) +{ + struct acpi_device *device = NULL; + + + if (acpi_bus_get_device(pr->handle, &device)) + return; + + /* add file 'performance' [R/W] */ + proc_create_data(ACPI_PROCESSOR_FILE_PERFORMANCE, S_IFREG | S_IRUGO, + acpi_device_dir(device), + &acpi_processor_perf_fops, acpi_driver_data(device)); + return; +} + +static void acpi_cpufreq_remove_file(struct acpi_processor *pr) +{ + struct acpi_device *device = NULL; + + + if (acpi_bus_get_device(pr->handle, &device)) + return; + + /* remove file 'performance' */ + remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE, + acpi_device_dir(device)); + + return; +} + +#else +static void acpi_cpufreq_add_file(struct acpi_processor *pr) +{ + return; +} +static void acpi_cpufreq_remove_file(struct acpi_processor *pr) +{ + return; +} +#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */ + static int acpi_processor_get_psd(struct acpi_processor *pr) { int result = 0; @@ -649,12 +747,14 @@ int acpi_processor_preregister_performance( } EXPORT_SYMBOL(acpi_processor_preregister_performance); + int acpi_processor_register_performance(struct acpi_processor_performance *performance, unsigned int cpu) { struct acpi_processor *pr; + if (!(acpi_processor_ppc_status & PPC_REGISTERED)) return -EINVAL; @@ -681,6 +781,8 @@ acpi_processor_register_performance(struct acpi_processor_performance return -EIO; } + acpi_cpufreq_add_file(pr); + mutex_unlock(&performance_mutex); return 0; } @@ -693,6 +795,7 @@ acpi_processor_unregister_performance(struct acpi_processor_performance { struct acpi_processor *pr; + mutex_lock(&performance_mutex); pr = per_cpu(processors, cpu); @@ -705,6 +808,8 @@ acpi_processor_unregister_performance(struct acpi_processor_performance kfree(pr->performance->states); pr->performance = NULL; + acpi_cpufreq_remove_file(pr); + mutex_unlock(&performance_mutex); return; diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index 519266654f06..7e3c609cbef2 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -90,6 +90,31 @@ void __init acpi_old_suspend_ordering(void) old_suspend_ordering = true; } +/* + * According to the ACPI specification the BIOS should make sure that ACPI is + * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, + * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI + * on such systems during resume. Unfortunately that doesn't help in + * particularly pathological cases in which SCI_EN has to be set directly on + * resume, although the specification states very clearly that this flag is + * owned by the hardware. The set_sci_en_on_resume variable will be set in such + * cases. + */ +static bool set_sci_en_on_resume; +/* + * The ACPI specification wants us to save NVS memory regions during hibernation + * and to restore them during the subsequent resume. However, it is not certain + * if this mechanism is going to work on all machines, so we allow the user to + * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line + * option. + */ +static bool s4_no_nvs; + +void __init acpi_s4_no_nvs(void) +{ + s4_no_nvs = true; +} + /** * acpi_pm_disable_gpes - Disable the GPEs. */ @@ -168,18 +193,6 @@ static void acpi_pm_end(void) #endif /* CONFIG_ACPI_SLEEP */ #ifdef CONFIG_SUSPEND -/* - * According to the ACPI specification the BIOS should make sure that ACPI is - * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, - * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI - * on such systems during resume. Unfortunately that doesn't help in - * particularly pathological cases in which SCI_EN has to be set directly on - * resume, although the specification states very clearly that this flag is - * owned by the hardware. The set_sci_en_on_resume variable will be set in such - * cases. - */ -static bool set_sci_en_on_resume; - extern void do_suspend_lowlevel(void); static u32 acpi_suspend_states[] = { @@ -383,20 +396,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { #endif /* CONFIG_SUSPEND */ #ifdef CONFIG_HIBERNATION -/* - * The ACPI specification wants us to save NVS memory regions during hibernation - * and to restore them during the subsequent resume. However, it is not certain - * if this mechanism is going to work on all machines, so we allow the user to - * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line - * option. - */ -static bool s4_no_nvs; - -void __init acpi_s4_no_nvs(void) -{ - s4_no_nvs = true; -} - static unsigned long s4_hardware_signature; static struct acpi_table_facs *facs; static bool nosigcheck; @@ -680,7 +679,7 @@ static void acpi_power_off_prepare(void) static void acpi_power_off(void) { /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ - printk(KERN_DEBUG "%s called\n", __func__); + printk("%s called\n", __func__); local_irq_disable(); acpi_enable_wakeup_device(ACPI_STATE_S5); acpi_enter_sleep_state(ACPI_STATE_S5); diff --git a/trunk/drivers/acpi/tables.c b/trunk/drivers/acpi/tables.c index a8852952fac4..775c97a282bd 100644 --- a/trunk/drivers/acpi/tables.c +++ b/trunk/drivers/acpi/tables.c @@ -293,12 +293,7 @@ static void __init check_multiple_madt(void) int __init acpi_table_init(void) { - acpi_status status; - - status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); - if (ACPI_FAILURE(status)) - return 1; - + acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); check_multiple_madt(); return 0; } diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index bb5ed059114a..f261737636da 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -1020,7 +1020,7 @@ acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) } seq_printf(seq, "levels: "); - for (i = 2; i < dev->brightness->count; i++) + for (i = 0; i < dev->brightness->count; i++) seq_printf(seq, " %d", dev->brightness->levels[i]); seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); @@ -1059,7 +1059,7 @@ acpi_video_device_write_brightness(struct file *file, return -EFAULT; /* validate through the list of available levels */ - for (i = 2; i < dev->brightness->count; i++) + for (i = 0; i < dev->brightness->count; i++) if (level == dev->brightness->levels[i]) { if (ACPI_SUCCESS (acpi_video_device_lcd_set_level(dev, level))) @@ -1260,7 +1260,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) printk(KERN_WARNING PREFIX "This indicates a BIOS bug. Please contact the manufacturer.\n"); } - printk(KERN_WARNING "%llx\n", options); + printk("%llx\n", options); seq_printf(seq, "can POST: "); if (options & 2) seq_printf(seq, " "); @@ -1712,7 +1712,7 @@ acpi_video_get_next_level(struct acpi_video_device *device, max = max_below = 0; min = min_above = 255; /* Find closest level to level_current */ - for (i = 2; i < device->brightness->count; i++) { + for (i = 0; i < device->brightness->count; i++) { l = device->brightness->levels[i]; if (abs(l - level_current) < abs(delta)) { delta = l - level_current; @@ -1722,7 +1722,7 @@ acpi_video_get_next_level(struct acpi_video_device *device, } /* Ajust level_current to closest available level */ level_current += delta; - for (i = 2; i < device->brightness->count; i++) { + for (i = 0; i < device->brightness->count; i++) { l = device->brightness->levels[i]; if (l < min) min = l; @@ -2006,12 +2006,6 @@ static int acpi_video_bus_add(struct acpi_device *device) device->pnp.bus_id[3] = '0' + instance; instance ++; } - /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */ - if (!strcmp(device->pnp.bus_id, "VGA")) { - if (instance) - device->pnp.bus_id[3] = '0' + instance; - instance++; - } video->device = device; strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index a603bbf9b1b7..77bba4c083cb 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -61,14 +61,9 @@ #define EM_MSG_LED_VALUE_ON 0x00010000 static int ahci_skip_host_reset; -static int ahci_ignore_sss; - module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444); MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)"); -module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); -MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); - static int ahci_enable_alpm(struct ata_port *ap, enum link_pm policy); static void ahci_disable_alpm(struct ata_port *ap); @@ -2697,10 +2692,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) host->iomap = pcim_iomap_table(pdev); host->private_data = hpriv; - if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) + if (!(hpriv->cap & HOST_CAP_SSS)) host->flags |= ATA_HOST_PARALLEL_SCAN; - else - printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n"); if (pi.flags & ATA_FLAG_EM) ahci_reset_em(host); diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 9fbf0595f3d4..88c242856dae 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -164,11 +164,6 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -static bool ata_sstatus_online(u32 sstatus) -{ - return (sstatus & 0xf) == 0x3; -} - /** * ata_link_next - link iteration helper * @link: the previous link, NULL to start @@ -1020,6 +1015,18 @@ static const char *sata_spd_string(unsigned int spd) return spd_str[spd - 1]; } +void ata_dev_disable(struct ata_device *dev) +{ + if (ata_dev_enabled(dev)) { + if (ata_msg_drv(dev->link->ap)) + ata_dev_printk(dev, KERN_WARNING, "disabled\n"); + ata_acpi_on_disable(dev); + ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | + ATA_DNXFER_QUIET); + dev->class++; + } +} + static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) { struct ata_link *link = dev->link; @@ -2232,40 +2239,6 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, return rc; } -static int ata_do_link_spd_horkage(struct ata_device *dev) -{ - struct ata_link *plink = ata_dev_phys_link(dev); - u32 target, target_limit; - - if (!sata_scr_valid(plink)) - return 0; - - if (dev->horkage & ATA_HORKAGE_1_5_GBPS) - target = 1; - else - return 0; - - target_limit = (1 << target) - 1; - - /* if already on stricter limit, no need to push further */ - if (plink->sata_spd_limit <= target_limit) - return 0; - - plink->sata_spd_limit = target_limit; - - /* Request another EH round by returning -EAGAIN if link is - * going faster than the target speed. Forward progress is - * guaranteed by setting sata_spd_limit to target_limit above. - */ - if (plink->sata_spd > target) { - ata_dev_printk(dev, KERN_INFO, - "applying link speed limit horkage to %s\n", - sata_spd_string(target)); - return -EAGAIN; - } - return 0; -} - static inline u8 ata_dev_knobble(struct ata_device *dev) { struct ata_port *ap = dev->link->ap; @@ -2356,10 +2329,6 @@ int ata_dev_configure(struct ata_device *dev) return 0; } - rc = ata_do_link_spd_horkage(dev); - if (rc) - return rc; - /* let ACPI work its magic */ rc = ata_acpi_on_devcfg(dev); if (rc) @@ -2815,7 +2784,7 @@ int ata_bus_probe(struct ata_port *ap) /* This is the last chance, better to slow * down than lose it. */ - sata_down_spd_limit(&ap->link, 0); + sata_down_spd_limit(&ap->link); ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); } } @@ -2911,27 +2880,21 @@ void ata_port_disable(struct ata_port *ap) /** * sata_down_spd_limit - adjust SATA spd limit downward * @link: Link to adjust SATA spd limit for - * @spd_limit: Additional limit * * Adjust SATA spd limit of @link downward. Note that this * function only adjusts the limit. The change must be applied * using sata_set_spd(). * - * If @spd_limit is non-zero, the speed is limited to equal to or - * lower than @spd_limit if such speed is supported. If - * @spd_limit is slower than any supported speed, only the lowest - * supported speed is allowed. - * * LOCKING: * Inherited from caller. * * RETURNS: * 0 on success, negative errno on failure */ -int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) +int sata_down_spd_limit(struct ata_link *link) { u32 sstatus, spd, mask; - int rc, bit; + int rc, highbit; if (!sata_scr_valid(link)) return -EOPNOTSUPP; @@ -2940,7 +2903,7 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) * If not, use cached value in link->sata_spd. */ rc = sata_scr_read(link, SCR_STATUS, &sstatus); - if (rc == 0 && ata_sstatus_online(sstatus)) + if (rc == 0) spd = (sstatus >> 4) & 0xf; else spd = link->sata_spd; @@ -2950,8 +2913,8 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) return -EINVAL; /* unconditionally mask off the highest bit */ - bit = fls(mask) - 1; - mask &= ~(1 << bit); + highbit = fls(mask) - 1; + mask &= ~(1 << highbit); /* Mask off all speeds higher than or equal to the current * one. Force 1.5Gbps if current SPD is not available. @@ -2965,15 +2928,6 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) if (!mask) return -EINVAL; - if (spd_limit) { - if (mask & ((1 << spd_limit) - 1)) - mask &= (1 << spd_limit) - 1; - else { - bit = ffs(mask) - 1; - mask = 1 << bit; - } - } - link->sata_spd_limit = mask; ata_link_printk(link, KERN_WARNING, "limiting SATA link speed to %s\n", @@ -4261,9 +4215,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* Devices that do not need bridging limits applied */ { "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, }, - /* Devices which aren't very happy with higher link speeds */ - { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, - /* End Marker */ { } }; @@ -4758,7 +4709,8 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) /** * ata_qc_new - Request an available ATA command, for queueing - * @ap: target port + * @ap: Port associated with device @dev + * @dev: Device from whom we request an available command structure * * LOCKING: * None. @@ -5223,7 +5175,7 @@ bool ata_phys_link_online(struct ata_link *link) u32 sstatus; if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 && - ata_sstatus_online(sstatus)) + (sstatus & 0xf) == 0x3) return true; return false; } @@ -5247,7 +5199,7 @@ bool ata_phys_link_offline(struct ata_link *link) u32 sstatus; if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 && - !ata_sstatus_online(sstatus)) + (sstatus & 0xf) != 0x3) return true; return false; } @@ -5460,8 +5412,8 @@ void ata_dev_init(struct ata_device *dev) dev->horkage = 0; spin_unlock_irqrestore(ap->lock, flags); - memset((void *)dev + ATA_DEVICE_CLEAR_BEGIN, 0, - ATA_DEVICE_CLEAR_END - ATA_DEVICE_CLEAR_BEGIN); + memset((void *)dev + ATA_DEVICE_CLEAR_OFFSET, 0, + sizeof(*dev) - ATA_DEVICE_CLEAR_OFFSET); dev->pio_mask = UINT_MAX; dev->mwdma_mask = UINT_MAX; dev->udma_mask = UINT_MAX; diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index ce2ef0475339..8147a8386370 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -82,10 +82,6 @@ enum { ATA_EH_FASTDRAIN_INTERVAL = 3000, ATA_EH_UA_TRIES = 5, - - /* probe speed down parameters, see ata_eh_schedule_probe() */ - ATA_EH_PROBE_TRIAL_INTERVAL = 60000, /* 1 min */ - ATA_EH_PROBE_TRIALS = 2, }; /* The following table determines how we sequence resets. Each entry @@ -1179,32 +1175,6 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc) __ata_eh_qc_complete(qc); } -/** - * ata_dev_disable - disable ATA device - * @dev: ATA device to disable - * - * Disable @dev. - * - * Locking: - * EH context. - */ -void ata_dev_disable(struct ata_device *dev) -{ - if (!ata_dev_enabled(dev)) - return; - - if (ata_msg_drv(dev->link->ap)) - ata_dev_printk(dev, KERN_WARNING, "disabled\n"); - ata_acpi_on_disable(dev); - ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); - dev->class++; - - /* From now till the next successful probe, ering is used to - * track probe failures. Clear accumulated device error info. - */ - ata_ering_clear(&dev->ering); -} - /** * ata_eh_detach_dev - detach ATA device * @dev: ATA device to detach @@ -1879,7 +1849,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, /* speed down? */ if (verdict & ATA_EH_SPDN_SPEED_DOWN) { /* speed down SATA link speed if possible */ - if (sata_down_spd_limit(link, 0) == 0) { + if (sata_down_spd_limit(link) == 0) { action |= ATA_EH_RESET; goto done; } @@ -2631,11 +2601,11 @@ int ata_eh_reset(struct ata_link *link, int classify, } if (try == max_tries - 1) { - sata_down_spd_limit(link, 0); + sata_down_spd_limit(link); if (slave) - sata_down_spd_limit(slave, 0); + sata_down_spd_limit(slave); } else if (rc == -EPIPE) - sata_down_spd_limit(failed_link, 0); + sata_down_spd_limit(failed_link); if (hardreset) reset = hardreset; @@ -2774,8 +2744,6 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, readid_flags, dev->id); switch (rc) { case 0: - /* clear error info accumulated during probe */ - ata_ering_clear(&dev->ering); new_mask |= 1 << dev->devno; break; case -ENOENT: @@ -2979,24 +2947,9 @@ static int ata_eh_skip_recovery(struct ata_link *link) return 1; } -static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg) -{ - u64 interval = msecs_to_jiffies(ATA_EH_PROBE_TRIAL_INTERVAL); - u64 now = get_jiffies_64(); - int *trials = void_arg; - - if (ent->timestamp < now - min(now, interval)) - return -1; - - (*trials)++; - return 0; -} - static int ata_eh_schedule_probe(struct ata_device *dev) { struct ata_eh_context *ehc = &dev->link->eh_context; - struct ata_link *link = ata_dev_phys_link(dev); - int trials = 0; if (!(ehc->i.probe_mask & (1 << dev->devno)) || (ehc->did_probe_mask & (1 << dev->devno))) @@ -3009,25 +2962,6 @@ static int ata_eh_schedule_probe(struct ata_device *dev) ehc->saved_xfer_mode[dev->devno] = 0; ehc->saved_ncq_enabled &= ~(1 << dev->devno); - /* Record and count probe trials on the ering. The specific - * error mask used is irrelevant. Because a successful device - * detection clears the ering, this count accumulates only if - * there are consecutive failed probes. - * - * If the count is equal to or higher than ATA_EH_PROBE_TRIALS - * in the last ATA_EH_PROBE_TRIAL_INTERVAL, link speed is - * forced to 1.5Gbps. - * - * This is to work around cases where failed link speed - * negotiation results in device misdetection leading to - * infinite DEVXCHG or PHRDY CHG events. - */ - ata_ering_record(&dev->ering, 0, AC_ERR_OTHER); - ata_ering_map(&dev->ering, ata_count_probe_trials_cb, &trials); - - if (trials > ATA_EH_PROBE_TRIALS) - sata_down_spd_limit(link, 1); - return 1; } @@ -3035,11 +2969,7 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err) { struct ata_eh_context *ehc = &dev->link->eh_context; - /* -EAGAIN from EH routine indicates retry without prejudice. - * The requester is responsible for ensuring forward progress. - */ - if (err != -EAGAIN) - ehc->tries[dev->devno]--; + ehc->tries[dev->devno]--; switch (err) { case -ENODEV: @@ -3049,13 +2979,12 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err) /* give it just one more chance */ ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1); case -EIO: - if (ehc->tries[dev->devno] == 1) { + if (ehc->tries[dev->devno] == 1 && dev->pio_mode > XFER_PIO_0) { /* This is the last chance, better to slow * down than lose it. */ - sata_down_spd_limit(ata_dev_phys_link(dev), 0); - if (dev->pio_mode > XFER_PIO_0) - ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); + sata_down_spd_limit(ata_dev_phys_link(dev)); + ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); } } diff --git a/trunk/drivers/ata/libata-pmp.c b/trunk/drivers/ata/libata-pmp.c index 619f2c33950e..98ca07a2db87 100644 --- a/trunk/drivers/ata/libata-pmp.c +++ b/trunk/drivers/ata/libata-pmp.c @@ -729,7 +729,7 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, if (tries) { /* consecutive revalidation failures? speed down */ if (reval_failed) - sata_down_spd_limit(link, 0); + sata_down_spd_limit(link); else reval_failed = 1; diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index b9747fa59e54..3c4c5ae277ba 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -415,7 +415,6 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, /** * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl - * @ap: target port * @sdev: SCSI device to get identify data for * @arg: User buffer area for identify data * diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index 714cb046b594..0b299b0f8172 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -773,32 +773,18 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf, else iowrite32_rep(data_addr, buf, words); - /* Transfer trailing bytes, if any */ if (unlikely(slop)) { - unsigned char pad[4]; - - /* Point buf to the tail of buffer */ - buf += buflen - slop; - - /* - * Use io*_rep() accessors here as well to avoid pointlessly - * swapping bytes to and fro on the big endian machines... - */ + __le32 pad; if (rw == READ) { - if (slop < 3) - ioread16_rep(data_addr, pad, 1); - else - ioread32_rep(data_addr, pad, 1); - memcpy(buf, pad, slop); + pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); + memcpy(buf + buflen - slop, &pad, slop); } else { - memcpy(pad, buf, slop); - if (slop < 3) - iowrite16_rep(data_addr, pad, 1); - else - iowrite32_rep(data_addr, pad, 1); + memcpy(&pad, buf + buflen - slop, slop); + iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); } + words++; } - return (buflen + 1) & ~1; + return words << 2; } EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); diff --git a/trunk/drivers/ata/libata.h b/trunk/drivers/ata/libata.h index cea8014cd87e..fe2839e58774 100644 --- a/trunk/drivers/ata/libata.h +++ b/trunk/drivers/ata/libata.h @@ -79,6 +79,7 @@ extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, u64 block, u32 n_block, unsigned int tf_flags, unsigned int tag); extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev); +extern void ata_dev_disable(struct ata_device *dev); extern void ata_pio_queue_task(struct ata_port *ap, void *data, unsigned long delay); extern void ata_port_flush_task(struct ata_port *ap); @@ -99,7 +100,7 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags); extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, unsigned int readid_flags); extern int ata_dev_configure(struct ata_device *dev); -extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); +extern int sata_down_spd_limit(struct ata_link *link); extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); extern void ata_sg_clean(struct ata_queued_cmd *qc); extern void ata_qc_free(struct ata_queued_cmd *qc); @@ -159,7 +160,6 @@ extern void ata_scsi_error(struct Scsi_Host *host); extern void ata_port_wait_eh(struct ata_port *ap); extern void ata_eh_fastdrain_timerfn(unsigned long arg); extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc); -extern void ata_dev_disable(struct ata_device *dev); extern void ata_eh_detach_dev(struct ata_device *dev); extern void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev, unsigned int action); diff --git a/trunk/drivers/ata/pata_amd.c b/trunk/drivers/ata/pata_amd.c index 115b1cd6dcf5..63719ab9ea44 100644 --- a/trunk/drivers/ata/pata_amd.c +++ b/trunk/drivers/ata/pata_amd.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_amd" -#define DRV_VERSION "0.4.1" +#define DRV_VERSION "0.3.11" /** * timing_setup - shared timing computation and load @@ -145,13 +145,6 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline) return ata_sff_prereset(link, deadline); } -/** - * amd_cable_detect - report cable type - * @ap: port - * - * AMD controller/BIOS setups record the cable type in word 0x42 - */ - static int amd_cable_detect(struct ata_port *ap) { static const u32 bitmask[2] = {0x03, 0x0C}; @@ -164,40 +157,6 @@ static int amd_cable_detect(struct ata_port *ap) return ATA_CBL_PATA40; } -/** - * amd_fifo_setup - set the PIO FIFO for ATA/ATAPI - * @ap: ATA interface - * @adev: ATA device - * - * Set the PCI fifo for this device according to the devices present - * on the bus at this point in time. We need to turn the post write buffer - * off for ATAPI devices as we may need to issue a word sized write to the - * device as the final I/O - */ - -static void amd_fifo_setup(struct ata_port *ap) -{ - struct ata_device *adev; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - static const u8 fifobit[2] = { 0xC0, 0x30}; - u8 fifo = fifobit[ap->port_no]; - u8 r; - - - ata_for_each_dev(adev, &ap->link, ENABLED) { - if (adev->class == ATA_DEV_ATAPI) - fifo = 0; - } - if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) /* FIFO is broken */ - fifo = 0; - - /* On the later chips the read prefetch bits become no-op bits */ - pci_read_config_byte(pdev, 0x41, &r); - r &= ~fifobit[ap->port_no]; - r |= fifo; - pci_write_config_byte(pdev, 0x41, r); -} - /** * amd33_set_piomode - set initial PIO mode data * @ap: ATA interface @@ -208,25 +167,21 @@ static void amd_fifo_setup(struct ata_port *ap) static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev) { - amd_fifo_setup(ap); timing_setup(ap, adev, 0x40, adev->pio_mode, 1); } static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev) { - amd_fifo_setup(ap); timing_setup(ap, adev, 0x40, adev->pio_mode, 2); } static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev) { - amd_fifo_setup(ap); timing_setup(ap, adev, 0x40, adev->pio_mode, 3); } static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev) { - amd_fifo_setup(ap); timing_setup(ap, adev, 0x40, adev->pio_mode, 4); } @@ -442,16 +397,6 @@ static struct ata_port_operations nv133_port_ops = { .set_dmamode = nv133_set_dmamode, }; -static void amd_clear_fifo(struct pci_dev *pdev) -{ - u8 fifo; - /* Disable the FIFO, the FIFO logic will re-enable it as - appropriate */ - pci_read_config_byte(pdev, 0x41, &fifo); - fifo &= 0x0F; - pci_write_config_byte(pdev, 0x41, fifo); -} - static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info[10] = { @@ -558,8 +503,14 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (type < 3) ata_pci_bmdma_clear_simplex(pdev); - if (pdev->vendor == PCI_VENDOR_ID_AMD) - amd_clear_fifo(pdev); + + /* Check for AMD7411 */ + if (type == 3) + /* FIFO is broken */ + pci_write_config_byte(pdev, 0x41, fifo & 0x0F); + else + pci_write_config_byte(pdev, 0x41, fifo | 0xF0); + /* Cable detection on Nvidia chips doesn't work too well, * cache BIOS programmed UDMA mode. */ @@ -585,11 +536,18 @@ static int amd_reinit_one(struct pci_dev *pdev) return rc; if (pdev->vendor == PCI_VENDOR_ID_AMD) { - amd_clear_fifo(pdev); + u8 fifo; + pci_read_config_byte(pdev, 0x41, &fifo); + if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) + /* FIFO is broken */ + pci_write_config_byte(pdev, 0x41, fifo & 0x0F); + else + pci_write_config_byte(pdev, 0x41, fifo | 0xF0); if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 || pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401) ata_pci_bmdma_clear_simplex(pdev); } + ata_host_resume(host); return 0; } diff --git a/trunk/drivers/ata/pata_it821x.c b/trunk/drivers/ata/pata_it821x.c index b05b86a912c5..f1bb2f9fecbf 100644 --- a/trunk/drivers/ata/pata_it821x.c +++ b/trunk/drivers/ata/pata_it821x.c @@ -557,9 +557,6 @@ static unsigned int it821x_read_id(struct ata_device *adev, id[83] |= 0x4400; /* Word 83 is valid and LBA48 */ id[86] |= 0x0400; /* LBA48 on */ id[ATA_ID_MAJOR_VER] |= 0x1F; - /* Clear the serial number because it's different each boot - which breaks validation on resume */ - memset(&id[ATA_ID_SERNO], 0x20, ATA_ID_SERNO_LEN); } return err_mask; } diff --git a/trunk/drivers/ata/pata_legacy.c b/trunk/drivers/ata/pata_legacy.c index e3bc1b436284..6c1d778b63a9 100644 --- a/trunk/drivers/ata/pata_legacy.c +++ b/trunk/drivers/ata/pata_legacy.c @@ -283,10 +283,9 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, unsigned char *buf, unsigned int buflen, int rw) { - int slop = buflen & 3; - /* 32bit I/O capable *and* we need to write a whole number of dwords */ - if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) { + if (ata_id_has_dword_io(dev->id)) { struct ata_port *ap = dev->link->ap; + int slop = buflen & 3; unsigned long flags; local_irq_save(flags); @@ -736,7 +735,7 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf, struct ata_port *ap = adev->link->ap; int slop = buflen & 3; - if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) { + if (ata_id_has_dword_io(adev->id)) { if (rw == WRITE) iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); else diff --git a/trunk/drivers/ata/pata_qdi.c b/trunk/drivers/ata/pata_qdi.c index f1b26f7c8e4d..3080f371222c 100644 --- a/trunk/drivers/ata/pata_qdi.c +++ b/trunk/drivers/ata/pata_qdi.c @@ -12,7 +12,7 @@ * * Probe code based on drivers/ide/legacy/qd65xx.c * Rewritten from the work of Colten Edwards by - * Samuel Thibault + * Samuel Thibault */ #include diff --git a/trunk/drivers/ata/pata_via.c b/trunk/drivers/ata/pata_via.c index ba556d3e6963..79a6c9a0b721 100644 --- a/trunk/drivers/ata/pata_via.c +++ b/trunk/drivers/ata/pata_via.c @@ -110,8 +110,7 @@ static const struct via_isa_bridge { { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, - { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES }, - { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES }, + { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES}, { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, @@ -594,7 +593,6 @@ static int via_reinit_one(struct pci_dev *pdev) #endif static const struct pci_device_id via[] = { - { PCI_VDEVICE(VIA, 0x0415), }, { PCI_VDEVICE(VIA, 0x0571), }, { PCI_VDEVICE(VIA, 0x0581), }, { PCI_VDEVICE(VIA, 0x1571), }, diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 7007edd2d451..f2d8a020ea53 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -663,8 +663,8 @@ static const struct pci_device_id mv_pci_tbl[] = { { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, /* RocketRAID 1720/174x have different identifiers */ { PCI_VDEVICE(TTI, 0x1720), chip_6042 }, - { PCI_VDEVICE(TTI, 0x1740), chip_6042 }, - { PCI_VDEVICE(TTI, 0x1742), chip_6042 }, + { PCI_VDEVICE(TTI, 0x1740), chip_508x }, + { PCI_VDEVICE(TTI, 0x1742), chip_508x }, { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, @@ -3114,17 +3114,19 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); } - /* Clear any currently outstanding host interrupt conditions */ - writelfl(0, mmio + hpriv->irq_cause_ofs); + if (!IS_SOC(hpriv)) { + /* Clear any currently outstanding host interrupt conditions */ + writelfl(0, mmio + hpriv->irq_cause_ofs); - /* and unmask interrupt generation for host regs */ - writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); + /* and unmask interrupt generation for host regs */ + writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); - /* - * enable only global host interrupts for now. - * The per-port interrupts get done later as ports are set up. - */ - mv_set_main_irq_mask(host, 0, PCI_ERR); + /* + * enable only global host interrupts for now. + * The per-port interrupts get done later as ports are set up. + */ + mv_set_main_irq_mask(host, 0, PCI_ERR); + } done: return rc; } diff --git a/trunk/drivers/ata/sata_nv.c b/trunk/drivers/ata/sata_nv.c index 55a8eed3f3a3..c49ad0e61b6f 100644 --- a/trunk/drivers/ata/sata_nv.c +++ b/trunk/drivers/ata/sata_nv.c @@ -421,33 +421,26 @@ static struct ata_port_operations nv_generic_ops = { .hardreset = ATA_OP_NULL, }; -/* nf2 is ripe with hardreset related problems. - * - * kernel bz#3352 reports nf2/3 controllers can't determine device - * signature reliably. The following thread reports detection failure - * on cold boot with the standard debouncing timing. +/* OSDL bz3352 reports that nf2/3 controllers can't determine device + * signature reliably. Also, the following thread reports detection + * failure on cold boot with the standard debouncing timing. * * http://thread.gmane.org/gmane.linux.ide/34098 * - * And bz#12176 reports that hardreset simply doesn't work on nf2. - * Give up on it and just don't do hardreset. + * Debounce with hotplug timing and request follow-up SRST. */ static struct ata_port_operations nv_nf2_ops = { - .inherits = &nv_generic_ops, + .inherits = &nv_common_ops, .freeze = nv_nf2_freeze, .thaw = nv_nf2_thaw, + .hardreset = nv_noclassify_hardreset, }; -/* For initial probing after boot and hot plugging, hardreset mostly - * works fine on CK804 but curiously, reprobing on the initial port by - * rescanning or rmmod/insmod fails to acquire the initial D2H Reg FIS - * in somewhat undeterministic way. Use noclassify hardreset. - */ +/* CK804 finally gets hardreset right */ static struct ata_port_operations nv_ck804_ops = { .inherits = &nv_common_ops, .freeze = nv_ck804_freeze, .thaw = nv_ck804_thaw, - .hardreset = nv_noclassify_hardreset, .host_stop = nv_ck804_host_stop, }; diff --git a/trunk/drivers/ata/sata_sil.c b/trunk/drivers/ata/sata_sil.c index d0091609e210..9f029595f454 100644 --- a/trunk/drivers/ata/sata_sil.c +++ b/trunk/drivers/ata/sata_sil.c @@ -324,7 +324,7 @@ static void sil_fill_sg(struct ata_queued_cmd *qc) prd->addr = cpu_to_le32(addr); prd->flags_len = cpu_to_le32(sg_len); - VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", si, addr, sg_len); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, sg_len); last_prd = prd; prd++; diff --git a/trunk/drivers/base/base.h b/trunk/drivers/base/base.h index 9f50f1b545dc..0a5f055dffba 100644 --- a/trunk/drivers/base/base.h +++ b/trunk/drivers/base/base.h @@ -88,6 +88,8 @@ extern void driver_detach(struct device_driver *drv); extern int driver_probe_device(struct device_driver *drv, struct device *dev); extern void sysdev_shutdown(void); +extern int sysdev_suspend(pm_message_t state); +extern int sysdev_resume(void); extern char *make_class_name(const char *name, struct kobject *kobj); diff --git a/trunk/drivers/base/dd.c b/trunk/drivers/base/dd.c index 135231239103..315bed8d5e7f 100644 --- a/trunk/drivers/base/dd.c +++ b/trunk/drivers/base/dd.c @@ -18,11 +18,9 @@ */ #include -#include #include #include #include -#include #include "base.h" #include "power/power.h" @@ -169,21 +167,6 @@ int driver_probe_done(void) return 0; } -/** - * wait_for_device_probe - * Wait for device probing to be completed. - * - * Note: this function polls at 100 msec intervals. - */ -int wait_for_device_probe(void) -{ - /* wait for the known devices to complete their probing */ - while (driver_probe_done() != 0) - msleep(100); - async_synchronize_full(); - return 0; -} - /** * driver_probe_device - attempt to bind device & driver together * @drv: driver to bind a device to diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c index 2d14f4ae6c01..670c9d6c1407 100644 --- a/trunk/drivers/base/power/main.c +++ b/trunk/drivers/base/power/main.c @@ -333,6 +333,7 @@ static void dpm_power_up(pm_message_t state) */ void device_power_up(pm_message_t state) { + sysdev_resume(); dpm_power_up(state); } EXPORT_SYMBOL_GPL(device_power_up); @@ -576,6 +577,8 @@ int device_power_down(pm_message_t state) } dev->power.status = DPM_OFF_IRQ; } + if (!error) + error = sysdev_suspend(state); if (error) dpm_power_up(resume_event(state)); return error; diff --git a/trunk/drivers/base/sys.c b/trunk/drivers/base/sys.c index b428c8c4bc64..c98c31ec2f75 100644 --- a/trunk/drivers/base/sys.c +++ b/trunk/drivers/base/sys.c @@ -303,6 +303,7 @@ void sysdev_unregister(struct sys_device * sysdev) * is guaranteed by virtue of the fact that child devices are registered * after their parents. */ + void sysdev_shutdown(void) { struct sysdev_class * cls; @@ -362,6 +363,7 @@ static void __sysdev_resume(struct sys_device *dev) * This is only called by the device PM core, so we let them handle * all synchronization. */ + int sysdev_suspend(pm_message_t state) { struct sysdev_class * cls; @@ -430,7 +432,7 @@ int sysdev_suspend(pm_message_t state) } return ret; } -EXPORT_SYMBOL_GPL(sysdev_suspend); + /** * sysdev_resume - Bring system devices back to life. @@ -440,6 +442,7 @@ EXPORT_SYMBOL_GPL(sysdev_suspend); * * Note: Interrupts are disabled when called. */ + int sysdev_resume(void) { struct sysdev_class * cls; @@ -460,7 +463,7 @@ int sysdev_resume(void) } return 0; } -EXPORT_SYMBOL_GPL(sysdev_resume); + int __init system_bus_init(void) { diff --git a/trunk/drivers/block/aoe/aoe.h b/trunk/drivers/block/aoe/aoe.h index 5e41e6dd657b..c237527b1aa5 100644 --- a/trunk/drivers/block/aoe/aoe.h +++ b/trunk/drivers/block/aoe/aoe.h @@ -18,7 +18,6 @@ enum { AOECMD_ATA, AOECMD_CFG, - AOECMD_VEND_MIN = 0xf0, AOEFL_RSP = (1<<3), AOEFL_ERR = (1<<2), diff --git a/trunk/drivers/block/aoe/aoenet.c b/trunk/drivers/block/aoe/aoenet.c index c6099ba9a4b8..30de5b1c647e 100644 --- a/trunk/drivers/block/aoe/aoenet.c +++ b/trunk/drivers/block/aoe/aoenet.c @@ -142,8 +142,6 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, aoecmd_cfg_rsp(skb); break; default: - if (h->cmd >= AOECMD_VEND_MIN) - break; /* don't complain about vendor commands */ printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd); } exit: diff --git a/trunk/drivers/block/ataflop.c b/trunk/drivers/block/ataflop.c index 4234c11c1e4c..69e1df7dfa14 100644 --- a/trunk/drivers/block/ataflop.c +++ b/trunk/drivers/block/ataflop.c @@ -1730,7 +1730,7 @@ static int __init fd_test_drive_present( int drive ) timeout = jiffies + 2*HZ+HZ/2; while (time_before(jiffies, timeout)) - if (!(st_mfp.par_dt_reg & 0x20)) + if (!(mfp.par_dt_reg & 0x20)) break; status = FDC_READ( FDCREG_STATUS ); @@ -1747,7 +1747,7 @@ static int __init fd_test_drive_present( int drive ) /* dummy seek command to make WP bit accessible */ FDC_WRITE( FDCREG_DATA, 0 ); FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK ); - while( st_mfp.par_dt_reg & 0x20 ) + while( mfp.par_dt_reg & 0x20 ) ; status = FDC_READ( FDCREG_STATUS ); } diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index b5a061114630..01e69383d9c0 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -3390,203 +3390,6 @@ static void free_hba(int i) kfree(p); } -/* Send a message CDB to the firmware. */ -static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, unsigned char type) -{ - typedef struct { - CommandListHeader_struct CommandHeader; - RequestBlock_struct Request; - ErrDescriptor_struct ErrorDescriptor; - } Command; - static const size_t cmd_sz = sizeof(Command) + sizeof(ErrorInfo_struct); - Command *cmd; - dma_addr_t paddr64; - uint32_t paddr32, tag; - void __iomem *vaddr; - int i, err; - - vaddr = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); - if (vaddr == NULL) - return -ENOMEM; - - /* The Inbound Post Queue only accepts 32-bit physical addresses for the - CCISS commands, so they must be allocated from the lower 4GiB of - memory. */ - err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); - if (err) { - iounmap(vaddr); - return -ENOMEM; - } - - cmd = pci_alloc_consistent(pdev, cmd_sz, &paddr64); - if (cmd == NULL) { - iounmap(vaddr); - return -ENOMEM; - } - - /* This must fit, because of the 32-bit consistent DMA mask. Also, - although there's no guarantee, we assume that the address is at - least 4-byte aligned (most likely, it's page-aligned). */ - paddr32 = paddr64; - - cmd->CommandHeader.ReplyQueue = 0; - cmd->CommandHeader.SGList = 0; - cmd->CommandHeader.SGTotal = 0; - cmd->CommandHeader.Tag.lower = paddr32; - cmd->CommandHeader.Tag.upper = 0; - memset(&cmd->CommandHeader.LUN.LunAddrBytes, 0, 8); - - cmd->Request.CDBLen = 16; - cmd->Request.Type.Type = TYPE_MSG; - cmd->Request.Type.Attribute = ATTR_HEADOFQUEUE; - cmd->Request.Type.Direction = XFER_NONE; - cmd->Request.Timeout = 0; /* Don't time out */ - cmd->Request.CDB[0] = opcode; - cmd->Request.CDB[1] = type; - memset(&cmd->Request.CDB[2], 0, 14); /* the rest of the CDB is reserved */ - - cmd->ErrorDescriptor.Addr.lower = paddr32 + sizeof(Command); - cmd->ErrorDescriptor.Addr.upper = 0; - cmd->ErrorDescriptor.Len = sizeof(ErrorInfo_struct); - - writel(paddr32, vaddr + SA5_REQUEST_PORT_OFFSET); - - for (i = 0; i < 10; i++) { - tag = readl(vaddr + SA5_REPLY_PORT_OFFSET); - if ((tag & ~3) == paddr32) - break; - schedule_timeout_uninterruptible(HZ); - } - - iounmap(vaddr); - - /* we leak the DMA buffer here ... no choice since the controller could - still complete the command. */ - if (i == 10) { - printk(KERN_ERR "cciss: controller message %02x:%02x timed out\n", - opcode, type); - return -ETIMEDOUT; - } - - pci_free_consistent(pdev, cmd_sz, cmd, paddr64); - - if (tag & 2) { - printk(KERN_ERR "cciss: controller message %02x:%02x failed\n", - opcode, type); - return -EIO; - } - - printk(KERN_INFO "cciss: controller message %02x:%02x succeeded\n", - opcode, type); - return 0; -} - -#define cciss_soft_reset_controller(p) cciss_message(p, 1, 0) -#define cciss_noop(p) cciss_message(p, 3, 0) - -static __devinit int cciss_reset_msi(struct pci_dev *pdev) -{ -/* the #defines are stolen from drivers/pci/msi.h. */ -#define msi_control_reg(base) (base + PCI_MSI_FLAGS) -#define PCI_MSIX_FLAGS_ENABLE (1 << 15) - - int pos; - u16 control = 0; - - pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); - if (pos) { - pci_read_config_word(pdev, msi_control_reg(pos), &control); - if (control & PCI_MSI_FLAGS_ENABLE) { - printk(KERN_INFO "cciss: resetting MSI\n"); - pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE); - } - } - - pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); - if (pos) { - pci_read_config_word(pdev, msi_control_reg(pos), &control); - if (control & PCI_MSIX_FLAGS_ENABLE) { - printk(KERN_INFO "cciss: resetting MSI-X\n"); - pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); - } - } - - return 0; -} - -/* This does a hard reset of the controller using PCI power management - * states. */ -static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev) -{ - u16 pmcsr, saved_config_space[32]; - int i, pos; - - printk(KERN_INFO "cciss: using PCI PM to reset controller\n"); - - /* This is very nearly the same thing as - - pci_save_state(pci_dev); - pci_set_power_state(pci_dev, PCI_D3hot); - pci_set_power_state(pci_dev, PCI_D0); - pci_restore_state(pci_dev); - - but we can't use these nice canned kernel routines on - kexec, because they also check the MSI/MSI-X state in PCI - configuration space and do the wrong thing when it is - set/cleared. Also, the pci_save/restore_state functions - violate the ordering requirements for restoring the - configuration space from the CCISS document (see the - comment below). So we roll our own .... */ - - for (i = 0; i < 32; i++) - pci_read_config_word(pdev, 2*i, &saved_config_space[i]); - - pos = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pos == 0) { - printk(KERN_ERR "cciss_reset_controller: PCI PM not supported\n"); - return -ENODEV; - } - - /* Quoting from the Open CISS Specification: "The Power - * Management Control/Status Register (CSR) controls the power - * state of the device. The normal operating state is D0, - * CSR=00h. The software off state is D3, CSR=03h. To reset - * the controller, place the interface device in D3 then to - * D0, this causes a secondary PCI reset which will reset the - * controller." */ - - /* enter the D3hot power management state */ - pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); - pmcsr &= ~PCI_PM_CTRL_STATE_MASK; - pmcsr |= PCI_D3hot; - pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); - - schedule_timeout_uninterruptible(HZ >> 1); - - /* enter the D0 power management state */ - pmcsr &= ~PCI_PM_CTRL_STATE_MASK; - pmcsr |= PCI_D0; - pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); - - schedule_timeout_uninterruptible(HZ >> 1); - - /* Restore the PCI configuration space. The Open CISS - * Specification says, "Restore the PCI Configuration - * Registers, offsets 00h through 60h. It is important to - * restore the command register, 16-bits at offset 04h, - * last. Do not restore the configuration status register, - * 16-bits at offset 06h." Note that the offset is 2*i. */ - for (i = 0; i < 32; i++) { - if (i == 2 || i == 3) - continue; - pci_write_config_word(pdev, 2*i, saved_config_space[i]); - } - wmb(); - pci_write_config_word(pdev, 4, saved_config_space[2]); - - return 0; -} - /* * This is it. Find all the controllers and register them. I really hate * stealing all these major device numbers. @@ -3601,28 +3404,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, int dac, return_code; InquiryData_struct *inq_buff = NULL; - if (reset_devices) { - /* Reset the controller with a PCI power-cycle */ - if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) - return -ENODEV; - - /* Some devices (notably the HP Smart Array 5i Controller) - need a little pause here */ - schedule_timeout_uninterruptible(30*HZ); - - /* Now try to get the controller to respond to a no-op */ - for (i=0; i<30; i++) { - if (cciss_noop(pdev) == 0) - break; - - schedule_timeout_uninterruptible(HZ); - } - if (i == 30) { - printk(KERN_ERR "cciss: controller seems dead\n"); - return -EBUSY; - } - } - i = alloc_cciss_hba(); if (i < 0) return -1; diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 83d8ed39433d..cf29cc4e6ab7 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -558,8 +558,6 @@ static void process_fd_request(void); static void recalibrate_floppy(void); static void floppy_shutdown(unsigned long); -static int floppy_request_regions(int); -static void floppy_release_regions(int); static int floppy_grab_irq_and_dma(void); static void floppy_release_irq_and_dma(void); @@ -4276,7 +4274,8 @@ static int __init floppy_init(void) FDCS->rawcmd = 2; if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) { /* free ioports reserved by floppy_grab_irq_and_dma() */ - floppy_release_regions(fdc); + release_region(FDCS->address + 2, 4); + release_region(FDCS->address + 7, 1); FDCS->address = -1; FDCS->version = FDC_NONE; continue; @@ -4285,7 +4284,8 @@ static int __init floppy_init(void) FDCS->version = get_fdc_version(); if (FDCS->version == FDC_NONE) { /* free ioports reserved by floppy_grab_irq_and_dma() */ - floppy_release_regions(fdc); + release_region(FDCS->address + 2, 4); + release_region(FDCS->address + 7, 1); FDCS->address = -1; continue; } @@ -4358,47 +4358,6 @@ static int __init floppy_init(void) static DEFINE_SPINLOCK(floppy_usage_lock); -static const struct io_region { - int offset; - int size; -} io_regions[] = { - { 2, 1 }, - /* address + 3 is sometimes reserved by pnp bios for motherboard */ - { 4, 2 }, - /* address + 6 is reserved, and may be taken by IDE. - * Unfortunately, Adaptec doesn't know this :-(, */ - { 7, 1 }, -}; - -static void floppy_release_allocated_regions(int fdc, const struct io_region *p) -{ - while (p != io_regions) { - p--; - release_region(FDCS->address + p->offset, p->size); - } -} - -#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)])) - -static int floppy_request_regions(int fdc) -{ - const struct io_region *p; - - for (p = io_regions; p < ARRAY_END(io_regions); p++) { - if (!request_region(FDCS->address + p->offset, p->size, "floppy")) { - DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset); - floppy_release_allocated_regions(fdc, p); - return -EBUSY; - } - } - return 0; -} - -static void floppy_release_regions(int fdc) -{ - floppy_release_allocated_regions(fdc, ARRAY_END(io_regions)); -} - static int floppy_grab_irq_and_dma(void) { unsigned long flags; @@ -4440,8 +4399,18 @@ static int floppy_grab_irq_and_dma(void) for (fdc = 0; fdc < N_FDC; fdc++) { if (FDCS->address != -1) { - if (floppy_request_regions(fdc)) - goto cleanup; + if (!request_region(FDCS->address + 2, 4, "floppy")) { + DPRINT("Floppy io-port 0x%04lx in use\n", + FDCS->address + 2); + goto cleanup1; + } + if (!request_region(FDCS->address + 7, 1, "floppy DIR")) { + DPRINT("Floppy io-port 0x%04lx in use\n", + FDCS->address + 7); + goto cleanup2; + } + /* address + 6 is reserved, and may be taken by IDE. + * Unfortunately, Adaptec doesn't know this :-(, */ } } for (fdc = 0; fdc < N_FDC; fdc++) { @@ -4463,11 +4432,15 @@ static int floppy_grab_irq_and_dma(void) fdc = 0; irqdma_allocated = 1; return 0; -cleanup: +cleanup2: + release_region(FDCS->address + 2, 4); +cleanup1: fd_free_irq(); fd_free_dma(); - while (--fdc >= 0) - floppy_release_regions(fdc); + while (--fdc >= 0) { + release_region(FDCS->address + 2, 4); + release_region(FDCS->address + 7, 1); + } spin_lock_irqsave(&floppy_usage_lock, flags); usage_count--; spin_unlock_irqrestore(&floppy_usage_lock, flags); @@ -4528,8 +4501,10 @@ static void floppy_release_irq_and_dma(void) #endif old_fdc = fdc; for (fdc = 0; fdc < N_FDC; fdc++) - if (FDCS->address != -1) - floppy_release_regions(fdc); + if (FDCS->address != -1) { + release_region(FDCS->address + 2, 4); + release_region(FDCS->address + 7, 1); + } fdc = old_fdc; } diff --git a/trunk/drivers/block/nbd.c b/trunk/drivers/block/nbd.c index 8299e2d3b611..34f80fa6fed1 100644 --- a/trunk/drivers/block/nbd.c +++ b/trunk/drivers/block/nbd.c @@ -549,15 +549,6 @@ static void do_nbd_request(struct request_queue * q) BUG_ON(lo->magic != LO_MAGIC); - if (unlikely(!lo->sock)) { - printk(KERN_ERR "%s: Attempted send on closed socket\n", - lo->disk->disk_name); - req->errors++; - nbd_end_request(req); - spin_lock_irq(q->queue_lock); - continue; - } - spin_lock_irq(&lo->queue_lock); list_add_tail(&req->queuelist, &lo->waiting_queue); spin_unlock_irq(&lo->queue_lock); diff --git a/trunk/drivers/block/paride/pg.c b/trunk/drivers/block/paride/pg.c index c397b3ddba9b..9dfa27163001 100644 --- a/trunk/drivers/block/paride/pg.c +++ b/trunk/drivers/block/paride/pg.c @@ -422,7 +422,7 @@ static void xs(char *buf, char *targ, int len) for (k = 0; k < len; k++) { char c = *buf++; - if (c != ' ' && c != l) + if (c != ' ' || c != l) l = *targ++ = c; } if (l == ' ') diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c index b6c8ce254359..918ef725de41 100644 --- a/trunk/drivers/block/xen-blkfront.c +++ b/trunk/drivers/block/xen-blkfront.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -83,7 +82,6 @@ struct blkfront_info enum blkif_state connected; int ring_ref; struct blkif_front_ring ring; - struct scatterlist sg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int evtchn, irq; struct request_queue *rq; struct work_struct work; @@ -206,11 +204,12 @@ static int blkif_queue_request(struct request *req) struct blkfront_info *info = req->rq_disk->private_data; unsigned long buffer_mfn; struct blkif_request *ring_req; + struct req_iterator iter; + struct bio_vec *bvec; unsigned long id; unsigned int fsect, lsect; - int i, ref; + int ref; grant_ref_t gref_head; - struct scatterlist *sg; if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) return 1; @@ -239,13 +238,12 @@ static int blkif_queue_request(struct request *req) if (blk_barrier_rq(req)) ring_req->operation = BLKIF_OP_WRITE_BARRIER; - ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); - BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); - - for_each_sg(info->sg, sg, ring_req->nr_segments, i) { - buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg))); - fsect = sg->offset >> 9; - lsect = fsect + (sg->length >> 9) - 1; + ring_req->nr_segments = 0; + rq_for_each_segment(bvec, req, iter) { + BUG_ON(ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST); + buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page)); + fsect = bvec->bv_offset >> 9; + lsect = fsect + (bvec->bv_len >> 9) - 1; /* install a grant reference. */ ref = gnttab_claim_grant_reference(&gref_head); BUG_ON(ref == -ENOSPC); @@ -256,12 +254,16 @@ static int blkif_queue_request(struct request *req) buffer_mfn, rq_data_dir(req) ); - info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn); - ring_req->seg[i] = + info->shadow[id].frame[ring_req->nr_segments] = + mfn_to_pfn(buffer_mfn); + + ring_req->seg[ring_req->nr_segments] = (struct blkif_request_segment) { .gref = ref, .first_sect = fsect, .last_sect = lsect }; + + ring_req->nr_segments++; } info->ring.req_prod_pvt++; @@ -620,8 +622,6 @@ static int setup_blkring(struct xenbus_device *dev, SHARED_RING_INIT(sring); FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE); - sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST); - err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring)); if (err < 0) { free_page((unsigned long)sring); diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 735bbe2be51a..f5be8081cd81 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -761,7 +761,7 @@ source "drivers/char/hw_random/Kconfig" config NVRAM tristate "/dev/nvram support" - depends on ATARI || X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM + depends on ATARI || X86 || ARM || GENERIC_NVRAM ---help--- If you say Y here and create a character special file /dev/nvram with major number 10 and minor number 144 using mknod ("man mknod"), diff --git a/trunk/drivers/char/scc.h b/trunk/drivers/char/scc.h index 341b1142bea8..93998f5baff5 100644 --- a/trunk/drivers/char/scc.h +++ b/trunk/drivers/char/scc.h @@ -387,7 +387,7 @@ struct scc_port { /* The SCC needs 3.5 PCLK cycles recovery time between to register * accesses. PCLK runs with 8 MHz on an Atari, so this delay is 3.5 * * 125 ns = 437.5 ns. This is too short for udelay(). - * 10/16/95: A tstb st_mfp.par_dt_reg takes 600ns (sure?) and thus should be + * 10/16/95: A tstb mfp.par_dt_reg takes 600ns (sure?) and thus should be * quite right */ diff --git a/trunk/drivers/char/sx.c b/trunk/drivers/char/sx.c index 518f2a25d91e..b60be7b0decf 100644 --- a/trunk/drivers/char/sx.c +++ b/trunk/drivers/char/sx.c @@ -1713,8 +1713,8 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, for (i = 0; i < SX_NBOARDS; i++) sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); sx_dprintk(SX_DEBUG_FIRMWARE, "\n"); - rc = -EIO; - goto out; + unlock_kernel(); + return -EIO; } switch (cmd) { @@ -1746,10 +1746,8 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc); break; case SXIO_DO_RAMTEST: - if (sx_initialized) { /* Already initialized: better not ramtest the board. */ - rc = -EPERM; - break; - } + if (sx_initialized) /* Already initialized: better not ramtest the board. */ + return -EPERM; if (IS_SX_BOARD(board)) { rc = do_memtest(board, 0, 0x7000); if (!rc) @@ -1789,7 +1787,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, nbytes - i : SX_CHUNK_SIZE)) { kfree(tmp); rc = -EFAULT; - goto out; + break; } memcpy_toio(board->base2 + offset + i, tmp, (i + SX_CHUNK_SIZE > nbytes) ? @@ -1846,7 +1844,6 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, rc = -ENOTTY; break; } -out: unlock_kernel(); func_exit(); return rc; diff --git a/trunk/drivers/char/tpm/tpm_infineon.c b/trunk/drivers/char/tpm/tpm_infineon.c index ecba4942fc8e..726ee8a0277f 100644 --- a/trunk/drivers/char/tpm/tpm_infineon.c +++ b/trunk/drivers/char/tpm/tpm_infineon.c @@ -4,7 +4,7 @@ * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module * Specifications at www.trustedcomputinggroup.org * - * Copyright (C) 2005, Marcel Selhorst + * Copyright (C) 2005, Marcel Selhorst * Sirrix AG - security technologies, http://www.sirrix.com and * Applied Data Security Group, Ruhr-University Bochum, Germany * Project-Homepage: http://www.prosec.rub.de/tpm @@ -636,7 +636,7 @@ static void __exit cleanup_inf(void) module_init(init_inf); module_exit(cleanup_inf); -MODULE_AUTHOR("Marcel Selhorst "); +MODULE_AUTHOR("Marcel Selhorst "); MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); MODULE_VERSION("1.9"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/cpufreq/cpufreq_ondemand.c b/trunk/drivers/cpufreq/cpufreq_ondemand.c index 6f45b1658a67..6a2b036c9389 100644 --- a/trunk/drivers/cpufreq/cpufreq_ondemand.c +++ b/trunk/drivers/cpufreq/cpufreq_ondemand.c @@ -117,7 +117,11 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu, busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq); busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq); busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal); - busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.nice); + + if (!dbs_tuners_ins.ignore_nice) { + busy_time = cputime64_add(busy_time, + kstat_cpu(cpu).cpustat.nice); + } idle_time = cputime64_sub(cur_wall_time, busy_time); if (wall) @@ -133,6 +137,23 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) if (idle_time == -1ULL) return get_cpu_idle_time_jiffy(cpu, wall); + if (dbs_tuners_ins.ignore_nice) { + cputime64_t cur_nice; + unsigned long cur_nice_jiffies; + struct cpu_dbs_info_s *dbs_info; + + dbs_info = &per_cpu(cpu_dbs_info, cpu); + cur_nice = cputime64_sub(kstat_cpu(cpu).cpustat.nice, + dbs_info->prev_cpu_nice); + /* + * Assumption: nice time between sampling periods will be + * less than 2^32 jiffies for 32 bit sys + */ + cur_nice_jiffies = (unsigned long) + cputime64_to_jiffies64(cur_nice); + dbs_info->prev_cpu_nice = kstat_cpu(cpu).cpustat.nice; + return idle_time + jiffies_to_usecs(cur_nice_jiffies); + } return idle_time; } @@ -298,9 +319,6 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, dbs_info = &per_cpu(cpu_dbs_info, j); dbs_info->prev_cpu_idle = get_cpu_idle_time(j, &dbs_info->prev_cpu_wall); - if (dbs_tuners_ins.ignore_nice) - dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice; - } mutex_unlock(&dbs_mutex); @@ -401,23 +419,6 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) j_dbs_info->prev_cpu_idle); j_dbs_info->prev_cpu_idle = cur_idle_time; - if (dbs_tuners_ins.ignore_nice) { - cputime64_t cur_nice; - unsigned long cur_nice_jiffies; - - cur_nice = cputime64_sub(kstat_cpu(j).cpustat.nice, - j_dbs_info->prev_cpu_nice); - /* - * Assumption: nice time between sampling periods will - * be less than 2^32 jiffies for 32 bit sys - */ - cur_nice_jiffies = (unsigned long) - cputime64_to_jiffies64(cur_nice); - - j_dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice; - idle_time += jiffies_to_usecs(cur_nice_jiffies); - } - if (unlikely(!wall_time || wall_time < idle_time)) continue; @@ -574,10 +575,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j, &j_dbs_info->prev_cpu_wall); - if (dbs_tuners_ins.ignore_nice) { - j_dbs_info->prev_cpu_nice = - kstat_cpu(j).cpustat.nice; - } } this_dbs_info->cpu = cpu; /* diff --git a/trunk/drivers/dma/dmaengine.c b/trunk/drivers/dma/dmaengine.c index 280a9d263eb3..a58993011edb 100644 --- a/trunk/drivers/dma/dmaengine.c +++ b/trunk/drivers/dma/dmaengine.c @@ -518,7 +518,6 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v dma_chan_name(chan), err); else break; - chan->private = NULL; chan = NULL; } } @@ -537,7 +536,6 @@ void dma_release_channel(struct dma_chan *chan) WARN_ONCE(chan->client_count != 1, "chan reference count %d != 1\n", chan->client_count); dma_chan_put(chan); - chan->private = NULL; mutex_unlock(&dma_list_mutex); } EXPORT_SYMBOL_GPL(dma_release_channel); diff --git a/trunk/drivers/dma/dw_dmac.c b/trunk/drivers/dma/dw_dmac.c index a97c07eef7ec..6b702cc46b3d 100644 --- a/trunk/drivers/dma/dw_dmac.c +++ b/trunk/drivers/dma/dw_dmac.c @@ -560,7 +560,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, unsigned long flags) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); - struct dw_dma_slave *dws = chan->private; + struct dw_dma_slave *dws = dwc->dws; struct dw_desc *prev; struct dw_desc *first; u32 ctllo; @@ -790,7 +790,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) cfghi = DWC_CFGH_FIFO_MODE; cfglo = 0; - dws = chan->private; + dws = dwc->dws; if (dws) { /* * We need controller-specific data to set up slave @@ -866,6 +866,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) spin_lock_bh(&dwc->lock); list_splice_init(&dwc->free_list, &list); dwc->descs_allocated = 0; + dwc->dws = NULL; /* Disable interrupts */ channel_clear_bit(dw, MASK.XFER, dwc->mask); diff --git a/trunk/drivers/dma/dw_dmac_regs.h b/trunk/drivers/dma/dw_dmac_regs.h index b252b202c5cf..00fdd187bb0c 100644 --- a/trunk/drivers/dma/dw_dmac_regs.h +++ b/trunk/drivers/dma/dw_dmac_regs.h @@ -139,6 +139,8 @@ struct dw_dma_chan { struct list_head queue; struct list_head free_list; + struct dw_dma_slave *dws; + unsigned int descs_allocated; }; diff --git a/trunk/drivers/firewire/fw-card.c b/trunk/drivers/firewire/fw-card.c index a5dd7a665aa8..7be2cf3514e7 100644 --- a/trunk/drivers/firewire/fw-card.c +++ b/trunk/drivers/firewire/fw-card.c @@ -412,7 +412,6 @@ fw_card_add(struct fw_card *card, { u32 *config_rom; size_t length; - int err; card->max_receive = max_receive; card->link_speed = link_speed; @@ -423,13 +422,7 @@ fw_card_add(struct fw_card *card, list_add_tail(&card->link, &card_list); mutex_unlock(&card_mutex); - err = card->driver->enable(card, config_rom, length); - if (err < 0) { - mutex_lock(&card_mutex); - list_del(&card->link); - mutex_unlock(&card_mutex); - } - return err; + return card->driver->enable(card, config_rom, length); } EXPORT_SYMBOL(fw_card_add); diff --git a/trunk/drivers/firmware/memmap.c b/trunk/drivers/firmware/memmap.c index 05aa2d406ac6..261b9aa3f248 100644 --- a/trunk/drivers/firmware/memmap.c +++ b/trunk/drivers/firmware/memmap.c @@ -1,7 +1,7 @@ /* * linux/drivers/firmware/memmap.c * Copyright (C) 2008 SUSE LINUX Products GmbH - * by Bernhard Walle + * by Bernhard Walle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License v2.0 as published by diff --git a/trunk/drivers/gpu/drm/Kconfig b/trunk/drivers/gpu/drm/Kconfig index 3a22eb9be378..5130b72d593c 100644 --- a/trunk/drivers/gpu/drm/Kconfig +++ b/trunk/drivers/gpu/drm/Kconfig @@ -70,7 +70,7 @@ config DRM_I915 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB + depends on FB tristate "i915 driver" help Choose this option if you have a system that has Intel 830M, 845G, @@ -80,17 +80,18 @@ config DRM_I915 XFree86 4.4 and above. If unsure, build this and i830 as modules and the X server will load the correct one. +endchoice + config DRM_I915_KMS bool "Enable modesetting on intel by default" depends on DRM_I915 help - Choose this option if you want kernel modesetting enabled by default, - and you have a new enough userspace to support this. Running old - userspaces with this enabled will cause pain. Note that this causes - the driver to bind to PCI devices, which precludes loading things - like intelfb. + Choose this option if you want kernel modesetting enabled by default, + and you have a new enough userspace to support this. Running old + userspaces with this enabled will cause pain. Note that this causes + the driver to bind to PCI devices, which precludes loading things + like intelfb. -endchoice config DRM_MGA tristate "Matrox g200/g400" diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index 94a768871734..bfce0992fefb 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -1741,8 +1741,9 @@ int drm_mode_getfb(struct drm_device *dev, * RETURNS: * Zero on success, errno on failure. */ -void drm_fb_release(struct drm_file *priv) +void drm_fb_release(struct file *filp) { + struct drm_file *priv = filp->private_data; struct drm_device *dev = priv->minor->dev; struct drm_framebuffer *fb, *tfb; diff --git a/trunk/drivers/gpu/drm/drm_crtc_helper.c b/trunk/drivers/gpu/drm/drm_crtc_helper.c index 1c3a8c557140..964c5eb1fada 100644 --- a/trunk/drivers/gpu/drm/drm_crtc_helper.c +++ b/trunk/drivers/gpu/drm/drm_crtc_helper.c @@ -452,59 +452,6 @@ static void drm_setup_crtcs(struct drm_device *dev) kfree(modes); kfree(enabled); } - -/** - * drm_encoder_crtc_ok - can a given crtc drive a given encoder? - * @encoder: encoder to test - * @crtc: crtc to test - * - * Return false if @encoder can't be driven by @crtc, true otherwise. - */ -static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, - struct drm_crtc *crtc) -{ - struct drm_device *dev; - struct drm_crtc *tmp; - int crtc_mask = 1; - - WARN(!crtc, "checking null crtc?"); - - dev = crtc->dev; - - list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { - if (tmp == crtc) - break; - crtc_mask <<= 1; - } - - if (encoder->possible_crtcs & crtc_mask) - return true; - return false; -} - -/* - * Check the CRTC we're going to map each output to vs. its current - * CRTC. If they don't match, we have to disable the output and the CRTC - * since the driver will have to re-route things. - */ -static void -drm_crtc_prepare_encoders(struct drm_device *dev) -{ - struct drm_encoder_helper_funcs *encoder_funcs; - struct drm_encoder *encoder; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - encoder_funcs = encoder->helper_private; - /* Disable unused encoders */ - if (encoder->crtc == NULL) - (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); - /* Disable encoders whose CRTC is about to change */ - if (encoder_funcs->get_crtc && - encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) - (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); - } -} - /** * drm_crtc_set_mode - set a mode * @crtc: CRTC to program @@ -565,8 +512,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, if (drm_mode_equal(&saved_mode, &crtc->mode)) { if (saved_x != crtc->x || saved_y != crtc->y || depth_changed || bpp_changed) { - ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, - old_fb); + crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, + old_fb); goto done; } } @@ -600,16 +547,12 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, encoder_funcs->prepare(encoder); } - drm_crtc_prepare_encoders(dev); - crtc_funcs->prepare(crtc); /* Set up the DPLL and any encoders state that needs to adjust or depend * on the DPLL. */ - ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); - if (!ret) - goto done; + crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { @@ -672,7 +615,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) struct drm_device *dev; struct drm_crtc **save_crtcs, *new_crtc; struct drm_encoder **save_encoders, *new_encoder; - struct drm_framebuffer *old_fb = NULL; + struct drm_framebuffer *old_fb; bool save_enabled; bool mode_changed = false; bool fb_changed = false; @@ -723,10 +666,9 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) * and then just flip_or_move it */ if (set->crtc->fb != set->fb) { /* If we have no fb then treat it as a full mode set */ - if (set->crtc->fb == NULL) { - DRM_DEBUG("crtc has no fb, full mode set\n"); + if (set->crtc->fb == NULL) mode_changed = true; - } else if ((set->fb->bits_per_pixel != + else if ((set->fb->bits_per_pixel != set->crtc->fb->bits_per_pixel) || set->fb->depth != set->crtc->fb->depth) fb_changed = true; @@ -738,7 +680,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) fb_changed = true; if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { - DRM_DEBUG("modes are different, full mode set\n"); + DRM_DEBUG("modes are different\n"); drm_mode_debug_printmodeline(&set->crtc->mode); drm_mode_debug_printmodeline(set->mode); mode_changed = true; @@ -764,7 +706,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) } if (new_encoder != connector->encoder) { - DRM_DEBUG("encoder changed, full mode switch\n"); mode_changed = true; connector->encoder = new_encoder; } @@ -791,20 +732,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) if (set->connectors[ro] == connector) new_crtc = set->crtc; } - - /* Make sure the new CRTC will work with the encoder */ - if (new_crtc && - !drm_encoder_crtc_ok(connector->encoder, new_crtc)) { - ret = -EINVAL; - goto fail_set_mode; - } if (new_crtc != connector->encoder->crtc) { - DRM_DEBUG("crtc changed, full mode switch\n"); mode_changed = true; connector->encoder->crtc = new_crtc; } - DRM_DEBUG("setting connector %d crtc to %p\n", - connector->base.id, new_crtc); } /* mode_set_base is not a required function */ @@ -821,8 +752,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) if (!drm_crtc_helper_set_mode(set->crtc, set->mode, set->x, set->y, old_fb)) { - DRM_ERROR("failed to set mode on crtc %p\n", - set->crtc); ret = -EINVAL; goto fail_set_mode; } @@ -836,10 +765,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) old_fb = set->crtc->fb; if (set->crtc->fb != set->fb) set->crtc->fb = set->fb; - ret = crtc_funcs->mode_set_base(set->crtc, - set->x, set->y, old_fb); - if (ret != 0) - goto fail_set_mode; + crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb); } kfree(save_encoders); @@ -848,14 +774,9 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) fail_set_mode: set->crtc->enabled = save_enabled; - set->crtc->fb = old_fb; count = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (!connector->encoder) - continue; - + list_for_each_entry(connector, &dev->mode_config.connector_list, head) connector->encoder->crtc = save_crtcs[count++]; - } fail_no_encoder: kfree(save_crtcs); count = 0; diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index a839a28d8ee6..5a4d3244758a 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -125,7 +125,7 @@ static bool edid_is_valid(struct edid *edid) DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); goto bad; } - if (edid->revision > 3) { + if (edid->revision <= 0 || edid->revision > 3) { DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision); goto bad; } @@ -320,10 +320,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo); mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo; - mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 4) | + mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 8) | pt->vsync_offset_lo); mode->vsync_end = mode->vsync_start + - ((pt->vsync_pulse_width_hi << 4) | + ((pt->vsync_pulse_width_hi << 8) | pt->vsync_pulse_width_lo); mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo); diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 6c020fe5431c..b06a53715853 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -457,9 +457,6 @@ int drm_release(struct inode *inode, struct file *filp) if (dev->driver->driver_features & DRIVER_GEM) drm_gem_release(dev, file_priv); - if (dev->driver->driver_features & DRIVER_MODESET) - drm_fb_release(file_priv); - mutex_lock(&dev->ctxlist_mutex); if (!list_empty(&dev->ctxlist)) { struct drm_ctx_list *pos, *n; diff --git a/trunk/drivers/gpu/drm/drm_gem.c b/trunk/drivers/gpu/drm/drm_gem.c index 88d3368ffddd..6915fb82d0b0 100644 --- a/trunk/drivers/gpu/drm/drm_gem.c +++ b/trunk/drivers/gpu/drm/drm_gem.c @@ -104,8 +104,8 @@ drm_gem_init(struct drm_device *dev) if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START, DRM_FILE_PAGE_OFFSET_SIZE)) { - drm_ht_remove(&mm->offset_hash); drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM); + drm_ht_remove(&mm->offset_hash); return -ENOMEM; } @@ -295,37 +295,35 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data, return -EBADF; again: - if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) { - ret = -ENOMEM; - goto err; - } + if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) + return -ENOMEM; spin_lock(&dev->object_name_lock); - if (!obj->name) { - ret = idr_get_new_above(&dev->object_name_idr, obj, 1, - &obj->name); - args->name = (uint64_t) obj->name; + if (obj->name) { + args->name = obj->name; spin_unlock(&dev->object_name_lock); + return 0; + } + ret = idr_get_new_above(&dev->object_name_idr, obj, 1, + &obj->name); + spin_unlock(&dev->object_name_lock); + if (ret == -EAGAIN) + goto again; - if (ret == -EAGAIN) - goto again; - - if (ret != 0) - goto err; - - /* Allocate a reference for the name table. */ - drm_gem_object_reference(obj); - } else { - args->name = (uint64_t) obj->name; - spin_unlock(&dev->object_name_lock); - ret = 0; + if (ret != 0) { + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); + return ret; } -err: - mutex_lock(&dev->struct_mutex); - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; + /* + * Leave the reference from the lookup around as the + * name table now holds one + */ + args->name = (uint64_t) obj->name; + + return 0; } /** @@ -450,7 +448,6 @@ drm_gem_object_handle_free(struct kref *kref) spin_lock(&dev->object_name_lock); if (obj->name) { idr_remove(&dev->object_name_idr, obj->name); - obj->name = 0; spin_unlock(&dev->object_name_lock); /* * The object name held a reference to this object, drop @@ -463,26 +460,6 @@ drm_gem_object_handle_free(struct kref *kref) } EXPORT_SYMBOL(drm_gem_object_handle_free); -void drm_gem_vm_open(struct vm_area_struct *vma) -{ - struct drm_gem_object *obj = vma->vm_private_data; - - drm_gem_object_reference(obj); -} -EXPORT_SYMBOL(drm_gem_vm_open); - -void drm_gem_vm_close(struct vm_area_struct *vma) -{ - struct drm_gem_object *obj = vma->vm_private_data; - struct drm_device *dev = obj->dev; - - mutex_lock(&dev->struct_mutex); - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); -} -EXPORT_SYMBOL(drm_gem_vm_close); - - /** * drm_gem_mmap - memory map routine for GEM objects * @filp: DRM file pointer @@ -544,14 +521,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) #endif vma->vm_page_prot = __pgprot(prot); - /* Take a ref for this mapping of the object, so that the fault - * handler can dereference the mmap offset's pointer to the object. - * This reference is cleaned up by the corresponding vm_close - * (which should happen whether the vma was created by this call, or - * by a vm_open due to mremap or partial unmap or whatever). - */ - drm_gem_object_reference(obj); - vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open_locked(vma); diff --git a/trunk/drivers/gpu/drm/drm_irq.c b/trunk/drivers/gpu/drm/drm_irq.c index 93e677a481f5..69aa0ab28403 100644 --- a/trunk/drivers/gpu/drm/drm_irq.c +++ b/trunk/drivers/gpu/drm/drm_irq.c @@ -276,7 +276,6 @@ int drm_irq_uninstall(struct drm_device * dev) for (i = 0; i < dev->num_crtcs; i++) { DRM_WAKEUP(&dev->vbl_queue[i]); dev->vblank_enabled[i] = 0; - dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i); } spin_unlock_irqrestore(&dev->vbl_lock, irqflags); @@ -435,8 +434,6 @@ EXPORT_SYMBOL(drm_vblank_get); */ void drm_vblank_put(struct drm_device *dev, int crtc) { - BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0); - /* Last user schedules interrupt disable */ if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); @@ -462,9 +459,8 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) * so that interrupts remain enabled in the interim. */ if (!dev->vblank_inmodeset[crtc]) { - dev->vblank_inmodeset[crtc] = 0x1; - if (drm_vblank_get(dev, crtc) == 0) - dev->vblank_inmodeset[crtc] |= 0x2; + dev->vblank_inmodeset[crtc] = 1; + drm_vblank_get(dev, crtc); } } EXPORT_SYMBOL(drm_vblank_pre_modeset); @@ -476,12 +472,9 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) if (dev->vblank_inmodeset[crtc]) { spin_lock_irqsave(&dev->vbl_lock, irqflags); dev->vblank_disable_allowed = 1; - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - - if (dev->vblank_inmodeset[crtc] & 0x2) - drm_vblank_put(dev, crtc); - dev->vblank_inmodeset[crtc] = 0; + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + drm_vblank_put(dev, crtc); } } EXPORT_SYMBOL(drm_vblank_post_modeset); diff --git a/trunk/drivers/gpu/drm/drm_memory.c b/trunk/drivers/gpu/drm/drm_memory.c index bcc869bc4092..803bc9e7ce3c 100644 --- a/trunk/drivers/gpu/drm/drm_memory.c +++ b/trunk/drivers/gpu/drm/drm_memory.c @@ -171,14 +171,9 @@ EXPORT_SYMBOL(drm_core_ioremap); void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev) { - if (drm_core_has_AGP(dev) && - dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) - map->handle = agp_remap(map->offset, map->size, dev); - else - map->handle = ioremap_wc(map->offset, map->size); + map->handle = ioremap_wc(map->offset, map->size); } EXPORT_SYMBOL(drm_core_ioremap_wc); - void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev) { if (!map->handle || !map->size) diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 6dab63bdc4c1..ee64b7301f67 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -202,7 +202,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) dev_priv->ring.map.flags = 0; dev_priv->ring.map.mtrr = 0; - drm_core_ioremap_wc(&dev_priv->ring.map, dev); + drm_core_ioremap(&dev_priv->ring.map, dev); if (dev_priv->ring.map.handle == NULL) { i915_dma_cleanup(dev); @@ -731,11 +731,8 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_GEM: value = dev_priv->has_gem; break; - case I915_PARAM_NUM_FENCES_AVAIL: - value = dev_priv->num_fence_regs - dev_priv->fence_reg_start; - break; default: - DRM_DEBUG("Unknown parameter %d\n", param->param); + DRM_ERROR("Unknown parameter %d\n", param->param); return -EINVAL; } @@ -767,15 +764,8 @@ static int i915_setparam(struct drm_device *dev, void *data, case I915_SETPARAM_ALLOW_BATCHBUFFER: dev_priv->allow_batchbuffer = param->value; break; - case I915_SETPARAM_NUM_USED_FENCES: - if (param->value > dev_priv->num_fence_regs || - param->value < 0) - return -EINVAL; - /* Userspace can use first N regs */ - dev_priv->fence_reg_start = param->value; - break; default: - DRM_DEBUG("unknown parameter %d\n", param->param); + DRM_ERROR("unknown parameter %d\n", param->param); return -EINVAL; } @@ -811,7 +801,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, dev_priv->hws_map.flags = 0; dev_priv->hws_map.mtrr = 0; - drm_core_ioremap_wc(&dev_priv->hws_map, dev); + drm_core_ioremap(&dev_priv->hws_map, dev); if (dev_priv->hws_map.handle == NULL) { i915_dma_cleanup(dev); dev_priv->status_gfx_addr = 0; @@ -976,6 +966,10 @@ static int i915_load_modeset_init(struct drm_device *dev) if (ret) goto kfree_devname; + dev_priv->mm.gtt_mapping = + io_mapping_create_wc(dev->agp->base, + dev->agp->agp_info.aper_size * 1024*1024); + /* Allow hardware batchbuffers unless told otherwise. */ dev_priv->allow_batchbuffer = 1; @@ -1087,28 +1081,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto free_priv; } - dev_priv->mm.gtt_mapping = - io_mapping_create_wc(dev->agp->base, - dev->agp->agp_info.aper_size * 1024*1024); - if (dev_priv->mm.gtt_mapping == NULL) { - ret = -EIO; - goto out_rmmap; - } - - /* Set up a WC MTRR for non-PAT systems. This is more common than - * one would think, because the kernel disables PAT on first - * generation Core chips because WC PAT gets overridden by a UC - * MTRR if present. Even if a UC MTRR isn't present. - */ - dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base, - dev->agp->agp_info.aper_size * - 1024 * 1024, - MTRR_TYPE_WRCOMB, 1); - if (dev_priv->mm.gtt_mtrr < 0) { - DRM_INFO("MTRR allocation failed\n. Graphics " - "performance may suffer.\n"); - } - #ifdef CONFIG_HIGHMEM64G /* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */ dev_priv->has_gem = 0; @@ -1117,17 +1089,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->has_gem = 1; #endif - dev->driver->get_vblank_counter = i915_get_vblank_counter; - if (IS_GM45(dev)) - dev->driver->get_vblank_counter = gm45_get_vblank_counter; - i915_gem_load(dev); /* Init HWS */ if (!I915_NEED_GFX_HWS(dev)) { ret = i915_init_phys_hws(dev); if (ret != 0) - goto out_iomapfree; + goto out_rmmap; } /* On the 945G/GM, the chipset reports the MSI capability on the @@ -1166,8 +1134,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) return 0; -out_iomapfree: - io_mapping_free(dev_priv->mm.gtt_mapping); out_rmmap: iounmap(dev_priv->regs); free_priv: @@ -1179,14 +1145,8 @@ int i915_driver_unload(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - io_mapping_free(dev_priv->mm.gtt_mapping); - if (dev_priv->mm.gtt_mtrr >= 0) { - mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, - dev->agp->agp_info.aper_size * 1024 * 1024); - dev_priv->mm.gtt_mtrr = -1; - } - if (drm_core_check_feature(dev, DRIVER_MODESET)) { + io_mapping_free(dev_priv->mm.gtt_mapping); drm_irq_uninstall(dev); } diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index b293ef0bae71..f8b3df0926c0 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -27,7 +27,6 @@ * */ -#include #include "drmP.h" #include "drm.h" #include "i915_drm.h" @@ -67,14 +66,6 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) i915_save_state(dev); - /* If KMS is active, we do the leavevt stuff here */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - if (i915_gem_idle(dev)) - dev_err(&dev->pdev->dev, - "GEM idle failed, resume may fail\n"); - drm_irq_uninstall(dev); - } - intel_opregion_free(dev); if (state.event == PM_EVENT_SUSPEND) { @@ -88,9 +79,6 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) static int i915_resume(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; - int ret = 0; - pci_set_power_state(dev->pdev, PCI_D0); pci_restore_state(dev->pdev); if (pci_enable_device(dev->pdev)) @@ -101,26 +89,11 @@ static int i915_resume(struct drm_device *dev) intel_opregion_init(dev); - /* KMS EnterVT equivalent */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - mutex_lock(&dev->struct_mutex); - dev_priv->mm.suspended = 0; - - ret = i915_gem_init_ringbuffer(dev); - if (ret != 0) - ret = -1; - mutex_unlock(&dev->struct_mutex); - - drm_irq_install(dev); - } - - return ret; + return 0; } static struct vm_operations_struct i915_gem_vm_ops = { .fault = i915_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, }; static struct drm_driver driver = { @@ -139,6 +112,7 @@ static struct drm_driver driver = { .suspend = i915_suspend, .resume = i915_resume, .device_is_agp = i915_driver_device_is_agp, + .get_vblank_counter = i915_get_vblank_counter, .enable_vblank = i915_enable_vblank, .disable_vblank = i915_disable_vblank, .irq_preinstall = i915_driver_irq_preinstall, diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 17fa40858d26..e13518252007 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -184,8 +184,6 @@ typedef struct drm_i915_private { unsigned int lvds_dither:1; unsigned int lvds_vbt:1; unsigned int int_crt_support:1; - unsigned int lvds_use_ssc:1; - int lvds_ssc_freq; struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ @@ -286,7 +284,6 @@ typedef struct drm_i915_private { struct drm_mm gtt_space; struct io_mapping *gtt_mapping; - int gtt_mtrr; /** * List of objects currently involved in rendering from the @@ -537,7 +534,6 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, extern int i915_enable_vblank(struct drm_device *dev, int crtc); extern void i915_disable_vblank(struct drm_device *dev, int crtc); extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); -extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); extern int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); @@ -605,7 +601,6 @@ int i915_gem_init_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj); int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); void i915_gem_object_unpin(struct drm_gem_object *obj); -int i915_gem_object_unbind(struct drm_gem_object *obj); void i915_gem_lastclose(struct drm_device *dev); uint32_t i915_get_gem_seqno(struct drm_device *dev); void i915_gem_retire_requests(struct drm_device *dev); @@ -618,7 +613,6 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long end); -int i915_gem_idle(struct drm_device *dev); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write); @@ -790,11 +784,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev)) #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev)) -/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte - * rows, which changed the alignment requirements and fence programming. - */ -#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ - IS_I915GM(dev))) #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev)) #define PRIMARY_RINGBUFFER_SIZE (128*1024) diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 85685bfd12da..debad5c04cc0 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -34,6 +34,10 @@ #define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) +static void +i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, + uint32_t read_domains, + uint32_t write_domain); static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); @@ -48,7 +52,7 @@ static void i915_gem_object_free_page_list(struct drm_gem_object *obj); static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment); -static int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write); +static void i915_gem_object_get_fence_reg(struct drm_gem_object *obj); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); static int i915_gem_evict_something(struct drm_device *dev); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, @@ -563,7 +567,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) pgoff_t page_offset; unsigned long pfn; int ret = 0; - bool write = !!(vmf->flags & FAULT_FLAG_WRITE); /* We don't use vmf->pgoff since that has the fake offset */ page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >> @@ -582,13 +585,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* Need a new fence register? */ if (obj_priv->fence_reg == I915_FENCE_REG_NONE && - obj_priv->tiling_mode != I915_TILING_NONE) { - ret = i915_gem_object_get_fence_reg(obj, write); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return VM_FAULT_SIGBUS; - } - } + obj_priv->tiling_mode != I915_TILING_NONE) + i915_gem_object_get_fence_reg(obj); pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + page_offset; @@ -603,6 +601,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) case -EAGAIN: return VM_FAULT_OOM; case -EFAULT: + case -EBUSY: + DRM_ERROR("can't insert pfn?? fault or busy...\n"); return VM_FAULT_SIGBUS; default: return VM_FAULT_NOPAGE; @@ -678,30 +678,6 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) return ret; } -static void -i915_gem_free_mmap_offset(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - struct drm_gem_mm *mm = dev->mm_private; - struct drm_map_list *list; - - list = &obj->map_list; - drm_ht_remove_item(&mm->offset_hash, &list->hash); - - if (list->file_offset_node) { - drm_mm_put_block(list->file_offset_node); - list->file_offset_node = NULL; - } - - if (list->map) { - drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER); - list->map = NULL; - } - - obj_priv->mmap_offset = 0; -} - /** * i915_gem_get_gtt_alignment - return required GTT alignment for an object * @obj: object to check @@ -776,11 +752,8 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, if (!obj_priv->mmap_offset) { ret = i915_gem_create_mmap_offset(obj); - if (ret) { - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); + if (ret) return ret; - } } args->offset = obj_priv->mmap_offset; @@ -1051,9 +1024,6 @@ i915_gem_retire_requests(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; uint32_t seqno; - if (!dev_priv->hw_status_page) - return; - seqno = i915_get_gem_seqno(dev); while (!list_empty(&dev_priv->mm.request_list)) { @@ -1241,7 +1211,7 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj) /** * Unbinds an object from the GTT aperture. */ -int +static int i915_gem_object_unbind(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; @@ -1475,26 +1445,21 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = obj->driver_private; int regnum = obj_priv->fence_reg; - int tile_width; uint32_t val; uint32_t pitch_val; if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || (obj_priv->gtt_offset & (obj->size - 1))) { - WARN(1, "%s: object 0x%08x not 1M or size (0x%zx) aligned\n", - __func__, obj_priv->gtt_offset, obj->size); + WARN(1, "%s: object not 1M or size aligned\n", __func__); return; } - if (obj_priv->tiling_mode == I915_TILING_Y && - HAS_128_BYTE_Y_TILING(dev)) - tile_width = 128; + if (obj_priv->tiling_mode == I915_TILING_Y && (IS_I945G(dev) || + IS_I945GM(dev) || + IS_G33(dev))) + pitch_val = (obj_priv->stride / 128) - 1; else - tile_width = 512; - - /* Note: pitch better be a power of two tile widths */ - pitch_val = obj_priv->stride / tile_width; - pitch_val = ffs(pitch_val) - 1; + pitch_val = (obj_priv->stride / 512) - 1; val = obj_priv->gtt_offset; if (obj_priv->tiling_mode == I915_TILING_Y) @@ -1518,8 +1483,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || (obj_priv->gtt_offset & (obj->size - 1))) { - WARN(1, "%s: object 0x%08x not 1M or size aligned\n", - __func__, obj_priv->gtt_offset); + WARN(1, "%s: object not 1M or size aligned\n", __func__); return; } @@ -1539,7 +1503,6 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) /** * i915_gem_object_get_fence_reg - set up a fence reg for an object * @obj: object to map through a fence reg - * @write: object is about to be written * * When mapping objects through the GTT, userspace wants to be able to write * to them without having to worry about swizzling if the object is tiled. @@ -1550,8 +1513,8 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) * It then sets up the reg based on the object's properties: address, pitch * and tiling format. */ -static int -i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) +static void +i915_gem_object_get_fence_reg(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -1564,18 +1527,12 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) WARN(1, "allocating a fence for non-tiled object?\n"); break; case I915_TILING_X: - if (!obj_priv->stride) - return -EINVAL; - WARN((obj_priv->stride & (512 - 1)), - "object 0x%08x is X tiled but has non-512B pitch\n", - obj_priv->gtt_offset); + WARN(obj_priv->stride & (512 - 1), + "object is X tiled but has non-512B pitch\n"); break; case I915_TILING_Y: - if (!obj_priv->stride) - return -EINVAL; - WARN((obj_priv->stride & (128 - 1)), - "object 0x%08x is Y tiled but has non-128B pitch\n", - obj_priv->gtt_offset); + WARN(obj_priv->stride & (128 - 1), + "object is Y tiled but has non-128B pitch\n"); break; } @@ -1606,11 +1563,10 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) * objects to finish before trying again. */ if (i == dev_priv->num_fence_regs) { - ret = i915_gem_object_set_to_gtt_domain(reg->obj, 0); + ret = i915_gem_object_wait_rendering(reg->obj); if (ret) { - WARN(ret != -ERESTARTSYS, - "switch to GTT domain failed: %d\n", ret); - return ret; + WARN(ret, "wait_rendering failed: %d\n", ret); + return; } goto try_again; } @@ -1635,8 +1591,6 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) i915_write_fence_reg(reg); else i830_write_fence_reg(reg); - - return 0; } /** @@ -1677,7 +1631,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) if (dev_priv->mm.suspended) return -EBUSY; if (alignment == 0) - alignment = i915_gem_get_gtt_alignment(obj); + alignment = PAGE_SIZE; if (alignment & (PAGE_SIZE - 1)) { DRM_ERROR("Invalid object alignment requested %u\n", alignment); return -EINVAL; @@ -2020,28 +1974,30 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) * drm_agp_chipset_flush */ static void -i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) +i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, + uint32_t read_domains, + uint32_t write_domain) { struct drm_device *dev = obj->dev; struct drm_i915_gem_object *obj_priv = obj->driver_private; uint32_t invalidate_domains = 0; uint32_t flush_domains = 0; - BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU); - BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU); + BUG_ON(read_domains & I915_GEM_DOMAIN_CPU); + BUG_ON(write_domain == I915_GEM_DOMAIN_CPU); #if WATCH_BUF DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", __func__, obj, - obj->read_domains, obj->pending_read_domains, - obj->write_domain, obj->pending_write_domain); + obj->read_domains, read_domains, + obj->write_domain, write_domain); #endif /* * If the object isn't moving to a new write domain, * let the object stay in multiple read domains */ - if (obj->pending_write_domain == 0) - obj->pending_read_domains |= obj->read_domains; + if (write_domain == 0) + read_domains |= obj->read_domains; else obj_priv->dirty = 1; @@ -2051,17 +2007,15 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) * any read domains which differ from the old * write domain */ - if (obj->write_domain && - obj->write_domain != obj->pending_read_domains) { + if (obj->write_domain && obj->write_domain != read_domains) { flush_domains |= obj->write_domain; - invalidate_domains |= - obj->pending_read_domains & ~obj->write_domain; + invalidate_domains |= read_domains & ~obj->write_domain; } /* * Invalidate any read caches which may have * stale data. That is, any new read domains. */ - invalidate_domains |= obj->pending_read_domains & ~obj->read_domains; + invalidate_domains |= read_domains & ~obj->read_domains; if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) { #if WATCH_BUF DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n", @@ -2070,15 +2024,9 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) i915_gem_clflush_object(obj); } - /* The actual obj->write_domain will be updated with - * pending_write_domain after we emit the accumulated flush for all - * of our domain changes in execbuffers (which clears objects' - * write_domains). So if we have a current write domain that we - * aren't changing, set pending_write_domain to that. - */ - if (flush_domains == 0 && obj->pending_write_domain == 0) - obj->pending_write_domain = obj->write_domain; - obj->read_domains = obj->pending_read_domains; + if ((write_domain | flush_domains) != 0) + obj->write_domain = write_domain; + obj->read_domains = read_domains; dev->invalidate_domains |= invalidate_domains; dev->flush_domains |= flush_domains; @@ -2281,8 +2229,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, (int) reloc.offset, reloc.read_domains, reloc.write_domain); - drm_gem_object_unreference(target_obj); - i915_gem_object_unpin(obj); return -EINVAL; } @@ -2512,15 +2458,13 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, if (dev_priv->mm.wedged) { DRM_ERROR("Execbuf while wedged\n"); mutex_unlock(&dev->struct_mutex); - ret = -EIO; - goto pre_mutex_err; + return -EIO; } if (dev_priv->mm.suspended) { DRM_ERROR("Execbuf while VT-switched.\n"); mutex_unlock(&dev->struct_mutex); - ret = -EBUSY; - goto pre_mutex_err; + return -EBUSY; } /* Look up object handles */ @@ -2588,7 +2532,9 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_gem_object *obj = object_list[i]; /* Compute new gpu domains and update invalidate/flush */ - i915_gem_object_set_to_gpu_domain(obj); + i915_gem_object_set_to_gpu_domain(obj, + obj->pending_read_domains, + obj->pending_write_domain); } i915_verify_inactive(dev, __FILE__, __LINE__); @@ -2607,12 +2553,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, (void)i915_add_request(dev, dev->flush_domains); } - for (i = 0; i < args->buffer_count; i++) { - struct drm_gem_object *obj = object_list[i]; - - obj->write_domain = obj->pending_write_domain; - } - i915_verify_inactive(dev, __FILE__, __LINE__); #if WATCH_COHERENCY @@ -2670,6 +2610,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, i915_verify_inactive(dev, __FILE__, __LINE__); + /* Copy the new buffer offsets back to the user's exec list. */ + ret = copy_to_user((struct drm_i915_relocation_entry __user *) + (uintptr_t) args->buffers_ptr, + exec_list, + sizeof(*exec_list) * args->buffer_count); + if (ret) + DRM_ERROR("failed to copy %d exec entries " + "back to user (%d)\n", + args->buffer_count, ret); err: for (i = 0; i < pinned; i++) i915_gem_object_unpin(object_list[i]); @@ -2679,18 +2628,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, mutex_unlock(&dev->struct_mutex); - if (!ret) { - /* Copy the new buffer offsets back to the user's exec list. */ - ret = copy_to_user((struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - exec_list, - sizeof(*exec_list) * args->buffer_count); - if (ret) - DRM_ERROR("failed to copy %d exec entries " - "back to user (%d)\n", - args->buffer_count, ret); - } - pre_mutex_err: drm_free(object_list, sizeof(*object_list) * args->buffer_count, DRM_MEM_DRIVER); @@ -2715,14 +2652,6 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) DRM_ERROR("Failure to bind: %d", ret); return ret; } - /* - * Pre-965 chips need a fence register set up in order to - * properly handle tiled surfaces. - */ - if (!IS_I965G(dev) && - obj_priv->fence_reg == I915_FENCE_REG_NONE && - obj_priv->tiling_mode != I915_TILING_NONE) - i915_gem_object_get_fence_reg(obj, true); } obj_priv->pin_count++; @@ -2794,7 +2723,6 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) { DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", args->handle); - drm_gem_object_unreference(obj); mutex_unlock(&dev->struct_mutex); return -EINVAL; } @@ -2875,13 +2803,6 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, return -EBADF; } - /* Update the active list for the hardware's current position. - * Otherwise this only updates on a delayed timer or when irqs are - * actually unmasked, and our working set ends up being larger than - * required. - */ - i915_gem_retire_requests(dev); - obj_priv = obj->driver_private; /* Don't count being on the flushing list against the object being * done. Otherwise, a buffer left on the flushing list but not getting @@ -2934,6 +2855,9 @@ int i915_gem_init_object(struct drm_gem_object *obj) void i915_gem_free_object(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; + struct drm_gem_mm *mm = dev->mm_private; + struct drm_map_list *list; + struct drm_map *map; struct drm_i915_gem_object *obj_priv = obj->driver_private; while (obj_priv->pin_count > 0) @@ -2944,7 +2868,19 @@ void i915_gem_free_object(struct drm_gem_object *obj) i915_gem_object_unbind(obj); - i915_gem_free_mmap_offset(obj); + list = &obj->map_list; + drm_ht_remove_item(&mm->offset_hash, &list->hash); + + if (list->file_offset_node) { + drm_mm_put_block(list->file_offset_node); + list->file_offset_node = NULL; + } + + map = list->map; + if (map) { + drm_free(map, sizeof(*map), DRM_MEM_DRIVER); + list->map = NULL; + } drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); @@ -2983,7 +2919,7 @@ i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) return 0; } -int +static int i915_gem_idle(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -3129,7 +3065,6 @@ i915_gem_init_hws(struct drm_device *dev) if (dev_priv->hw_status_page == NULL) { DRM_ERROR("Failed to map status page.\n"); memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - i915_gem_object_unpin(obj); drm_gem_object_unreference(obj); return -EINVAL; } @@ -3142,31 +3077,6 @@ i915_gem_init_hws(struct drm_device *dev) return 0; } -static void -i915_gem_cleanup_hws(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - - if (dev_priv->hws_obj == NULL) - return; - - obj = dev_priv->hws_obj; - obj_priv = obj->driver_private; - - kunmap(obj_priv->page_list[0]); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); - dev_priv->hws_obj = NULL; - - memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - dev_priv->hw_status_page = NULL; - - /* Write high address into HWS_PGA when disabling. */ - I915_WRITE(HWS_PGA, 0x1ffff000); -} - int i915_gem_init_ringbuffer(struct drm_device *dev) { @@ -3184,7 +3094,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev) obj = drm_gem_object_alloc(dev, 128 * 1024); if (obj == NULL) { DRM_ERROR("Failed to allocate ringbuffer\n"); - i915_gem_cleanup_hws(dev); return -ENOMEM; } obj_priv = obj->driver_private; @@ -3192,7 +3101,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev) ret = i915_gem_object_pin(obj, 4096); if (ret != 0) { drm_gem_object_unreference(obj); - i915_gem_cleanup_hws(dev); return ret; } @@ -3210,9 +3118,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) if (ring->map.handle == NULL) { DRM_ERROR("Failed to map ringbuffer.\n"); memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); - i915_gem_object_unpin(obj); drm_gem_object_unreference(obj); - i915_gem_cleanup_hws(dev); return -EINVAL; } ring->ring_obj = obj; @@ -3292,7 +3198,20 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) dev_priv->ring.ring_obj = NULL; memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); - i915_gem_cleanup_hws(dev); + if (dev_priv->hws_obj != NULL) { + struct drm_gem_object *obj = dev_priv->hws_obj; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + + kunmap(obj_priv->page_list[0]); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(obj); + dev_priv->hws_obj = NULL; + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); + dev_priv->hw_status_page = NULL; + + /* Write high address into HWS_PGA when disabling. */ + I915_WRITE(HWS_PGA, 0x1ffff000); + } } int @@ -3310,6 +3229,10 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, dev_priv->mm.wedged = 0; } + dev_priv->mm.gtt_mapping = io_mapping_create_wc(dev->agp->base, + dev->agp->agp_info.aper_size + * 1024 * 1024); + mutex_lock(&dev->struct_mutex); dev_priv->mm.suspended = 0; @@ -3332,6 +3255,7 @@ int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + drm_i915_private_t *dev_priv = dev->dev_private; int ret; if (drm_core_check_feature(dev, DRIVER_MODESET)) @@ -3340,6 +3264,7 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, ret = i915_gem_idle(dev); drm_irq_uninstall(dev); + io_mapping_free(dev_priv->mm.gtt_mapping); return ret; } @@ -3348,9 +3273,6 @@ i915_gem_lastclose(struct drm_device *dev) { int ret; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - ret = i915_gem_idle(dev); if (ret) DRM_ERROR("failed to idle hardware: %d\n", ret); @@ -3372,7 +3294,7 @@ i915_gem_load(struct drm_device *dev) /* Old X drivers will take 0-2 for front, back, depth buffers */ dev_priv->fence_reg_start = 3; - if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) + if (IS_I965G(dev)) dev_priv->num_fence_regs = 16; else dev_priv->num_fence_regs = 8; @@ -3548,7 +3470,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, user_data = (char __user *) (uintptr_t) args->data_ptr; obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; - DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size); + DRM_ERROR("obj_addr %p, %lld\n", obj_addr, args->size); ret = copy_from_user(obj_addr, user_data, args->size); if (ret) return -EFAULT; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c index 7fb4191ef934..241f39b7f460 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -173,73 +173,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) dev_priv->mm.bit_6_swizzle_y = swizzle_y; } - -/** - * Returns the size of the fence for a tiled object of the given size. - */ -static int -i915_get_fence_size(struct drm_device *dev, int size) -{ - int i; - int start; - - if (IS_I965G(dev)) { - /* The 965 can have fences at any page boundary. */ - return ALIGN(size, 4096); - } else { - /* Align the size to a power of two greater than the smallest - * fence size. - */ - if (IS_I9XX(dev)) - start = 1024 * 1024; - else - start = 512 * 1024; - - for (i = start; i < size; i <<= 1) - ; - - return i; - } -} - -/* Check pitch constriants for all chips & tiling formats */ -static bool -i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) -{ - int tile_width; - - /* Linear is always fine */ - if (tiling_mode == I915_TILING_NONE) - return true; - - if (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) - tile_width = 128; - else - tile_width = 512; - - /* 965+ just needs multiples of tile width */ - if (IS_I965G(dev)) { - if (stride & (tile_width - 1)) - return false; - return true; - } - - /* Pre-965 needs power of two tile widths */ - if (stride < tile_width) - return false; - - if (stride & (stride - 1)) - return false; - - /* We don't handle the aperture area covered by the fence being bigger - * than the object size. - */ - if (i915_get_fence_size(dev, size) != size) - return false; - - return true; -} - /** * Sets the tiling mode of an object, returning the required swizzling of * bit 6 of addresses in the object. @@ -258,11 +191,6 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, return -EINVAL; obj_priv = obj->driver_private; - if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { - drm_gem_object_unreference(obj); - return -EINVAL; - } - mutex_lock(&dev->struct_mutex); if (args->tiling_mode == I915_TILING_NONE) { @@ -279,29 +207,13 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; } } - if (args->tiling_mode != obj_priv->tiling_mode) { - int ret; - - /* Unbind the object, as switching tiling means we're - * switching the cache organization due to fencing, probably. - */ - ret = i915_gem_object_unbind(obj); - if (ret != 0) { - WARN(ret != -ERESTARTSYS, - "failed to unbind object for tiling switch"); - args->tiling_mode = obj_priv->tiling_mode; - mutex_unlock(&dev->struct_mutex); - drm_gem_object_unreference(obj); - - return ret; - } - obj_priv->tiling_mode = args->tiling_mode; - } + obj_priv->tiling_mode = args->tiling_mode; obj_priv->stride = args->stride; - drm_gem_object_unreference(obj); mutex_unlock(&dev->struct_mutex); + drm_gem_object_unreference(obj); + return 0; } @@ -339,8 +251,9 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, DRM_ERROR("unknown tiling mode\n"); } - drm_gem_object_unreference(obj); mutex_unlock(&dev->struct_mutex); + drm_gem_object_unreference(obj); + return 0; } diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 548ff2c66431..6290219de6c8 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -174,19 +174,6 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) return count; } -u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; - - if (!i915_pipe_enabled(dev, pipe)) { - DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); - return 0; - } - - return I915_READ(reg); -} - irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 9d6539a868b3..273162579e1b 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -186,12 +186,12 @@ #define FENCE_REG_830_0 0x2000 #define I830_FENCE_START_MASK 0x07f80000 #define I830_FENCE_TILING_Y_SHIFT 12 -#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) +#define I830_FENCE_SIZE_BITS(size) ((get_order(size >> 19) - 1) << 8) #define I830_FENCE_PITCH_SHIFT 4 #define I830_FENCE_REG_VALID (1<<0) #define I915_FENCE_START_MASK 0x0ff00000 -#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8) +#define I915_FENCE_SIZE_BITS(size) ((get_order(size >> 20) - 1) << 8) #define FENCE_REG_965_0 0x03000 #define I965_FENCE_PITCH_SHIFT 2 @@ -1371,9 +1371,6 @@ #define PIPE_FRAME_LOW_SHIFT 24 #define PIPE_PIXEL_MASK 0x00ffffff #define PIPE_PIXEL_SHIFT 0 -/* GM45+ just has to be different */ -#define PIPEA_FRMCOUNT_GM45 0x70040 -#define PIPEA_FLIPCOUNT_GM45 0x70044 /* Cursor A & B regs */ #define CURACNTR 0x70080 @@ -1442,9 +1439,6 @@ #define PIPEBSTAT 0x71024 #define PIPEBFRAMEHIGH 0x71040 #define PIPEBFRAMEPIXEL 0x71044 -#define PIPEB_FRMCOUNT_GM45 0x71040 -#define PIPEB_FLIPCOUNT_GM45 0x71044 - /* Display B control */ #define DSPBCNTR 0x71180 diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.c b/trunk/drivers/gpu/drm/i915/intel_bios.c index fc28e2bbd542..4ca82a025525 100644 --- a/trunk/drivers/gpu/drm/i915/intel_bios.c +++ b/trunk/drivers/gpu/drm/i915/intel_bios.c @@ -111,12 +111,6 @@ parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb) panel_fixed_mode->clock = dvo_timing->clock * 10; panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; - /* Some VBTs have bogus h/vtotal values */ - if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) - panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; - if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) - panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1; - drm_mode_set_name(panel_fixed_mode); dev_priv->vbt_mode = panel_fixed_mode; @@ -141,14 +135,6 @@ parse_general_features(struct drm_i915_private *dev_priv, if (general) { dev_priv->int_tv_support = general->int_tv_support; dev_priv->int_crt_support = general->int_crt_support; - dev_priv->lvds_use_ssc = general->enable_ssc; - - if (dev_priv->lvds_use_ssc) { - if (IS_I855(dev_priv->dev)) - dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48; - else - dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; - } } } diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index a2834276cb38..31c3732b7a69 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -90,12 +90,12 @@ typedef struct { #define I9XX_DOT_MAX 400000 #define I9XX_VCO_MIN 1400000 #define I9XX_VCO_MAX 2800000 -#define I9XX_N_MIN 1 -#define I9XX_N_MAX 6 +#define I9XX_N_MIN 3 +#define I9XX_N_MAX 8 #define I9XX_M_MIN 70 #define I9XX_M_MAX 120 #define I9XX_M1_MIN 10 -#define I9XX_M1_MAX 22 +#define I9XX_M1_MAX 20 #define I9XX_M2_MIN 5 #define I9XX_M2_MAX 9 #define I9XX_P_SDVO_DAC_MIN 5 @@ -189,7 +189,9 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) return limit; } -static void intel_clock(int refclk, intel_clock_t *clock) +/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ + +static void i8xx_clock(int refclk, intel_clock_t *clock) { clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); clock->p = clock->p1 * clock->p2; @@ -197,6 +199,25 @@ static void intel_clock(int refclk, intel_clock_t *clock) clock->dot = clock->vco / clock->p; } +/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */ + +static void i9xx_clock(int refclk, intel_clock_t *clock) +{ + clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); + clock->p = clock->p1 * clock->p2; + clock->vco = refclk * clock->m / (clock->n + 2); + clock->dot = clock->vco / clock->p; +} + +static void intel_clock(struct drm_device *dev, int refclk, + intel_clock_t *clock) +{ + if (IS_I9XX(dev)) + i9xx_clock (refclk, clock); + else + i8xx_clock (refclk, clock); +} + /** * Returns whether any output on the specified pipe is of the specified type */ @@ -217,7 +238,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) return false; } -#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) +#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; } /** * Returns whether the given set of divisors are valid for a given refclk with * the given connectors. @@ -297,7 +318,7 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target, clock.p1 <= limit->p1.max; clock.p1++) { int this_err; - intel_clock(refclk, &clock); + intel_clock(dev, refclk, &clock); if (!intel_PLL_is_valid(crtc, &clock)) continue; @@ -322,7 +343,7 @@ intel_wait_for_vblank(struct drm_device *dev) udelay(20000); } -static int +static void intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { @@ -340,21 +361,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; u32 dspcntr, alignment; - int ret; /* no fb bound */ if (!crtc->fb) { DRM_DEBUG("No FB bound\n"); - return 0; - } - - switch (pipe) { - case 0: - case 1: - break; - default: - DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); - return -EINVAL; + return; } intel_fb = to_intel_framebuffer(crtc->fb); @@ -366,30 +377,28 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, alignment = 64 * 1024; break; case I915_TILING_X: - /* pin() will align the object as required by fence */ - alignment = 0; + if (IS_I9XX(dev)) + alignment = 1024 * 1024; + else + alignment = 512 * 1024; break; case I915_TILING_Y: /* FIXME: Is this true? */ DRM_ERROR("Y tiled not allowed for scan out buffers\n"); - return -EINVAL; + return; default: BUG(); } - mutex_lock(&dev->struct_mutex); - ret = i915_gem_object_pin(intel_fb->obj, alignment); - if (ret != 0) { - mutex_unlock(&dev->struct_mutex); - return ret; - } + if (i915_gem_object_pin(intel_fb->obj, alignment)) + return; - ret = i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1); - if (ret != 0) { - i915_gem_object_unpin(intel_fb->obj); - mutex_unlock(&dev->struct_mutex); - return ret; - } + i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1); + + Start = obj_priv->gtt_offset; + Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); + + I915_WRITE(dspstride, crtc->fb->pitch); dspcntr = I915_READ(dspcntr_reg); /* Mask out pixel format bits in case we change it */ @@ -410,17 +419,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, break; default: DRM_ERROR("Unknown color depth\n"); - i915_gem_object_unpin(intel_fb->obj); - mutex_unlock(&dev->struct_mutex); - return -EINVAL; + return; } I915_WRITE(dspcntr_reg, dspcntr); - Start = obj_priv->gtt_offset; - Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); - DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); - I915_WRITE(dspstride, crtc->fb->pitch); if (IS_I965G(dev)) { I915_WRITE(dspbase, Offset); I915_READ(dspbase); @@ -437,24 +440,27 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, intel_fb = to_intel_framebuffer(old_fb); i915_gem_object_unpin(intel_fb->obj); } - mutex_unlock(&dev->struct_mutex); if (!dev->primary->master) - return 0; + return; master_priv = dev->primary->master->driver_priv; if (!master_priv->sarea_priv) - return 0; + return; - if (pipe) { - master_priv->sarea_priv->pipeB_x = x; - master_priv->sarea_priv->pipeB_y = y; - } else { + switch (pipe) { + case 0: master_priv->sarea_priv->pipeA_x = x; master_priv->sarea_priv->pipeA_y = y; + break; + case 1: + master_priv->sarea_priv->pipeB_x = x; + master_priv->sarea_priv->pipeB_y = y; + break; + default: + DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); + break; } - - return 0; } @@ -702,11 +708,11 @@ static int intel_panel_fitter_pipe (struct drm_device *dev) return 1; } -static int intel_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) +static void intel_crtc_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + int x, int y, + struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -726,14 +732,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk, num_outputs = 0; + int refclk; intel_clock_t clock; u32 dpll = 0, fp = 0, dspcntr, pipeconf; bool ok, is_sdvo = false, is_dvo = false; bool is_crt = false, is_lvds = false, is_tv = false; struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; - int ret; drm_vblank_pre_modeset(dev, pipe); @@ -750,8 +755,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, case INTEL_OUTPUT_SDVO: case INTEL_OUTPUT_HDMI: is_sdvo = true; - if (intel_output->needs_tv_clock) - is_tv = true; break; case INTEL_OUTPUT_DVO: is_dvo = true; @@ -763,14 +766,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, is_crt = true; break; } - - num_outputs++; } - if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) { - refclk = dev_priv->lvds_ssc_freq * 1000; - DRM_DEBUG("using SSC reference clock of %d MHz\n", refclk / 1000); - } else if (IS_I9XX(dev)) { + if (IS_I9XX(dev)) { refclk = 96000; } else { refclk = 48000; @@ -779,7 +777,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); - return -EINVAL; + return; } fp = clock.n << 16 | clock.m1 << 8 | clock.m2; @@ -829,14 +827,11 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, } } - if (is_sdvo && is_tv) - dpll |= PLL_REF_INPUT_TVCLKINBC; - else if (is_tv) + if (is_tv) { /* XXX: just matching BIOS for now */ - /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ +/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ dpll |= 3; - else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) - dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; + } else dpll |= PLL_REF_INPUT_DREFCLK; @@ -953,13 +948,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(dspcntr_reg, dspcntr); /* Flush the plane changes */ - ret = intel_pipe_set_base(crtc, x, y, old_fb); - if (ret != 0) - return ret; + intel_pipe_set_base(crtc, x, y, old_fb); drm_vblank_post_modeset(dev, pipe); - - return 0; } /** Loads the palette/gamma unit for the CRTC with the prepared values */ @@ -1008,7 +999,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, temp = CURSOR_MODE_DISABLE; addr = 0; bo = NULL; - mutex_lock(&dev->struct_mutex); goto finish; } @@ -1031,19 +1021,18 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, } /* we only need to pin inside GTT if cursor is non-phy */ - mutex_lock(&dev->struct_mutex); if (!dev_priv->cursor_needs_physical) { ret = i915_gem_object_pin(bo, PAGE_SIZE); if (ret) { DRM_ERROR("failed to pin cursor bo\n"); - goto fail_locked; + goto fail; } addr = obj_priv->gtt_offset; } else { ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); if (ret) { DRM_ERROR("failed to attach phys object\n"); - goto fail_locked; + goto fail; } addr = obj_priv->phys_obj->handle->busaddr; } @@ -1063,9 +1052,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); } else i915_gem_object_unpin(intel_crtc->cursor_bo); + mutex_lock(&dev->struct_mutex); drm_gem_object_unreference(intel_crtc->cursor_bo); + mutex_unlock(&dev->struct_mutex); } - mutex_unlock(&dev->struct_mutex); intel_crtc->cursor_addr = addr; intel_crtc->cursor_bo = bo; @@ -1073,7 +1063,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, return 0; fail: mutex_lock(&dev->struct_mutex); -fail_locked: drm_gem_object_unreference(bo); mutex_unlock(&dev->struct_mutex); return ret; @@ -1301,7 +1290,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) } /* XXX: Handle the 100Mhz refclk */ - intel_clock(96000, &clock); + i9xx_clock(96000, &clock); } else { bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN); @@ -1313,9 +1302,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) { /* XXX: might not be 66MHz */ - intel_clock(66000, &clock); + i8xx_clock(66000, &clock); } else - intel_clock(48000, &clock); + i8xx_clock(48000, &clock); } else { if (dpll & PLL_P1_DIVIDE_BY_TWO) clock.p1 = 2; @@ -1328,7 +1317,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) else clock.p2 = 2; - intel_clock(48000, &clock); + i8xx_clock(48000, &clock); } } @@ -1463,7 +1452,6 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask) static void intel_setup_outputs(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; intel_crt_init(dev); @@ -1475,16 +1463,13 @@ static void intel_setup_outputs(struct drm_device *dev) if (IS_I9XX(dev)) { int found; - if (I915_READ(SDVOB) & SDVO_DETECTED) { - found = intel_sdvo_init(dev, SDVOB); - if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) - intel_hdmi_init(dev, SDVOB); - } - if (!IS_G4X(dev) || (I915_READ(SDVOB) & SDVO_DETECTED)) { - found = intel_sdvo_init(dev, SDVOC); - if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) - intel_hdmi_init(dev, SDVOC); - } + found = intel_sdvo_init(dev, SDVOB); + if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) + intel_hdmi_init(dev, SDVOB); + + found = intel_sdvo_init(dev, SDVOC); + if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) + intel_hdmi_init(dev, SDVOC); } else intel_dvo_init(dev); @@ -1607,9 +1592,7 @@ intel_user_framebuffer_create(struct drm_device *dev, ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj); if (ret) { - mutex_lock(&dev->struct_mutex); drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); return NULL; } diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 957daef8edff..8a4cc50c5b4e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -82,7 +82,6 @@ struct intel_output { struct intel_i2c_chan *i2c_bus; /* for control functions */ struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */ bool load_detect_temp; - bool needs_tv_clock; void *dev_priv; }; diff --git a/trunk/drivers/gpu/drm/i915/intel_fb.c b/trunk/drivers/gpu/drm/i915/intel_fb.c index b7f0ebe9f810..afd1217b8a02 100644 --- a/trunk/drivers/gpu/drm/i915/intel_fb.c +++ b/trunk/drivers/gpu/drm/i915/intel_fb.c @@ -473,7 +473,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, ret = intel_framebuffer_create(dev, &mode_cmd, &fb, fbo); if (ret) { DRM_ERROR("failed to allocate fb.\n"); - goto out_unpin; + goto out_unref; } list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list); @@ -484,7 +484,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, info = framebuffer_alloc(sizeof(struct intelfb_par), device); if (!info) { ret = -ENOMEM; - goto out_unpin; + goto out_unref; } par = info->par; @@ -513,7 +513,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, size); if (!info->screen_base) { ret = -ENOSPC; - goto out_unpin; + goto out_unref; } info->screen_size = size; @@ -608,8 +608,6 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, mutex_unlock(&dev->struct_mutex); return 0; -out_unpin: - i915_gem_object_unpin(fbo); out_unref: drm_gem_object_unreference(fbo); mutex_unlock(&dev->struct_mutex); diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 0d211af98854..b36a5214d8df 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -27,7 +27,6 @@ * Jesse Barnes */ -#include #include #include "drmP.h" #include "drm.h" @@ -312,8 +311,10 @@ static int intel_lvds_get_modes(struct drm_connector *connector) if (dev_priv->panel_fixed_mode != NULL) { struct drm_display_mode *mode; + mutex_lock(&dev->mode_config.mutex); mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); drm_mode_probed_add(connector, mode); + mutex_unlock(&dev->mode_config.mutex); return 1; } @@ -404,16 +405,6 @@ void intel_lvds_init(struct drm_device *dev) u32 lvds; int pipe; - /* Blacklist machines that we know falsely report LVDS. */ - /* FIXME: add a check for the Aopen Mini PC */ - - /* Apple Mac Mini Core Duo and Mac Mini Core 2 Duo */ - if(dmi_match(DMI_PRODUCT_NAME, "Macmini1,1") || - dmi_match(DMI_PRODUCT_NAME, "Macmini2,1")) { - DRM_DEBUG("Skipping LVDS initialization for Apple Mac Mini\n"); - return; - } - intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); if (!intel_output) { return; @@ -467,7 +458,7 @@ void intel_lvds_init(struct drm_device *dev) dev_priv->panel_fixed_mode = drm_mode_duplicate(dev, scan); mutex_unlock(&dev->mode_config.mutex); - goto out; + goto out; /* FIXME: check for quirks */ } mutex_unlock(&dev->mode_config.mutex); } @@ -481,6 +472,8 @@ void intel_lvds_init(struct drm_device *dev) if (dev_priv->panel_fixed_mode) { dev_priv->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, + dev_priv->panel_fixed_mode); goto out; } } @@ -499,7 +492,7 @@ void intel_lvds_init(struct drm_device *dev) if (dev_priv->panel_fixed_mode) { dev_priv->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; - goto out; + goto out; /* FIXME: check for quirks */ } } @@ -507,6 +500,38 @@ void intel_lvds_init(struct drm_device *dev) if (!dev_priv->panel_fixed_mode) goto failed; + /* FIXME: detect aopen & mac mini type stuff automatically? */ + /* + * Blacklist machines with BIOSes that list an LVDS panel without + * actually having one. + */ + if (IS_I945GM(dev)) { + /* aopen mini pc */ + if (dev->pdev->subsystem_vendor == 0xa0a0) + goto failed; + + if ((dev->pdev->subsystem_vendor == 0x8086) && + (dev->pdev->subsystem_device == 0x7270)) { + /* It's a Mac Mini or Macbook Pro. + * + * Apple hardware is out to get us. The macbook pro + * has a real LVDS panel, but the mac mini does not, + * and they have the same device IDs. We'll + * distinguish by panel size, on the assumption + * that Apple isn't about to make any machines with an + * 800x600 display. + */ + + if (dev_priv->panel_fixed_mode != NULL && + dev_priv->panel_fixed_mode->hdisplay == 800 && + dev_priv->panel_fixed_mode->vdisplay == 600) { + DRM_DEBUG("Suspected Mac Mini, ignoring the LVDS\n"); + goto failed; + } + } + } + + out: drm_sysfs_connector_add(connector); return; diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index fbe6f3931b1b..407215469102 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -40,59 +40,13 @@ struct intel_sdvo_priv { struct intel_i2c_chan *i2c_bus; int slaveaddr; - - /* Register for the SDVO device: SDVOB or SDVOC */ int output_device; - /* Active outputs controlled by this SDVO output */ - uint16_t controlled_output; + u16 active_outputs; - /* - * Capabilities of the SDVO device returned by - * i830_sdvo_get_capabilities() - */ struct intel_sdvo_caps caps; - - /* Pixel clock limitations reported by the SDVO device, in kHz */ int pixel_clock_min, pixel_clock_max; - /** - * This is set if we're going to treat the device as TV-out. - * - * While we have these nice friendly flags for output types that ought - * to decide this for us, the S-Video output on our HDMI+S-Video card - * shows up as RGB1 (VGA). - */ - bool is_tv; - - /** - * This is set if we treat the device as HDMI, instead of DVI. - */ - bool is_hdmi; - - /** - * Returned SDTV resolutions allowed for the current format, if the - * device reported it. - */ - struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; - - /** - * Current selected TV format. - * - * This is stored in the same structure that's passed to the device, for - * convenience. - */ - struct intel_sdvo_tv_format tv_format; - - /* - * supported encoding mode, used to determine whether HDMI is - * supported - */ - struct intel_sdvo_encode encode; - - /* DDC bus used by this SDVO output */ - uint8_t ddc_bus; - int save_sdvo_mult; u16 save_active_outputs; struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; @@ -193,9 +147,9 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} /** Mapping of command numbers to names, for debug output */ -static const struct _sdvo_cmd_name { - u8 cmd; - char *name; +const static struct _sdvo_cmd_name { + u8 cmd; + char *name; } sdvo_cmd_names[] = { SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), @@ -232,35 +186,8 @@ static const struct _sdvo_cmd_name { SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT), SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT), SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), - /* HDMI op code */ - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), }; #define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") @@ -579,50 +506,6 @@ static bool intel_sdvo_set_output_timing(struct intel_output *intel_output, SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); } -static bool -intel_sdvo_create_preferred_input_timing(struct intel_output *output, - uint16_t clock, - uint16_t width, - uint16_t height) -{ - struct intel_sdvo_preferred_input_timing_args args; - uint8_t status; - - args.clock = clock; - args.width = width; - args.height = height; - intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, - &args, sizeof(args)); - status = intel_sdvo_read_response(output, NULL, 0); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - return true; -} - -static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output, - struct intel_sdvo_dtd *dtd) -{ - bool status; - - intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, - NULL, 0); - - status = intel_sdvo_read_response(output, &dtd->part1, - sizeof(dtd->part1)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, - NULL, 0); - - status = intel_sdvo_read_response(output, &dtd->part2, - sizeof(dtd->part2)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - return false; -} static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) { @@ -653,12 +536,36 @@ static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 return true; } -static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, - struct drm_display_mode *mode) +static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO + * device will be told of the multiplier during mode_set. + */ + adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); + return true; +} + +static void intel_sdvo_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { - uint16_t width, height; - uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; - uint16_t h_sync_offset, v_sync_offset; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc = encoder->crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_output *intel_output = enc_to_intel_output(encoder); + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + u16 width, height; + u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len; + u16 h_sync_offset, v_sync_offset; + u32 sdvox; + struct intel_sdvo_dtd output_dtd; + int sdvo_pixel_multiply; + + if (!mode) + return; width = mode->crtc_hdisplay; height = mode->crtc_vdisplay; @@ -673,423 +580,93 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; - dtd->part1.clock = mode->clock / 10; - dtd->part1.h_active = width & 0xff; - dtd->part1.h_blank = h_blank_len & 0xff; - dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | + output_dtd.part1.clock = mode->clock / 10; + output_dtd.part1.h_active = width & 0xff; + output_dtd.part1.h_blank = h_blank_len & 0xff; + output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) | ((h_blank_len >> 8) & 0xf); - dtd->part1.v_active = height & 0xff; - dtd->part1.v_blank = v_blank_len & 0xff; - dtd->part1.v_high = (((height >> 8) & 0xf) << 4) | + output_dtd.part1.v_active = height & 0xff; + output_dtd.part1.v_blank = v_blank_len & 0xff; + output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) | ((v_blank_len >> 8) & 0xf); - dtd->part2.h_sync_off = h_sync_offset; - dtd->part2.h_sync_width = h_sync_len & 0xff; - dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | + output_dtd.part2.h_sync_off = h_sync_offset; + output_dtd.part2.h_sync_width = h_sync_len & 0xff; + output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | (v_sync_len & 0xf); - dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | + output_dtd.part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) | ((v_sync_len & 0x30) >> 4); - dtd->part2.dtd_flags = 0x18; + output_dtd.part2.dtd_flags = 0x18; if (mode->flags & DRM_MODE_FLAG_PHSYNC) - dtd->part2.dtd_flags |= 0x2; + output_dtd.part2.dtd_flags |= 0x2; if (mode->flags & DRM_MODE_FLAG_PVSYNC) - dtd->part2.dtd_flags |= 0x4; - - dtd->part2.sdvo_flags = 0; - dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; - dtd->part2.reserved = 0; -} - -static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, - struct intel_sdvo_dtd *dtd) -{ - uint16_t width, height; - uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; - uint16_t h_sync_offset, v_sync_offset; - - width = mode->crtc_hdisplay; - height = mode->crtc_vdisplay; - - /* do some mode translations */ - h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start; - h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; - - v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start; - v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; - - h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; - v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; - - mode->hdisplay = dtd->part1.h_active; - mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; - mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; - mode->hsync_start += (dtd->part2.sync_off_width_high & 0xa0) << 2; - mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; - mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; - mode->htotal = mode->hdisplay + dtd->part1.h_blank; - mode->htotal += (dtd->part1.h_high & 0xf) << 8; - - mode->vdisplay = dtd->part1.v_active; - mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; - mode->vsync_start = mode->vdisplay; - mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; - mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0a) << 2; - mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; - mode->vsync_end = mode->vsync_start + - (dtd->part2.v_sync_off_width & 0xf); - mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; - mode->vtotal = mode->vdisplay + dtd->part1.v_blank; - mode->vtotal += (dtd->part1.v_high & 0xf) << 8; - - mode->clock = dtd->part1.clock * 10; - - mode->flags &= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); - if (dtd->part2.dtd_flags & 0x2) - mode->flags |= DRM_MODE_FLAG_PHSYNC; - if (dtd->part2.dtd_flags & 0x4) - mode->flags |= DRM_MODE_FLAG_PVSYNC; -} - -static bool intel_sdvo_get_supp_encode(struct intel_output *output, - struct intel_sdvo_encode *encode) -{ - uint8_t status; - - intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); - status = intel_sdvo_read_response(output, encode, sizeof(*encode)); - if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ - memset(encode, 0, sizeof(*encode)); - return false; - } - - return true; -} - -static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode) -{ - uint8_t status; - - intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1); - status = intel_sdvo_read_response(output, NULL, 0); - - return (status == SDVO_CMD_STATUS_SUCCESS); -} - -static bool intel_sdvo_set_colorimetry(struct intel_output *output, - uint8_t mode) -{ - uint8_t status; - - intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1); - status = intel_sdvo_read_response(output, NULL, 0); - - return (status == SDVO_CMD_STATUS_SUCCESS); -} - -#if 0 -static void intel_sdvo_dump_hdmi_buf(struct intel_output *output) -{ - int i, j; - uint8_t set_buf_index[2]; - uint8_t av_split; - uint8_t buf_size; - uint8_t buf[48]; - uint8_t *pos; - - intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); - intel_sdvo_read_response(output, &av_split, 1); - - for (i = 0; i <= av_split; i++) { - set_buf_index[0] = i; set_buf_index[1] = 0; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, - set_buf_index, 2); - intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0); - intel_sdvo_read_response(output, &buf_size, 1); - - pos = buf; - for (j = 0; j <= buf_size; j += 8) { - intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA, - NULL, 0); - intel_sdvo_read_response(output, pos, 8); - pos += 8; - } - } -} -#endif - -static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index, - uint8_t *data, int8_t size, uint8_t tx_rate) -{ - uint8_t set_buf_index[2]; - - set_buf_index[0] = index; - set_buf_index[1] = 0; - - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2); - - for (; size > 0; size -= 8) { - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8); - data += 8; - } - - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); -} - -static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) -{ - uint8_t csum = 0; - int i; - - for (i = 0; i < size; i++) - csum += data[i]; - - return 0x100 - csum; -} - -#define DIP_TYPE_AVI 0x82 -#define DIP_VERSION_AVI 0x2 -#define DIP_LEN_AVI 13 - -struct dip_infoframe { - uint8_t type; - uint8_t version; - uint8_t len; - uint8_t checksum; - union { - struct { - /* Packet Byte #1 */ - uint8_t S:2; - uint8_t B:2; - uint8_t A:1; - uint8_t Y:2; - uint8_t rsvd1:1; - /* Packet Byte #2 */ - uint8_t R:4; - uint8_t M:2; - uint8_t C:2; - /* Packet Byte #3 */ - uint8_t SC:2; - uint8_t Q:2; - uint8_t EC:3; - uint8_t ITC:1; - /* Packet Byte #4 */ - uint8_t VIC:7; - uint8_t rsvd2:1; - /* Packet Byte #5 */ - uint8_t PR:4; - uint8_t rsvd3:4; - /* Packet Byte #6~13 */ - uint16_t top_bar_end; - uint16_t bottom_bar_start; - uint16_t left_bar_end; - uint16_t right_bar_start; - } avi; - struct { - /* Packet Byte #1 */ - uint8_t channel_count:3; - uint8_t rsvd1:1; - uint8_t coding_type:4; - /* Packet Byte #2 */ - uint8_t sample_size:2; /* SS0, SS1 */ - uint8_t sample_frequency:3; - uint8_t rsvd2:3; - /* Packet Byte #3 */ - uint8_t coding_type_private:5; - uint8_t rsvd3:3; - /* Packet Byte #4 */ - uint8_t channel_allocation; - /* Packet Byte #5 */ - uint8_t rsvd4:3; - uint8_t level_shift:4; - uint8_t downmix_inhibit:1; - } audio; - uint8_t payload[28]; - } __attribute__ ((packed)) u; -} __attribute__((packed)); - -static void intel_sdvo_set_avi_infoframe(struct intel_output *output, - struct drm_display_mode * mode) -{ - struct dip_infoframe avi_if = { - .type = DIP_TYPE_AVI, - .version = DIP_VERSION_AVI, - .len = DIP_LEN_AVI, - }; - - avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, - 4 + avi_if.len); - intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len, - SDVO_HBUF_TX_VSYNC); -} - -static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct intel_output *output = enc_to_intel_output(encoder); - struct intel_sdvo_priv *dev_priv = output->dev_priv; + output_dtd.part2.dtd_flags |= 0x4; - if (!dev_priv->is_tv) { - /* Make the CRTC code factor in the SDVO pixel multiplier. The - * SDVO device will be told of the multiplier during mode_set. - */ - adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); - } else { - struct intel_sdvo_dtd output_dtd; - bool success; - - /* We need to construct preferred input timings based on our - * output timings. To do that, we have to set the output - * timings, even though this isn't really the right place in - * the sequence to do it. Oh well. - */ - - - /* Set output timings */ - intel_sdvo_get_dtd_from_mode(&output_dtd, mode); - intel_sdvo_set_target_output(output, - dev_priv->controlled_output); - intel_sdvo_set_output_timing(output, &output_dtd); - - /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, true, false); - - - success = intel_sdvo_create_preferred_input_timing(output, - mode->clock / 10, - mode->hdisplay, - mode->vdisplay); - if (success) { - struct intel_sdvo_dtd input_dtd; + output_dtd.part2.sdvo_flags = 0; + output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0; + output_dtd.part2.reserved = 0; - intel_sdvo_get_preferred_input_timing(output, - &input_dtd); - intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); - - } else { - return false; - } - } - return true; -} - -static void intel_sdvo_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = encoder->crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *output = enc_to_intel_output(encoder); - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; - u32 sdvox = 0; - int sdvo_pixel_multiply; - struct intel_sdvo_in_out_map in_out; - struct intel_sdvo_dtd input_dtd; - u8 status; - - if (!mode) - return; - - /* First, set the input mapping for the first input to our controlled - * output. This is only correct if we're a single-input device, in - * which case the first input is the output from the appropriate SDVO - * channel on the motherboard. In a two-input device, the first input - * will be SDVOB and the second SDVOC. - */ - in_out.in0 = sdvo_priv->controlled_output; - in_out.in1 = 0; - - intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, - &in_out, sizeof(in_out)); - status = intel_sdvo_read_response(output, NULL, 0); - - if (sdvo_priv->is_hdmi) { - intel_sdvo_set_avi_infoframe(output, mode); - sdvox |= SDVO_AUDIO_ENABLE; - } - - intel_sdvo_get_dtd_from_mode(&input_dtd, mode); - - /* If it's a TV, we already set the output timing in mode_fixup. - * Otherwise, the output timing is equal to the input timing. - */ - if (!sdvo_priv->is_tv) { - /* Set the output timing to the screen */ - intel_sdvo_set_target_output(output, - sdvo_priv->controlled_output); - intel_sdvo_set_output_timing(output, &input_dtd); - } + /* Set the output timing to the screen */ + intel_sdvo_set_target_output(intel_output, sdvo_priv->active_outputs); + intel_sdvo_set_output_timing(intel_output, &output_dtd); /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, true, false); + intel_sdvo_set_target_input(intel_output, true, false); - /* We would like to use intel_sdvo_create_preferred_input_timing() to + /* We would like to use i830_sdvo_create_preferred_input_timing() to * provide the device with a timing it can support, if it supports that * feature. However, presumably we would need to adjust the CRTC to * output the preferred timing, and we don't support that currently. */ -#if 0 - success = intel_sdvo_create_preferred_input_timing(output, clock, - width, height); - if (success) { - struct intel_sdvo_dtd *input_dtd; - - intel_sdvo_get_preferred_input_timing(output, &input_dtd); - intel_sdvo_set_input_timing(output, &input_dtd); - } -#else - intel_sdvo_set_input_timing(output, &input_dtd); -#endif + intel_sdvo_set_input_timing(intel_output, &output_dtd); switch (intel_sdvo_get_pixel_multiplier(mode)) { case 1: - intel_sdvo_set_clock_rate_mult(output, + intel_sdvo_set_clock_rate_mult(intel_output, SDVO_CLOCK_RATE_MULT_1X); break; case 2: - intel_sdvo_set_clock_rate_mult(output, + intel_sdvo_set_clock_rate_mult(intel_output, SDVO_CLOCK_RATE_MULT_2X); break; case 4: - intel_sdvo_set_clock_rate_mult(output, + intel_sdvo_set_clock_rate_mult(intel_output, SDVO_CLOCK_RATE_MULT_4X); break; } /* Set the SDVO control regs. */ - if (IS_I965G(dev)) { - sdvox |= SDVO_BORDER_ENABLE | - SDVO_VSYNC_ACTIVE_HIGH | - SDVO_HSYNC_ACTIVE_HIGH; - } else { - sdvox |= I915_READ(sdvo_priv->output_device); - switch (sdvo_priv->output_device) { - case SDVOB: - sdvox &= SDVOB_PRESERVE_MASK; - break; - case SDVOC: - sdvox &= SDVOC_PRESERVE_MASK; - break; - } - sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; - } + if (0/*IS_I965GM(dev)*/) { + sdvox = SDVO_BORDER_ENABLE; + } else { + sdvox = I915_READ(sdvo_priv->output_device); + switch (sdvo_priv->output_device) { + case SDVOB: + sdvox &= SDVOB_PRESERVE_MASK; + break; + case SDVOC: + sdvox &= SDVOC_PRESERVE_MASK; + break; + } + sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; + } if (intel_crtc->pipe == 1) sdvox |= SDVO_PIPE_B_SELECT; sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); if (IS_I965G(dev)) { - /* done in crtc_mode_set as the dpll_md reg must be written early */ - } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { - /* done in crtc_mode_set as it lives inside the dpll register */ + /* done in crtc_mode_set as the dpll_md reg must be written + early */ + } else if (IS_I945G(dev) || IS_I945GM(dev)) { + /* done in crtc_mode_set as it lives inside the + dpll register */ } else { sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; } - intel_sdvo_write_sdvox(output, sdvox); + intel_sdvo_write_sdvox(intel_output, sdvox); } static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) @@ -1137,7 +714,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) if (0) intel_sdvo_set_encoder_power_state(intel_output, mode); - intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output); + intel_sdvo_set_active_outputs(intel_output, sdvo_priv->active_outputs); } return; } @@ -1175,9 +752,6 @@ static void intel_sdvo_save(struct drm_connector *connector) &sdvo_priv->save_output_dtd[o]); } } - if (sdvo_priv->is_tv) { - /* XXX: Save TV format/enhancements. */ - } sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device); } @@ -1185,6 +759,7 @@ static void intel_sdvo_save(struct drm_connector *connector) static void intel_sdvo_restore(struct drm_connector *connector) { struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct intel_output *intel_output = to_intel_output(connector); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; int o; @@ -1215,11 +790,7 @@ static void intel_sdvo_restore(struct drm_connector *connector) intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult); - if (sdvo_priv->is_tv) { - /* XXX: Restore TV format/enhancements. */ - } - - intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX); + I915_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX); if (sdvo_priv->save_SDVOX & SDVO_ENABLE) { @@ -1345,173 +916,20 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect status = intel_sdvo_read_response(intel_output, &response, 2); DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]); - - if (status != SDVO_CMD_STATUS_SUCCESS) - return connector_status_unknown; - if ((response[0] != 0) || (response[1] != 0)) return connector_status_connected; else return connector_status_disconnected; } -static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) +static int intel_sdvo_get_modes(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; /* set the bus switch and get the modes */ - intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); + intel_sdvo_set_control_bus_switch(intel_output, SDVO_CONTROL_BUS_DDC2); intel_ddc_get_modes(intel_output); -#if 0 - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - /* Mac mini hack. On this device, I get DDC through the analog, which - * load-detects as disconnected. I fail to DDC through the SDVO DDC, - * but it does load-detect as connected. So, just steal the DDC bits - * from analog when we fail at finding it the right way. - */ - crt = xf86_config->output[0]; - intel_output = crt->driver_private; - if (intel_output->type == I830_OUTPUT_ANALOG && - crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { - I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A"); - edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus); - xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true); - } - if (edid_mon) { - xf86OutputSetEDID(output, edid_mon); - modes = xf86OutputGetEDIDModes(output); - } -#endif -} - -/** - * This function checks the current TV format, and chooses a default if - * it hasn't been set. - */ -static void -intel_sdvo_check_tv_format(struct intel_output *output) -{ - struct intel_sdvo_priv *dev_priv = output->dev_priv; - struct intel_sdvo_tv_format format, unset; - uint8_t status; - - intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0); - status = intel_sdvo_read_response(output, &format, sizeof(format)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return; - - memset(&unset, 0, sizeof(unset)); - if (memcmp(&format, &unset, sizeof(format))) { - DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n", - SDVO_NAME(dev_priv)); - - format.ntsc_m = true; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0); - status = intel_sdvo_read_response(output, NULL, 0); - } -} - -/* - * Set of SDVO TV modes. - * Note! This is in reply order (see loop in get_tv_modes). - * XXX: all 60Hz refresh? - */ -struct drm_display_mode sdvo_tv_modes[] = { - { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815680, 321, 384, 416, - 200, 0, 232, 201, 233, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814080, 321, 384, 416, - 240, 0, 272, 241, 273, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910080, 401, 464, 496, - 300, 0, 332, 301, 333, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913280, 641, 704, 736, - 350, 0, 382, 351, 383, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736, - 400, 0, 432, 401, 433, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736, - 400, 0, 432, 401, 433, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624000, 705, 768, 800, - 480, 0, 512, 481, 513, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232000, 705, 768, 800, - 576, 0, 608, 577, 609, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751680, 721, 784, 816, - 350, 0, 382, 351, 383, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199680, 721, 784, 816, - 400, 0, 432, 401, 433, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116480, 721, 784, 816, - 480, 0, 512, 481, 513, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054080, 721, 784, 816, - 540, 0, 572, 541, 573, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816640, 721, 784, 816, - 576, 0, 608, 577, 609, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570560, 769, 832, 864, - 576, 0, 608, 577, 609, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030080, 801, 864, 896, - 600, 0, 632, 601, 633, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581760, 833, 896, 928, - 624, 0, 656, 625, 657, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707040, 921, 984, 1016, - 766, 0, 798, 767, 799, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827200, 1025, 1088, 1120, - 768, 0, 800, 769, 801, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265920, 1281, 1344, 1376, - 1024, 0, 1056, 1025, 1057, 4196112, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -}; - -static void intel_sdvo_get_tv_modes(struct drm_connector *connector) -{ - struct intel_output *output = to_intel_output(connector); - uint32_t reply = 0; - uint8_t status; - int i = 0; - - intel_sdvo_check_tv_format(output); - - /* Read the list of supported input resolutions for the selected TV - * format. - */ - intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, - NULL, 0); - status = intel_sdvo_read_response(output, &reply, 3); - if (status != SDVO_CMD_STATUS_SUCCESS) - return; - - for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) - if (reply & (1 << i)) - drm_mode_probed_add(connector, &sdvo_tv_modes[i]); -} - -static int intel_sdvo_get_modes(struct drm_connector *connector) -{ - struct intel_output *output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; - - if (sdvo_priv->is_tv) - intel_sdvo_get_tv_modes(connector); - else - intel_sdvo_get_ddc_modes(connector); - if (list_empty(&connector->probed_modes)) return 0; return 1; @@ -1560,65 +978,6 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { }; -/** - * Choose the appropriate DDC bus for control bus switch command for this - * SDVO output based on the controlled output. - * - * DDC bus number assignment is in a priority order of RGB outputs, then TMDS - * outputs, then LVDS outputs. - */ -static void -intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv) -{ - uint16_t mask = 0; - unsigned int num_bits; - - /* Make a mask of outputs less than or equal to our own priority in the - * list. - */ - switch (dev_priv->controlled_output) { - case SDVO_OUTPUT_LVDS1: - mask |= SDVO_OUTPUT_LVDS1; - case SDVO_OUTPUT_LVDS0: - mask |= SDVO_OUTPUT_LVDS0; - case SDVO_OUTPUT_TMDS1: - mask |= SDVO_OUTPUT_TMDS1; - case SDVO_OUTPUT_TMDS0: - mask |= SDVO_OUTPUT_TMDS0; - case SDVO_OUTPUT_RGB1: - mask |= SDVO_OUTPUT_RGB1; - case SDVO_OUTPUT_RGB0: - mask |= SDVO_OUTPUT_RGB0; - break; - } - - /* Count bits to find what number we are in the priority list. */ - mask &= dev_priv->caps.output_flags; - num_bits = hweight16(mask); - if (num_bits > 3) { - /* if more than 3 outputs, default to DDC bus 3 for now */ - num_bits = 3; - } - - /* Corresponds to SDVO_CONTROL_BUS_DDCx */ - dev_priv->ddc_bus = 1 << num_bits; -} - -static bool -intel_sdvo_get_digital_encoding_mode(struct intel_output *output) -{ - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; - uint8_t status; - - intel_sdvo_set_target_output(output, sdvo_priv->controlled_output); - - intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); - status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - return true; -} - bool intel_sdvo_init(struct drm_device *dev, int output_device) { struct drm_connector *connector; @@ -1681,76 +1040,45 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); - if (sdvo_priv->caps.output_flags & - (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { - if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) - sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0; - else - sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; - - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - encoder_type = DRM_MODE_ENCODER_TMDS; - connector_type = DRM_MODE_CONNECTOR_DVID; + memset(&sdvo_priv->active_outputs, 0, sizeof(sdvo_priv->active_outputs)); - if (intel_sdvo_get_supp_encode(intel_output, - &sdvo_priv->encode) && - intel_sdvo_get_digital_encoding_mode(intel_output) && - sdvo_priv->is_hdmi) { - /* enable hdmi encoding mode if supported */ - intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); - intel_sdvo_set_colorimetry(intel_output, - SDVO_COLORIMETRY_RGB256); - connector_type = DRM_MODE_CONNECTOR_HDMIA; - } - } - else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0) + /* TODO, CVBS, SVID, YPRPB & SCART outputs. */ + if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) { - sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - encoder_type = DRM_MODE_ENCODER_TVDAC; - connector_type = DRM_MODE_CONNECTOR_SVIDEO; - sdvo_priv->is_tv = true; - intel_output->needs_tv_clock = true; - } - else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) - { - sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; + sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0; connector->display_info.subpixel_order = SubPixelHorizontalRGB; encoder_type = DRM_MODE_ENCODER_DAC; connector_type = DRM_MODE_CONNECTOR_VGA; } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) { - sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; + sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1; connector->display_info.subpixel_order = SubPixelHorizontalRGB; encoder_type = DRM_MODE_ENCODER_DAC; connector_type = DRM_MODE_CONNECTOR_VGA; } - else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0) + else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) { - sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; + sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0; connector->display_info.subpixel_order = SubPixelHorizontalRGB; - encoder_type = DRM_MODE_ENCODER_LVDS; - connector_type = DRM_MODE_CONNECTOR_LVDS; + encoder_type = DRM_MODE_ENCODER_TMDS; + connector_type = DRM_MODE_CONNECTOR_DVID; } - else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1) + else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) { - sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; + sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1; connector->display_info.subpixel_order = SubPixelHorizontalRGB; - encoder_type = DRM_MODE_ENCODER_LVDS; - connector_type = DRM_MODE_CONNECTOR_LVDS; + encoder_type = DRM_MODE_ENCODER_TMDS; + connector_type = DRM_MODE_CONNECTOR_DVID; } else { unsigned char bytes[2]; - sdvo_priv->controlled_output = 0; memcpy (bytes, &sdvo_priv->caps.output_flags, 2); - DRM_DEBUG("%s: Unknown SDVO output type (0x%02x%02x)\n", + DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n", SDVO_NAME(sdvo_priv), bytes[0], bytes[1]); - encoder_type = DRM_MODE_ENCODER_NONE; - connector_type = DRM_MODE_CONNECTOR_Unknown; goto err_i2c; } @@ -1761,8 +1089,6 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); drm_sysfs_connector_add(connector); - intel_sdvo_select_ddc_bus(sdvo_priv); - /* Set the input timing to the screen. Assume always input 0. */ intel_sdvo_set_target_input(intel_output, true, false); diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h b/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h index 1117b9c151a6..861a43f8693c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h @@ -173,9 +173,6 @@ struct intel_sdvo_get_trained_inputs_response { * Returns two struct intel_sdvo_output_flags structures. */ #define SDVO_CMD_GET_IN_OUT_MAP 0x06 -struct intel_sdvo_in_out_map { - u16 in0, in1; -}; /** * Sets the current mapping of SDVO inputs to outputs on the device. @@ -209,8 +206,7 @@ struct intel_sdvo_in_out_map { struct intel_sdvo_get_interrupt_event_source_response { u16 interrupt_status; unsigned int ambient_light_interrupt:1; - unsigned int hdmi_audio_encrypt_change:1; - unsigned int pad:6; + unsigned int pad:7; } __attribute__((packed)); /** @@ -309,411 +305,23 @@ struct intel_sdvo_set_target_input_args { # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 -/** 5 bytes of bit flags for TV formats shared by all TV format functions */ -struct intel_sdvo_tv_format { - unsigned int ntsc_m:1; - unsigned int ntsc_j:1; - unsigned int ntsc_443:1; - unsigned int pal_b:1; - unsigned int pal_d:1; - unsigned int pal_g:1; - unsigned int pal_h:1; - unsigned int pal_i:1; - - unsigned int pal_m:1; - unsigned int pal_n:1; - unsigned int pal_nc:1; - unsigned int pal_60:1; - unsigned int secam_b:1; - unsigned int secam_d:1; - unsigned int secam_g:1; - unsigned int secam_k:1; - - unsigned int secam_k1:1; - unsigned int secam_l:1; - unsigned int secam_60:1; - unsigned int hdtv_std_smpte_240m_1080i_59:1; - unsigned int hdtv_std_smpte_240m_1080i_60:1; - unsigned int hdtv_std_smpte_260m_1080i_59:1; - unsigned int hdtv_std_smpte_260m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080i_50:1; - - unsigned int hdtv_std_smpte_274m_1080i_59:1; - unsigned int hdtv_std_smpte_274m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080p_23:1; - unsigned int hdtv_std_smpte_274m_1080p_24:1; - unsigned int hdtv_std_smpte_274m_1080p_25:1; - unsigned int hdtv_std_smpte_274m_1080p_29:1; - unsigned int hdtv_std_smpte_274m_1080p_30:1; - unsigned int hdtv_std_smpte_274m_1080p_50:1; - - unsigned int hdtv_std_smpte_274m_1080p_59:1; - unsigned int hdtv_std_smpte_274m_1080p_60:1; - unsigned int hdtv_std_smpte_295m_1080i_50:1; - unsigned int hdtv_std_smpte_295m_1080p_50:1; - unsigned int hdtv_std_smpte_296m_720p_59:1; - unsigned int hdtv_std_smpte_296m_720p_60:1; - unsigned int hdtv_std_smpte_296m_720p_50:1; - unsigned int hdtv_std_smpte_293m_480p_59:1; - - unsigned int hdtv_std_smpte_170m_480i_59:1; - unsigned int hdtv_std_iturbt601_576i_50:1; - unsigned int hdtv_std_iturbt601_576p_50:1; - unsigned int hdtv_std_eia_7702a_480i_60:1; - unsigned int hdtv_std_eia_7702a_480p_60:1; - unsigned int pad:3; -} __attribute__((packed)); #define SDVO_CMD_GET_TV_FORMAT 0x28 #define SDVO_CMD_SET_TV_FORMAT 0x29 -/** Returns the resolutiosn that can be used with the given TV format */ -#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83 -struct intel_sdvo_sdtv_resolution_request { - unsigned int ntsc_m:1; - unsigned int ntsc_j:1; - unsigned int ntsc_443:1; - unsigned int pal_b:1; - unsigned int pal_d:1; - unsigned int pal_g:1; - unsigned int pal_h:1; - unsigned int pal_i:1; - - unsigned int pal_m:1; - unsigned int pal_n:1; - unsigned int pal_nc:1; - unsigned int pal_60:1; - unsigned int secam_b:1; - unsigned int secam_d:1; - unsigned int secam_g:1; - unsigned int secam_k:1; - - unsigned int secam_k1:1; - unsigned int secam_l:1; - unsigned int secam_60:1; - unsigned int pad:5; -} __attribute__((packed)); - -struct intel_sdvo_sdtv_resolution_reply { - unsigned int res_320x200:1; - unsigned int res_320x240:1; - unsigned int res_400x300:1; - unsigned int res_640x350:1; - unsigned int res_640x400:1; - unsigned int res_640x480:1; - unsigned int res_704x480:1; - unsigned int res_704x576:1; - - unsigned int res_720x350:1; - unsigned int res_720x400:1; - unsigned int res_720x480:1; - unsigned int res_720x540:1; - unsigned int res_720x576:1; - unsigned int res_768x576:1; - unsigned int res_800x600:1; - unsigned int res_832x624:1; - - unsigned int res_920x766:1; - unsigned int res_1024x768:1; - unsigned int res_1280x1024:1; - unsigned int pad:5; -} __attribute__((packed)); - -/* Get supported resolution with squire pixel aspect ratio that can be - scaled for the requested HDTV format */ -#define SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT 0x85 - -struct intel_sdvo_hdtv_resolution_request { - unsigned int hdtv_std_smpte_240m_1080i_59:1; - unsigned int hdtv_std_smpte_240m_1080i_60:1; - unsigned int hdtv_std_smpte_260m_1080i_59:1; - unsigned int hdtv_std_smpte_260m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080i_50:1; - unsigned int hdtv_std_smpte_274m_1080i_59:1; - unsigned int hdtv_std_smpte_274m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080p_23:1; - - unsigned int hdtv_std_smpte_274m_1080p_24:1; - unsigned int hdtv_std_smpte_274m_1080p_25:1; - unsigned int hdtv_std_smpte_274m_1080p_29:1; - unsigned int hdtv_std_smpte_274m_1080p_30:1; - unsigned int hdtv_std_smpte_274m_1080p_50:1; - unsigned int hdtv_std_smpte_274m_1080p_59:1; - unsigned int hdtv_std_smpte_274m_1080p_60:1; - unsigned int hdtv_std_smpte_295m_1080i_50:1; - - unsigned int hdtv_std_smpte_295m_1080p_50:1; - unsigned int hdtv_std_smpte_296m_720p_59:1; - unsigned int hdtv_std_smpte_296m_720p_60:1; - unsigned int hdtv_std_smpte_296m_720p_50:1; - unsigned int hdtv_std_smpte_293m_480p_59:1; - unsigned int hdtv_std_smpte_170m_480i_59:1; - unsigned int hdtv_std_iturbt601_576i_50:1; - unsigned int hdtv_std_iturbt601_576p_50:1; - - unsigned int hdtv_std_eia_7702a_480i_60:1; - unsigned int hdtv_std_eia_7702a_480p_60:1; - unsigned int pad:6; -} __attribute__((packed)); - -struct intel_sdvo_hdtv_resolution_reply { - unsigned int res_640x480:1; - unsigned int res_800x600:1; - unsigned int res_1024x768:1; - unsigned int res_1280x960:1; - unsigned int res_1400x1050:1; - unsigned int res_1600x1200:1; - unsigned int res_1920x1440:1; - unsigned int res_2048x1536:1; - - unsigned int res_2560x1920:1; - unsigned int res_3200x2400:1; - unsigned int res_3840x2880:1; - unsigned int pad1:5; - - unsigned int res_848x480:1; - unsigned int res_1064x600:1; - unsigned int res_1280x720:1; - unsigned int res_1360x768:1; - unsigned int res_1704x960:1; - unsigned int res_1864x1050:1; - unsigned int res_1920x1080:1; - unsigned int res_2128x1200:1; - - unsigned int res_2560x1400:1; - unsigned int res_2728x1536:1; - unsigned int res_3408x1920:1; - unsigned int res_4264x2400:1; - unsigned int res_5120x2880:1; - unsigned int pad2:3; - - unsigned int res_768x480:1; - unsigned int res_960x600:1; - unsigned int res_1152x720:1; - unsigned int res_1124x768:1; - unsigned int res_1536x960:1; - unsigned int res_1680x1050:1; - unsigned int res_1728x1080:1; - unsigned int res_1920x1200:1; - - unsigned int res_2304x1440:1; - unsigned int res_2456x1536:1; - unsigned int res_3072x1920:1; - unsigned int res_3840x2400:1; - unsigned int res_4608x2880:1; - unsigned int pad3:3; - - unsigned int res_1280x1024:1; - unsigned int pad4:7; - - unsigned int res_1280x768:1; - unsigned int pad5:7; -} __attribute__((packed)); - -/* Get supported power state returns info for encoder and monitor, rely on - last SetTargetInput and SetTargetOutput calls */ #define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a -/* Get power state returns info for encoder and monitor, rely on last - SetTargetInput and SetTargetOutput calls */ -#define SDVO_CMD_GET_POWER_STATE 0x2b #define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b #define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c # define SDVO_ENCODER_STATE_ON (1 << 0) # define SDVO_ENCODER_STATE_STANDBY (1 << 1) # define SDVO_ENCODER_STATE_SUSPEND (1 << 2) # define SDVO_ENCODER_STATE_OFF (1 << 3) -# define SDVO_MONITOR_STATE_ON (1 << 4) -# define SDVO_MONITOR_STATE_STANDBY (1 << 5) -# define SDVO_MONITOR_STATE_SUSPEND (1 << 6) -# define SDVO_MONITOR_STATE_OFF (1 << 7) - -#define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING 0x2d -#define SDVO_CMD_GET_PANEL_POWER_SEQUENCING 0x2e -#define SDVO_CMD_SET_PANEL_POWER_SEQUENCING 0x2f -/** - * The panel power sequencing parameters are in units of milliseconds. - * The high fields are bits 8:9 of the 10-bit values. - */ -struct sdvo_panel_power_sequencing { - u8 t0; - u8 t1; - u8 t2; - u8 t3; - u8 t4; - - unsigned int t0_high:2; - unsigned int t1_high:2; - unsigned int t2_high:2; - unsigned int t3_high:2; - - unsigned int t4_high:2; - unsigned int pad:6; -} __attribute__((packed)); - -#define SDVO_CMD_GET_MAX_BACKLIGHT_LEVEL 0x30 -struct sdvo_max_backlight_reply { - u8 max_value; - u8 default_value; -} __attribute__((packed)); - -#define SDVO_CMD_GET_BACKLIGHT_LEVEL 0x31 -#define SDVO_CMD_SET_BACKLIGHT_LEVEL 0x32 - -#define SDVO_CMD_GET_AMBIENT_LIGHT 0x33 -struct sdvo_get_ambient_light_reply { - u16 trip_low; - u16 trip_high; - u16 value; -} __attribute__((packed)); -#define SDVO_CMD_SET_AMBIENT_LIGHT 0x34 -struct sdvo_set_ambient_light_reply { - u16 trip_low; - u16 trip_high; - unsigned int enable:1; - unsigned int pad:7; -} __attribute__((packed)); - -/* Set display power state */ -#define SDVO_CMD_SET_DISPLAY_POWER_STATE 0x7d -# define SDVO_DISPLAY_STATE_ON (1 << 0) -# define SDVO_DISPLAY_STATE_STANDBY (1 << 1) -# define SDVO_DISPLAY_STATE_SUSPEND (1 << 2) -# define SDVO_DISPLAY_STATE_OFF (1 << 3) - -#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84 -struct intel_sdvo_enhancements_reply { - unsigned int flicker_filter:1; - unsigned int flicker_filter_adaptive:1; - unsigned int flicker_filter_2d:1; - unsigned int saturation:1; - unsigned int hue:1; - unsigned int brightness:1; - unsigned int contrast:1; - unsigned int overscan_h:1; - - unsigned int overscan_v:1; - unsigned int position_h:1; - unsigned int position_v:1; - unsigned int sharpness:1; - unsigned int dot_crawl:1; - unsigned int dither:1; - unsigned int max_tv_chroma_filter:1; - unsigned int max_tv_luma_filter:1; -} __attribute__((packed)); - -/* Picture enhancement limits below are dependent on the current TV format, - * and thus need to be queried and set after it. - */ -#define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d -#define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b -#define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52 -#define SDVO_CMD_GET_MAX_SATURATION 0x55 -#define SDVO_CMD_GET_MAX_HUE 0x58 -#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b -#define SDVO_CMD_GET_MAX_CONTRAST 0x5e -#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 -#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 -#define SDVO_CMD_GET_MAX_POSITION_H 0x67 -#define SDVO_CMD_GET_MAX_POSITION_V 0x6a -#define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d -#define SDVO_CMD_GET_MAX_TV_CHROMA 0x74 -#define SDVO_CMD_GET_MAX_TV_LUMA 0x77 -struct intel_sdvo_enhancement_limits_reply { - u16 max_value; - u16 default_value; -} __attribute__((packed)); -#define SDVO_CMD_GET_LVDS_PANEL_INFORMATION 0x7f -#define SDVO_CMD_SET_LVDS_PANEL_INFORMATION 0x80 -# define SDVO_LVDS_COLOR_DEPTH_18 (0 << 0) -# define SDVO_LVDS_COLOR_DEPTH_24 (1 << 0) -# define SDVO_LVDS_CONNECTOR_SPWG (0 << 2) -# define SDVO_LVDS_CONNECTOR_OPENLDI (1 << 2) -# define SDVO_LVDS_SINGLE_CHANNEL (0 << 4) -# define SDVO_LVDS_DUAL_CHANNEL (1 << 4) - -#define SDVO_CMD_GET_FLICKER_FILTER 0x4e -#define SDVO_CMD_SET_FLICKER_FILTER 0x4f -#define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50 -#define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51 -#define SDVO_CMD_GET_2D_FLICKER_FITER 0x53 -#define SDVO_CMD_SET_2D_FLICKER_FITER 0x54 -#define SDVO_CMD_GET_SATURATION 0x56 -#define SDVO_CMD_SET_SATURATION 0x57 -#define SDVO_CMD_GET_HUE 0x59 -#define SDVO_CMD_SET_HUE 0x5a -#define SDVO_CMD_GET_BRIGHTNESS 0x5c -#define SDVO_CMD_SET_BRIGHTNESS 0x5d -#define SDVO_CMD_GET_CONTRAST 0x5f -#define SDVO_CMD_SET_CONTRAST 0x60 -#define SDVO_CMD_GET_OVERSCAN_H 0x62 -#define SDVO_CMD_SET_OVERSCAN_H 0x63 -#define SDVO_CMD_GET_OVERSCAN_V 0x65 -#define SDVO_CMD_SET_OVERSCAN_V 0x66 -#define SDVO_CMD_GET_POSITION_H 0x68 -#define SDVO_CMD_SET_POSITION_H 0x69 -#define SDVO_CMD_GET_POSITION_V 0x6b -#define SDVO_CMD_SET_POSITION_V 0x6c -#define SDVO_CMD_GET_SHARPNESS 0x6e -#define SDVO_CMD_SET_SHARPNESS 0x6f -#define SDVO_CMD_GET_TV_CHROMA 0x75 -#define SDVO_CMD_SET_TV_CHROMA 0x76 -#define SDVO_CMD_GET_TV_LUMA 0x78 -#define SDVO_CMD_SET_TV_LUMA 0x79 -struct intel_sdvo_enhancements_arg { - u16 value; -}__attribute__((packed)); - -#define SDVO_CMD_GET_DOT_CRAWL 0x70 -#define SDVO_CMD_SET_DOT_CRAWL 0x71 -# define SDVO_DOT_CRAWL_ON (1 << 0) -# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1) - -#define SDVO_CMD_GET_DITHER 0x72 -#define SDVO_CMD_SET_DITHER 0x73 -# define SDVO_DITHER_ON (1 << 0) -# define SDVO_DITHER_DEFAULT_ON (1 << 1) +#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93 #define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a -# define SDVO_CONTROL_BUS_PROM (1 << 0) -# define SDVO_CONTROL_BUS_DDC1 (1 << 1) -# define SDVO_CONTROL_BUS_DDC2 (1 << 2) -# define SDVO_CONTROL_BUS_DDC3 (1 << 3) - -/* HDMI op codes */ -#define SDVO_CMD_GET_SUPP_ENCODE 0x9d -#define SDVO_CMD_GET_ENCODE 0x9e -#define SDVO_CMD_SET_ENCODE 0x9f - #define SDVO_ENCODE_DVI 0x0 - #define SDVO_ENCODE_HDMI 0x1 -#define SDVO_CMD_SET_PIXEL_REPLI 0x8b -#define SDVO_CMD_GET_PIXEL_REPLI 0x8c -#define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d -#define SDVO_CMD_SET_COLORIMETRY 0x8e - #define SDVO_COLORIMETRY_RGB256 0x0 - #define SDVO_COLORIMETRY_RGB220 0x1 - #define SDVO_COLORIMETRY_YCrCb422 0x3 - #define SDVO_COLORIMETRY_YCrCb444 0x4 -#define SDVO_CMD_GET_COLORIMETRY 0x8f -#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90 -#define SDVO_CMD_SET_AUDIO_STAT 0x91 -#define SDVO_CMD_GET_AUDIO_STAT 0x92 -#define SDVO_CMD_SET_HBUF_INDEX 0x93 -#define SDVO_CMD_GET_HBUF_INDEX 0x94 -#define SDVO_CMD_GET_HBUF_INFO 0x95 -#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 -#define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97 -#define SDVO_CMD_SET_HBUF_DATA 0x98 -#define SDVO_CMD_GET_HBUF_DATA 0x99 -#define SDVO_CMD_SET_HBUF_TXRATE 0x9a -#define SDVO_CMD_GET_HBUF_TXRATE 0x9b - #define SDVO_HBUF_TX_DISABLED (0 << 6) - #define SDVO_HBUF_TX_ONCE (2 << 6) - #define SDVO_HBUF_TX_VSYNC (3 << 6) -#define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c - -struct intel_sdvo_encode{ - u8 dvi_rev; - u8 hdmi_rev; -} __attribute__ ((packed)); +# define SDVO_CONTROL_BUS_PROM 0x0 +# define SDVO_CONTROL_BUS_DDC1 0x1 +# define SDVO_CONTROL_BUS_DDC2 0x2 +# define SDVO_CONTROL_BUS_DDC3 0x3 diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c index 56485d67369b..fbb35dc56f5c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_tv.c +++ b/trunk/drivers/gpu/drm/i915/intel_tv.c @@ -411,7 +411,7 @@ struct tv_mode { * These values account for -1s required. */ -static const struct tv_mode tv_modes[] = { +const static struct tv_mode tv_modes[] = { { .name = "NTSC-M", .clock = 107520, diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cp.c b/trunk/drivers/gpu/drm/radeon/radeon_cp.c index 92965dbb3c14..63212d7bbc28 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cp.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cp.c @@ -557,10 +557,8 @@ static int radeon_do_engine_reset(struct drm_device * dev) } static void radeon_cp_init_ring_buffer(struct drm_device * dev, - drm_radeon_private_t *dev_priv, - struct drm_file *file_priv) + drm_radeon_private_t * dev_priv) { - struct drm_radeon_master_private *master_priv; u32 ring_start, cur_read_ptr; u32 tmp; @@ -679,14 +677,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->scratch[2] = 0; RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); - /* reset sarea copies of these */ - master_priv = file_priv->master->driver_priv; - if (master_priv->sarea_priv) { - master_priv->sarea_priv->last_frame = 0; - master_priv->sarea_priv->last_dispatch = 0; - master_priv->sarea_priv->last_clear = 0; - } - radeon_do_wait_for_idle(dev_priv); /* Sync everything up */ @@ -1049,9 +1039,9 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) { - drm_core_ioremap_wc(dev_priv->cp_ring, dev); - drm_core_ioremap_wc(dev_priv->ring_rptr, dev); - drm_core_ioremap_wc(dev->agp_buffer_map, dev); + drm_core_ioremap(dev_priv->cp_ring, dev); + drm_core_ioremap(dev_priv->ring_rptr, dev); + drm_core_ioremap(dev->agp_buffer_map, dev); if (!dev_priv->cp_ring->handle || !dev_priv->ring_rptr->handle || !dev->agp_buffer_map->handle) { @@ -1225,7 +1215,7 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, } radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); + radeon_cp_init_ring_buffer(dev, dev_priv); dev_priv->last_buf = 0; @@ -1291,7 +1281,7 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) * * Charl P. Botha */ -static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) +static int radeon_do_resume_cp(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -1314,7 +1304,7 @@ static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_pri } radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); + radeon_cp_init_ring_buffer(dev, dev_priv); radeon_do_engine_reset(dev); radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); @@ -1489,7 +1479,8 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri */ int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) { - return radeon_do_resume_cp(dev, file_priv); + + return radeon_do_resume_cp(dev); } int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index 1cc967448f4d..6cad69ed21c5 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -1300,13 +1300,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, @@ -1611,7 +1605,6 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, - { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) }, { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) }, { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) }, @@ -1619,6 +1612,10 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) }, { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, @@ -1629,6 +1626,8 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, { } }; diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h index 88511970508d..e899f510ebeb 100644 --- a/trunk/drivers/hid/hid-ids.h +++ b/trunk/drivers/hid/hid-ids.h @@ -348,9 +348,6 @@ #define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 #define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 -#define USB_VENDOR_ID_POWERCOM 0x0d9f -#define USB_DEVICE_ID_POWERCOM_UPS 0x0002 - #define USB_VENDOR_ID_SAITEK 0x06a3 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 diff --git a/trunk/drivers/hid/hidraw.c b/trunk/drivers/hid/hidraw.c index 02b19db5442e..732449628971 100644 --- a/trunk/drivers/hid/hidraw.c +++ b/trunk/drivers/hid/hidraw.c @@ -267,10 +267,8 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, default: { struct hid_device *hid = dev->hid; - if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) { - ret = -EINVAL; - break; - } + if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) + return -EINVAL; if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) { int len; @@ -279,9 +277,8 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, len = strlen(hid->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - ret = copy_to_user(user_arg, hid->name, len) ? + return copy_to_user(user_arg, hid->name, len) ? -EFAULT : len; - break; } if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) { @@ -291,13 +288,12 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, len = strlen(hid->phys) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - ret = copy_to_user(user_arg, hid->phys, len) ? + return copy_to_user(user_arg, hid->phys, len) ? -EFAULT : len; - break; } } - ret = -ENOTTY; + ret = -ENOTTY; } unlock_kernel(); return ret; diff --git a/trunk/drivers/hwmon/f71882fg.c b/trunk/drivers/hwmon/f71882fg.c index 5f81ddf71508..609cafff86bc 100644 --- a/trunk/drivers/hwmon/f71882fg.c +++ b/trunk/drivers/hwmon/f71882fg.c @@ -1872,7 +1872,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, devid = superio_inw(sioaddr, SIO_REG_MANID); if (devid != SIO_FINTEK_ID) { - pr_debug(DRVNAME ": Not a Fintek device\n"); + printk(KERN_INFO DRVNAME ": Not a Fintek device\n"); goto exit; } @@ -1932,7 +1932,7 @@ static int __init f71882fg_device_add(unsigned short address, res.name = f71882fg_pdev->name; err = acpi_check_resource_conflict(&res); if (err) - goto exit_device_put; + return err; err = platform_device_add_resources(f71882fg_pdev, &res, 1); if (err) { diff --git a/trunk/drivers/hwmon/hp_accel.c b/trunk/drivers/hwmon/hp_accel.c index 29c83b5b9697..03705240000f 100644 --- a/trunk/drivers/hwmon/hp_accel.c +++ b/trunk/drivers/hwmon/hp_accel.c @@ -153,10 +153,7 @@ static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3}; static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3}; static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3}; static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3}; -static struct axis_conversion lis3lv02d_axis_xy_rotated_left_usd = {-2, 1, -3}; static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3}; -static struct axis_conversion lis3lv02d_axis_xy_rotated_right = {2, -1, 3}; -static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3}; #define AXIS_DMI_MATCH(_ident, _name, _axis) { \ .ident = _ident, \ @@ -166,18 +163,6 @@ static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3}; }, \ .driver_data = &lis3lv02d_axis_##_axis \ } - -#define AXIS_DMI_MATCH2(_ident, _class1, _name1, \ - _class2, _name2, \ - _axis) { \ - .ident = _ident, \ - .callback = lis3lv02d_dmi_matched, \ - .matches = { \ - DMI_MATCH(DMI_##_class1, _name1), \ - DMI_MATCH(DMI_##_class2, _name2), \ - }, \ - .driver_data = &lis3lv02d_axis_##_axis \ -} static struct dmi_system_id lis3lv02d_dmi_ids[] = { /* product names are truncated to match all kinds of a same model */ AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted), @@ -187,22 +172,10 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted), AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted), AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left), - AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd), - AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd), - AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right), - AXIS_DMI_MATCH("NC671xx", "HP Compaq 671", xy_swap_yz_inverted), - /* Intel-based HP Pavilion dv5 */ - AXIS_DMI_MATCH2("HPDV5_I", - PRODUCT_NAME, "HP Pavilion dv5", - BOARD_NAME, "3603", - x_inverted), - /* AMD-based HP Pavilion dv5 */ - AXIS_DMI_MATCH2("HPDV5_A", - PRODUCT_NAME, "HP Pavilion dv5", - BOARD_NAME, "3600", - y_inverted), { NULL, } /* Laptop models without axis info (yet): + * "NC651xx" "HP Compaq 651" + * "NC671xx" "HP Compaq 671" * "NC6910" "HP Compaq 6910" * HP Compaq 8710x Notebook PC / Mobile Workstation * "NC2400" "HP Compaq nc2400" @@ -235,49 +208,9 @@ static struct delayed_led_classdev hpled_led = { .set_brightness = hpled_set, }; -static acpi_status -lis3lv02d_get_resource(struct acpi_resource *resource, void *context) -{ - if (resource->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { - struct acpi_resource_extended_irq *irq; - u32 *device_irq = context; - - irq = &resource->data.extended_irq; - *device_irq = irq->interrupts[0]; - } - - return AE_OK; -} - -static void lis3lv02d_enum_resources(struct acpi_device *device) -{ - acpi_status status; - - status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, - lis3lv02d_get_resource, &adev.irq); - if (ACPI_FAILURE(status)) - printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); -} - -static s16 lis3lv02d_read_16(acpi_handle handle, int reg) -{ - u8 lo, hi; - - adev.read(handle, reg - 1, &lo); - adev.read(handle, reg, &hi); - /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ - return (s16)((hi << 8) | lo); -} - -static s16 lis3lv02d_read_8(acpi_handle handle, int reg) -{ - s8 lo; - adev.read(handle, reg, &lo); - return lo; -} - static int lis3lv02d_add(struct acpi_device *device) { + u8 val; int ret; if (!device) @@ -291,22 +224,10 @@ static int lis3lv02d_add(struct acpi_device *device) strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); device->driver_data = &adev; - lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami); - switch (adev.whoami) { - case LIS_DOUBLE_ID: - printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n"); - adev.read_data = lis3lv02d_read_16; - adev.mdps_max_val = 2048; - break; - case LIS_SINGLE_ID: - printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n"); - adev.read_data = lis3lv02d_read_8; - adev.mdps_max_val = 128; - break; - default: + lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val); + if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) { printk(KERN_ERR DRIVER_NAME - ": unknown sensor type 0x%X\n", adev.whoami); - return -EINVAL; + ": Accelerometer chip not LIS3LV02D{L,Q}\n"); } /* If possible use a "standard" axes order */ @@ -321,9 +242,6 @@ static int lis3lv02d_add(struct acpi_device *device) if (ret) return ret; - /* obtain IRQ number of our device from ACPI */ - lis3lv02d_enum_resources(adev.device); - ret = lis3lv02d_init_device(&adev); if (ret) { flush_work(&hpled_led.work); diff --git a/trunk/drivers/hwmon/lis3lv02d.c b/trunk/drivers/hwmon/lis3lv02d.c index 8bb2158f0453..219d2d0d5a62 100644 --- a/trunk/drivers/hwmon/lis3lv02d.c +++ b/trunk/drivers/hwmon/lis3lv02d.c @@ -3,7 +3,7 @@ * * Copyright (C) 2007-2008 Yan Burman * Copyright (C) 2008 Eric Piel - * Copyright (C) 2008-2009 Pavel Machek + * Copyright (C) 2008 Pavel Machek * * 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 @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include "lis3lv02d.h" @@ -53,14 +52,24 @@ * joystick. */ -struct acpi_lis3lv02d adev = { - .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait), -}; +/* Maximum value our axis may get for the input device (signed 12 bits) */ +#define MDPS_MAX_VAL 2048 +struct acpi_lis3lv02d adev; EXPORT_SYMBOL_GPL(adev); static int lis3lv02d_add_fs(struct acpi_device *device); +static s16 lis3lv02d_read_16(acpi_handle handle, int reg) +{ + u8 lo, hi; + + adev.read(handle, reg, &lo); + adev.read(handle, reg + 1, &hi); + /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ + return (s16)((hi << 8) | lo); +} + /** * lis3lv02d_get_axis - For the given axis, give the value converted * @axis: 1,2,3 - can also be negative @@ -89,9 +98,9 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z) { int position[3]; - position[0] = adev.read_data(handle, OUTX); - position[1] = adev.read_data(handle, OUTY); - position[2] = adev.read_data(handle, OUTZ); + position[0] = lis3lv02d_read_16(handle, OUTX_L); + position[1] = lis3lv02d_read_16(handle, OUTY_L); + position[2] = lis3lv02d_read_16(handle, OUTZ_L); *x = lis3lv02d_get_axis(adev.ac.x, position); *y = lis3lv02d_get_axis(adev.ac.y, position); @@ -101,13 +110,26 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z) void lis3lv02d_poweroff(acpi_handle handle) { adev.is_on = 0; + /* disable X,Y,Z axis and power down */ + adev.write(handle, CTRL_REG1, 0x00); } EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); void lis3lv02d_poweron(acpi_handle handle) { + u8 val; + adev.is_on = 1; adev.init(handle); + adev.write(handle, FF_WU_CFG, 0); + /* + * BDU: LSB and MSB values are not updated until both have been read. + * So the value read will always be correct. + * IEN: Interrupt for free-fall and DD, not for data-ready. + */ + adev.read(handle, CTRL_REG2, &val); + val |= CTRL2_BDU | CTRL2_IEN; + adev.write(handle, CTRL_REG2, val); } EXPORT_SYMBOL_GPL(lis3lv02d_poweron); @@ -140,140 +162,6 @@ static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev) mutex_unlock(&dev->lock); } -static irqreturn_t lis302dl_interrupt(int irq, void *dummy) -{ - /* - * Be careful: on some HP laptops the bios force DD when on battery and - * the lid is closed. This leads to interrupts as soon as a little move - * is done. - */ - atomic_inc(&adev.count); - - wake_up_interruptible(&adev.misc_wait); - kill_fasync(&adev.async_queue, SIGIO, POLL_IN); - return IRQ_HANDLED; -} - -static int lis3lv02d_misc_open(struct inode *inode, struct file *file) -{ - int ret; - - if (test_and_set_bit(0, &adev.misc_opened)) - return -EBUSY; /* already open */ - - atomic_set(&adev.count, 0); - - /* - * The sensor can generate interrupts for free-fall and direction - * detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep - * the things simple and _fast_ we activate it only for free-fall, so - * no need to read register (very slow with ACPI). For the same reason, - * we forbid shared interrupts. - * - * IRQF_TRIGGER_RISING seems pointless on HP laptops because the - * io-apic is not configurable (and generates a warning) but I keep it - * in case of support for other hardware. - */ - ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING, - DRIVER_NAME, &adev); - - if (ret) { - clear_bit(0, &adev.misc_opened); - printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq); - return -EBUSY; - } - lis3lv02d_increase_use(&adev); - printk("lis3: registered interrupt %d\n", adev.irq); - return 0; -} - -static int lis3lv02d_misc_release(struct inode *inode, struct file *file) -{ - fasync_helper(-1, file, 0, &adev.async_queue); - lis3lv02d_decrease_use(&adev); - free_irq(adev.irq, &adev); - clear_bit(0, &adev.misc_opened); /* release the device */ - return 0; -} - -static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - DECLARE_WAITQUEUE(wait, current); - u32 data; - unsigned char byte_data; - ssize_t retval = 1; - - if (count < 1) - return -EINVAL; - - add_wait_queue(&adev.misc_wait, &wait); - while (true) { - set_current_state(TASK_INTERRUPTIBLE); - data = atomic_xchg(&adev.count, 0); - if (data) - break; - - if (file->f_flags & O_NONBLOCK) { - retval = -EAGAIN; - goto out; - } - - if (signal_pending(current)) { - retval = -ERESTARTSYS; - goto out; - } - - schedule(); - } - - if (data < 255) - byte_data = data; - else - byte_data = 255; - - /* make sure we are not going into copy_to_user() with - * TASK_INTERRUPTIBLE state */ - set_current_state(TASK_RUNNING); - if (copy_to_user(buf, &byte_data, sizeof(byte_data))) - retval = -EFAULT; - -out: - __set_current_state(TASK_RUNNING); - remove_wait_queue(&adev.misc_wait, &wait); - - return retval; -} - -static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) -{ - poll_wait(file, &adev.misc_wait, wait); - if (atomic_read(&adev.count)) - return POLLIN | POLLRDNORM; - return 0; -} - -static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) -{ - return fasync_helper(fd, file, on, &adev.async_queue); -} - -static const struct file_operations lis3lv02d_misc_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = lis3lv02d_misc_read, - .open = lis3lv02d_misc_open, - .release = lis3lv02d_misc_release, - .poll = lis3lv02d_misc_poll, - .fasync = lis3lv02d_misc_fasync, -}; - -static struct miscdevice lis3lv02d_misc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "freefall", - .fops = &lis3lv02d_misc_fops, -}; - /** * lis3lv02d_joystick_kthread - Kthread polling function * @data: unused - here to conform to threadfn prototype @@ -315,6 +203,7 @@ static void lis3lv02d_joystick_close(struct input_dev *input) lis3lv02d_decrease_use(&adev); } + static inline void lis3lv02d_calibrate_joystick(void) { lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib); @@ -342,9 +231,9 @@ int lis3lv02d_joystick_enable(void) adev.idev->close = lis3lv02d_joystick_close; set_bit(EV_ABS, adev.idev->evbit); - input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); - input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); - input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); + input_set_abs_params(adev.idev, ABS_X, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); + input_set_abs_params(adev.idev, ABS_Y, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); + input_set_abs_params(adev.idev, ABS_Z, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); err = input_register_device(adev.idev); if (err) { @@ -361,7 +250,6 @@ void lis3lv02d_joystick_disable(void) if (!adev.idev) return; - misc_deregister(&lis3lv02d_misc_device); input_unregister_device(adev.idev); adev.idev = NULL; } @@ -380,19 +268,6 @@ int lis3lv02d_init_device(struct acpi_lis3lv02d *dev) if (lis3lv02d_joystick_enable()) printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); - printk("lis3_init_device: irq %d\n", dev->irq); - - /* if we did not get an IRQ from ACPI - we have nothing more to do */ - if (!dev->irq) { - printk(KERN_ERR DRIVER_NAME - ": No IRQ in ACPI. Disabling /dev/freefall\n"); - goto out; - } - - printk("lis3: registering device\n"); - if (misc_register(&lis3lv02d_misc_device)) - printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); -out: lis3lv02d_decrease_use(dev); return 0; } @@ -476,6 +351,6 @@ int lis3lv02d_remove_fs(void) EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver"); -MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); +MODULE_AUTHOR("Yan Burman and Eric Piel"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/lis3lv02d.h b/trunk/drivers/hwmon/lis3lv02d.h index 75972bf372ff..223f1c0763bb 100644 --- a/trunk/drivers/hwmon/lis3lv02d.h +++ b/trunk/drivers/hwmon/lis3lv02d.h @@ -22,15 +22,12 @@ /* * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to * be connected via SPI. There exists also several similar chips (such as LIS302DL or - * LIS3L02DQ) and they have slightly different registers, but we can provide a - * common interface for all of them. + * LIS3L02DQ) but not in the HP laptops and they have slightly different registers. * They can also be connected via I²C. */ -/* 2-byte registers */ -#define LIS_DOUBLE_ID 0x3A /* LIS3LV02D[LQ] */ -/* 1-byte registers */ -#define LIS_SINGLE_ID 0x3B /* LIS[32]02DL and others */ +#define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */ +#define LIS302DL_ID 0x3B /* Also the LIS202DL! */ enum lis3lv02d_reg { WHO_AM_I = 0x0F, @@ -47,13 +44,10 @@ enum lis3lv02d_reg { STATUS_REG = 0x27, OUTX_L = 0x28, OUTX_H = 0x29, - OUTX = 0x29, OUTY_L = 0x2A, OUTY_H = 0x2B, - OUTY = 0x2B, OUTZ_L = 0x2C, OUTZ_H = 0x2D, - OUTZ = 0x2D, FF_WU_CFG = 0x30, FF_WU_SRC = 0x31, FF_WU_ACK = 0x32, @@ -165,10 +159,6 @@ struct acpi_lis3lv02d { acpi_status (*write) (acpi_handle handle, int reg, u8 val); acpi_status (*read) (acpi_handle handle, int reg, u8 *ret); - u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */ - s16 (*read_data) (acpi_handle handle, int reg); - int mdps_max_val; - struct input_dev *idev; /* input device */ struct task_struct *kthread; /* kthread for input */ struct mutex lock; @@ -180,11 +170,6 @@ struct acpi_lis3lv02d { unsigned char is_on; /* whether the device is on or off */ unsigned char usage; /* usage counter */ struct axis_conversion ac; /* hw -> logical axis */ - - u32 irq; /* IRQ number */ - struct fasync_struct *async_queue; /* queue for the misc device */ - wait_queue_head_t misc_wait; /* Wait queue for the misc device */ - unsigned long misc_opened; /* bit0: whether the device is open */ }; int lis3lv02d_init_device(struct acpi_lis3lv02d *dev); diff --git a/trunk/drivers/hwmon/vt1211.c b/trunk/drivers/hwmon/vt1211.c index 73f77a9b8b18..b0ce37852281 100644 --- a/trunk/drivers/hwmon/vt1211.c +++ b/trunk/drivers/hwmon/vt1211.c @@ -1262,7 +1262,7 @@ static int __init vt1211_device_add(unsigned short address) res.name = pdev->name; err = acpi_check_resource_conflict(&res); if (err) - goto EXIT_DEV_PUT; + goto EXIT; err = platform_device_add_resources(pdev, &res, 1); if (err) { diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index feae743ba991..cb808d015361 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -1548,7 +1548,7 @@ static int __init sensors_w83627ehf_init(void) err = acpi_check_resource_conflict(&res); if (err) - goto exit_device_put; + goto exit; err = platform_device_add_resources(pdev, &res, 1); if (err) { diff --git a/trunk/drivers/i2c/busses/i2c-acorn.c b/trunk/drivers/i2c/busses/i2c-acorn.c index 9aefb5e5864d..9fee3ca17344 100644 --- a/trunk/drivers/i2c/busses/i2c-acorn.c +++ b/trunk/drivers/i2c/busses/i2c-acorn.c @@ -79,11 +79,10 @@ static struct i2c_algo_bit_data ioc_data = { .getsda = ioc_getsda, .getscl = ioc_getscl, .udelay = 80, - .timeout = HZ, + .timeout = 100 }; static struct i2c_adapter ioc_ops = { - .nr = 0, .algo_data = &ioc_data, }; @@ -91,7 +90,7 @@ static int __init i2c_ioc_init(void) { force_ones = FORCE_ONES | SCL | SDA; - return i2c_bit_add_numbered_bus(&ioc_ops); + return i2c_bit_add_bus(&ioc_ops); } module_init(i2c_ioc_init); diff --git a/trunk/drivers/i2c/busses/i2c-amd8111.c b/trunk/drivers/i2c/busses/i2c-amd8111.c index a7c59908c457..edab51973bf5 100644 --- a/trunk/drivers/i2c/busses/i2c-amd8111.c +++ b/trunk/drivers/i2c/busses/i2c-amd8111.c @@ -72,7 +72,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus) { int timeout = 500; - while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout) + while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF)) udelay(1); if (!timeout) { @@ -88,7 +88,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus) { int timeout = 500; - while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout) + while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF)) udelay(1); if (!timeout) { diff --git a/trunk/drivers/i2c/busses/i2c-ixp2000.c b/trunk/drivers/i2c/busses/i2c-ixp2000.c index c016f7a2c5fc..8e8467970481 100644 --- a/trunk/drivers/i2c/busses/i2c-ixp2000.c +++ b/trunk/drivers/i2c/busses/i2c-ixp2000.c @@ -114,7 +114,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev) drv_data->algo_data.getsda = ixp2000_bit_getsda; drv_data->algo_data.getscl = ixp2000_bit_getscl; drv_data->algo_data.udelay = 6; - drv_data->algo_data.timeout = HZ; + drv_data->algo_data.timeout = 100; strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, sizeof(drv_data->adapter.name)); diff --git a/trunk/drivers/i2c/busses/i2c-pxa.c b/trunk/drivers/i2c/busses/i2c-pxa.c index bdb1f7510e91..6af68146c342 100644 --- a/trunk/drivers/i2c/busses/i2c-pxa.c +++ b/trunk/drivers/i2c/busses/i2c-pxa.c @@ -644,7 +644,7 @@ static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c, i2c_pxa_start_message(i2c); - while (i2c->msg_num > 0 && --timeout) { + while (timeout-- && i2c->msg_num > 0) { i2c_pxa_handler(0, i2c); udelay(10); } diff --git a/trunk/drivers/i2c/busses/scx200_i2c.c b/trunk/drivers/i2c/busses/scx200_i2c.c index 42df0eca43d5..162b74a04886 100644 --- a/trunk/drivers/i2c/busses/scx200_i2c.c +++ b/trunk/drivers/i2c/busses/scx200_i2c.c @@ -76,7 +76,7 @@ static struct i2c_algo_bit_data scx200_i2c_data = { .getsda = scx200_i2c_getsda, .getscl = scx200_i2c_getscl, .udelay = 10, - .timeout = HZ, + .timeout = 100, }; static struct i2c_adapter scx200_i2c_ops = { diff --git a/trunk/drivers/i2c/i2c-core.c b/trunk/drivers/i2c/i2c-core.c index e7d984866de0..b1c9abe24c7b 100644 --- a/trunk/drivers/i2c/i2c-core.c +++ b/trunk/drivers/i2c/i2c-core.c @@ -1831,8 +1831,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, case I2C_SMBUS_QUICK: msg[0].len = 0; /* Special case: The read/write field is used as data */ - msg[0].flags = flags | (read_write == I2C_SMBUS_READ ? - I2C_M_RD : 0); + msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0; num = 1; break; case I2C_SMBUS_BYTE: diff --git a/trunk/drivers/i2c/i2c-dev.c b/trunk/drivers/i2c/i2c-dev.c index 7e13d2df9af3..c171988a9f51 100644 --- a/trunk/drivers/i2c/i2c-dev.c +++ b/trunk/drivers/i2c/i2c-dev.c @@ -35,7 +35,6 @@ #include #include #include -#include #include static struct i2c_driver i2cdev_driver; @@ -423,10 +422,7 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) client->adapter->retries = arg; break; case I2C_TIMEOUT: - /* For historical reasons, user-space sets the timeout - * value in units of 10 ms. - */ - client->adapter->timeout = msecs_to_jiffies(arg * 10); + client->adapter->timeout = arg; break; default: /* NOTE: returning a fault code here could cause trouble diff --git a/trunk/drivers/ide/Kconfig b/trunk/drivers/ide/Kconfig index e072903b12f0..3dad2299d9c5 100644 --- a/trunk/drivers/ide/Kconfig +++ b/trunk/drivers/ide/Kconfig @@ -46,7 +46,7 @@ menuconfig IDE SMART parameters from disk drives. To compile this driver as a module, choose M here: the - module will be called ide-core.ko. + module will be called ide. For further information, please read . diff --git a/trunk/drivers/ide/amd74xx.c b/trunk/drivers/ide/amd74xx.c index 77267c859965..69660a431cd9 100644 --- a/trunk/drivers/ide/amd74xx.c +++ b/trunk/drivers/ide/amd74xx.c @@ -166,7 +166,7 @@ static unsigned int init_chipset_amd74xx(struct pci_dev *dev) * Check for broken FIFO support. */ if (dev->vendor == PCI_VENDOR_ID_AMD && - dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) + dev->vendor == PCI_DEVICE_ID_AMD_VIPER_7411) t &= 0x0f; else t |= 0xf0; diff --git a/trunk/drivers/ide/atiixp.c b/trunk/drivers/ide/atiixp.c index ecd1e62ca91a..b2735d28f5cc 100644 --- a/trunk/drivers/ide/atiixp.c +++ b/trunk/drivers/ide/atiixp.c @@ -52,7 +52,7 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio) { struct pci_dev *dev = to_pci_dev(drive->hwif->dev); unsigned long flags; - int timing_shift = (drive->dn ^ 1) * 8; + int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; u32 pio_timing_data; u16 pio_mode_data; @@ -85,7 +85,7 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed) { struct pci_dev *dev = to_pci_dev(drive->hwif->dev); unsigned long flags; - int timing_shift = (drive->dn ^ 1) * 8; + int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; u32 tmp32; u16 tmp16; u16 udma_ctl = 0; diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index ddfbea41d296..0bfeb0c79d6e 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -55,7 +55,7 @@ static DEFINE_MUTEX(idecd_ref_mutex); -static void ide_cd_release(struct device *); +static void ide_cd_release(struct kref *); static struct cdrom_info *ide_cd_get(struct gendisk *disk) { @@ -67,7 +67,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk) if (ide_device_get(cd->drive)) cd = NULL; else - get_device(&cd->dev); + kref_get(&cd->kref); } mutex_unlock(&idecd_ref_mutex); @@ -79,7 +79,7 @@ static void ide_cd_put(struct cdrom_info *cd) ide_drive_t *drive = cd->drive; mutex_lock(&idecd_ref_mutex); - put_device(&cd->dev); + kref_put(&cd->kref, ide_cd_release); ide_device_put(drive); mutex_unlock(&idecd_ref_mutex); } @@ -194,14 +194,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, bio_sectors = max(bio_sectors(failed_command->bio), 4U); sector &= ~(bio_sectors - 1); - /* - * The SCSI specification allows for the value - * returned by READ CAPACITY to be up to 75 2K - * sectors past the last readable block. - * Therefore, if we hit a medium error within the - * last 75 2K sectors, we decrease the saved size - * value. - */ if (sector < get_capacity(info->disk) && drive->probed_capacity - sector < 4 * 75) set_capacity(info->disk, sector); @@ -1798,17 +1790,15 @@ static void ide_cd_remove(ide_drive_t *drive) ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); ide_proc_unregister_driver(drive, info->driver); - device_del(&info->dev); + del_gendisk(info->disk); - mutex_lock(&idecd_ref_mutex); - put_device(&info->dev); - mutex_unlock(&idecd_ref_mutex); + ide_cd_put(info); } -static void ide_cd_release(struct device *dev) +static void ide_cd_release(struct kref *kref) { - struct cdrom_info *info = to_ide_drv(dev, cdrom_info); + struct cdrom_info *info = to_ide_drv(kref, cdrom_info); struct cdrom_device_info *devinfo = &info->devinfo; ide_drive_t *drive = info->drive; struct gendisk *g = info->disk; @@ -2007,12 +1997,7 @@ static int ide_cd_probe(ide_drive_t *drive) ide_init_disk(g, drive); - info->dev.parent = &drive->gendev; - info->dev.release = ide_cd_release; - dev_set_name(&info->dev, dev_name(&drive->gendev)); - - if (device_register(&info->dev)) - goto out_free_disk; + kref_init(&info->kref); info->drive = drive; info->driver = &ide_cdrom_driver; @@ -2026,7 +2011,7 @@ static int ide_cd_probe(ide_drive_t *drive) g->driverfs_dev = &drive->gendev; g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; if (ide_cdrom_setup(drive)) { - put_device(&info->dev); + ide_cd_release(&info->kref); goto failed; } @@ -2036,8 +2021,6 @@ static int ide_cd_probe(ide_drive_t *drive) add_disk(g); return 0; -out_free_disk: - put_disk(g); out_free_cd: kfree(info); failed: diff --git a/trunk/drivers/ide/ide-cd.h b/trunk/drivers/ide/ide-cd.h index c878bfcf1116..ac40d6cb90a2 100644 --- a/trunk/drivers/ide/ide-cd.h +++ b/trunk/drivers/ide/ide-cd.h @@ -80,7 +80,7 @@ struct cdrom_info { ide_drive_t *drive; struct ide_driver *driver; struct gendisk *disk; - struct device dev; + struct kref kref; /* Buffer for table of contents. NULL if we haven't allocated a TOC buffer for this device yet. */ diff --git a/trunk/drivers/ide/ide-gd.c b/trunk/drivers/ide/ide-gd.c index 047109419902..7857b209c6df 100644 --- a/trunk/drivers/ide/ide-gd.c +++ b/trunk/drivers/ide/ide-gd.c @@ -25,7 +25,7 @@ module_param(debug_mask, ulong, 0644); static DEFINE_MUTEX(ide_disk_ref_mutex); -static void ide_disk_release(struct device *); +static void ide_disk_release(struct kref *); static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) { @@ -37,7 +37,7 @@ static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) if (ide_device_get(idkp->drive)) idkp = NULL; else - get_device(&idkp->dev); + kref_get(&idkp->kref); } mutex_unlock(&ide_disk_ref_mutex); return idkp; @@ -48,7 +48,7 @@ static void ide_disk_put(struct ide_disk_obj *idkp) ide_drive_t *drive = idkp->drive; mutex_lock(&ide_disk_ref_mutex); - put_device(&idkp->dev); + kref_put(&idkp->kref, ide_disk_release); ide_device_put(drive); mutex_unlock(&ide_disk_ref_mutex); } @@ -66,18 +66,17 @@ static void ide_gd_remove(ide_drive_t *drive) struct gendisk *g = idkp->disk; ide_proc_unregister_driver(drive, idkp->driver); - device_del(&idkp->dev); + del_gendisk(g); + drive->disk_ops->flush(drive); - mutex_lock(&ide_disk_ref_mutex); - put_device(&idkp->dev); - mutex_unlock(&ide_disk_ref_mutex); + ide_disk_put(idkp); } -static void ide_disk_release(struct device *dev) +static void ide_disk_release(struct kref *kref) { - struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj); + struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj); ide_drive_t *drive = idkp->drive; struct gendisk *g = idkp->disk; @@ -349,12 +348,7 @@ static int ide_gd_probe(ide_drive_t *drive) ide_init_disk(g, drive); - idkp->dev.parent = &drive->gendev; - idkp->dev.release = ide_disk_release; - dev_set_name(&idkp->dev, dev_name(&drive->gendev)); - - if (device_register(&idkp->dev)) - goto out_free_disk; + kref_init(&idkp->kref); idkp->drive = drive; idkp->driver = &ide_gd_driver; @@ -379,8 +373,6 @@ static int ide_gd_probe(ide_drive_t *drive) add_disk(g); return 0; -out_free_disk: - put_disk(g); out_free_idkp: kfree(idkp); failed: diff --git a/trunk/drivers/ide/ide-gd.h b/trunk/drivers/ide/ide-gd.h index b604bdd318a1..a86779f0756b 100644 --- a/trunk/drivers/ide/ide-gd.h +++ b/trunk/drivers/ide/ide-gd.h @@ -17,7 +17,7 @@ struct ide_disk_obj { ide_drive_t *drive; struct ide_driver *driver; struct gendisk *disk; - struct device dev; + struct kref kref; unsigned int openers; /* protected by BKL for now */ /* Last failed packet command */ diff --git a/trunk/drivers/ide/ide-tape.c b/trunk/drivers/ide/ide-tape.c index bb450a7608c2..d7ecd3c79757 100644 --- a/trunk/drivers/ide/ide-tape.c +++ b/trunk/drivers/ide/ide-tape.c @@ -169,7 +169,7 @@ typedef struct ide_tape_obj { ide_drive_t *drive; struct ide_driver *driver; struct gendisk *disk; - struct device dev; + struct kref kref; /* * failed_pc points to the last failed packet command, or contains @@ -267,7 +267,7 @@ static DEFINE_MUTEX(idetape_ref_mutex); static struct class *idetape_sysfs_class; -static void ide_tape_release(struct device *); +static void ide_tape_release(struct kref *); static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) { @@ -279,7 +279,7 @@ static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) if (ide_device_get(tape->drive)) tape = NULL; else - get_device(&tape->dev); + kref_get(&tape->kref); } mutex_unlock(&idetape_ref_mutex); return tape; @@ -290,7 +290,7 @@ static void ide_tape_put(struct ide_tape_obj *tape) ide_drive_t *drive = tape->drive; mutex_lock(&idetape_ref_mutex); - put_device(&tape->dev); + kref_put(&tape->kref, ide_tape_release); ide_device_put(drive); mutex_unlock(&idetape_ref_mutex); } @@ -308,7 +308,7 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) mutex_lock(&idetape_ref_mutex); tape = idetape_devs[i]; if (tape) - get_device(&tape->dev); + kref_get(&tape->kref); mutex_unlock(&idetape_ref_mutex); return tape; } @@ -2256,17 +2256,15 @@ static void ide_tape_remove(ide_drive_t *drive) idetape_tape_t *tape = drive->driver_data; ide_proc_unregister_driver(drive, tape->driver); - device_del(&tape->dev); + ide_unregister_region(tape->disk); - mutex_lock(&idetape_ref_mutex); - put_device(&tape->dev); - mutex_unlock(&idetape_ref_mutex); + ide_tape_put(tape); } -static void ide_tape_release(struct device *dev) +static void ide_tape_release(struct kref *kref) { - struct ide_tape_obj *tape = to_ide_drv(dev, ide_tape_obj); + struct ide_tape_obj *tape = to_ide_drv(kref, ide_tape_obj); ide_drive_t *drive = tape->drive; struct gendisk *g = tape->disk; @@ -2409,12 +2407,7 @@ static int ide_tape_probe(ide_drive_t *drive) ide_init_disk(g, drive); - tape->dev.parent = &drive->gendev; - tape->dev.release = ide_tape_release; - dev_set_name(&tape->dev, dev_name(&drive->gendev)); - - if (device_register(&tape->dev)) - goto out_free_disk; + kref_init(&tape->kref); tape->drive = drive; tape->driver = &idetape_driver; @@ -2443,8 +2436,6 @@ static int ide_tape_probe(ide_drive_t *drive) return 0; -out_free_disk: - put_disk(g); out_free_tape: kfree(tape); failed: diff --git a/trunk/drivers/ide/ide.c b/trunk/drivers/ide/ide.c index 0920e3b0c962..258805da15c3 100644 --- a/trunk/drivers/ide/ide.c +++ b/trunk/drivers/ide/ide.c @@ -337,7 +337,6 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp) int a, b, i, j = 1; unsigned int *dev_param_mask = (unsigned int *)kp->arg; - /* controller . device (0 or 1) [ : 1 (set) | 0 (clear) ] */ if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 && sscanf(s, "%d.%d", &a, &b) != 2) return -EINVAL; @@ -350,7 +349,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp) if (j) *dev_param_mask |= (1 << i); else - *dev_param_mask &= ~(1 << i); + *dev_param_mask &= (1 << i); return 0; } @@ -393,8 +392,6 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp) { int a, b, c = 0, h = 0, s = 0, i, j = 1; - /* controller . device (0 or 1) : Cylinders , Heads , Sectors */ - /* controller . device (0 or 1) : 1 (use CHS) | 0 (ignore CHS) */ if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 && sscanf(str, "%d.%d:%d", &a, &b, &j) != 3) return -EINVAL; @@ -410,7 +407,7 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp) if (j) ide_disks |= (1 << i); else - ide_disks &= ~(1 << i); + ide_disks &= (1 << i); ide_disks_chs[i].cyl = c; ide_disks_chs[i].head = h; @@ -472,8 +469,6 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp) { int i, j = 1; - /* controller (ignore) */ - /* controller : 1 (ignore) | 0 (use) */ if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1) return -EINVAL; @@ -483,7 +478,7 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp) if (j) ide_ignore_cable |= (1 << i); else - ide_ignore_cable &= ~(1 << i); + ide_ignore_cable &= (1 << i); return 0; } diff --git a/trunk/drivers/ide/it821x.c b/trunk/drivers/ide/it821x.c index 13b8153112ed..e1c4f5437396 100644 --- a/trunk/drivers/ide/it821x.c +++ b/trunk/drivers/ide/it821x.c @@ -5,8 +5,9 @@ * May be copied or modified under the terms of the GNU General Public License * Based in part on the ITE vendor provided SCSI driver. * - * Documentation: - * Datasheet is freely available, some other documents under NDA. + * Documentation available from + * http://www.ite.com.tw/pc/IT8212F_V04.pdf + * Some other documents are NDA. * * The ITE8212 isn't exactly a standard IDE controller. It has two * modes. In pass through mode then it is an IDE controller. In its smart diff --git a/trunk/drivers/ide/qd65xx.c b/trunk/drivers/ide/qd65xx.c index 08c4fa35e9b1..5b2e3af43c4b 100644 --- a/trunk/drivers/ide/qd65xx.c +++ b/trunk/drivers/ide/qd65xx.c @@ -16,7 +16,7 @@ /* * Rewritten from the work of Colten Edwards by - * Samuel Thibault + * Samuel Thibault */ #include diff --git a/trunk/drivers/ide/qd65xx.h b/trunk/drivers/ide/qd65xx.h index d7e67a1a1dcc..6636f9665d16 100644 --- a/trunk/drivers/ide/qd65xx.h +++ b/trunk/drivers/ide/qd65xx.h @@ -4,7 +4,7 @@ /* * Authors: Petr Soucek - * Samuel Thibault + * Samuel Thibault */ /* truncates a in [b,c] */ diff --git a/trunk/drivers/ieee1394/dma.h b/trunk/drivers/ieee1394/dma.h index 467373cab8e5..2727bcd24194 100644 --- a/trunk/drivers/ieee1394/dma.h +++ b/trunk/drivers/ieee1394/dma.h @@ -12,7 +12,6 @@ #include -struct file; struct pci_dev; struct scatterlist; struct vm_area_struct; diff --git a/trunk/drivers/ieee1394/dv1394.c b/trunk/drivers/ieee1394/dv1394.c index 3838bc4acaba..a329e6bd5d2d 100644 --- a/trunk/drivers/ieee1394/dv1394.c +++ b/trunk/drivers/ieee1394/dv1394.c @@ -1823,10 +1823,6 @@ static int dv1394_open(struct inode *inode, struct file *file) #endif - printk(KERN_INFO "%s: NOTE, the dv1394 interface is unsupported " - "and will not be available in the new firewire driver stack. " - "Try libraw1394 based programs instead.\n", current->comm); - return 0; } @@ -2571,6 +2567,10 @@ static int __init dv1394_init_module(void) { int ret; + printk(KERN_WARNING + "NOTE: The dv1394 driver is unsupported and may be removed in a " + "future Linux release. Use raw1394 instead.\n"); + cdev_init(&dv1394_cdev, &dv1394_fops); dv1394_cdev.owner = THIS_MODULE; ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16); diff --git a/trunk/drivers/ieee1394/ieee1394_core.c b/trunk/drivers/ieee1394/ieee1394_core.c index 872338003721..2beb8d94f7bd 100644 --- a/trunk/drivers/ieee1394/ieee1394_core.c +++ b/trunk/drivers/ieee1394/ieee1394_core.c @@ -1275,7 +1275,7 @@ static void __exit ieee1394_cleanup(void) unregister_chrdev_region(IEEE1394_CORE_DEV, 256); } -fs_initcall(ieee1394_init); +module_init(ieee1394_init); module_exit(ieee1394_cleanup); /* Exported symbols */ @@ -1314,7 +1314,6 @@ EXPORT_SYMBOL(hpsb_make_lock64packet); EXPORT_SYMBOL(hpsb_make_phypacket); EXPORT_SYMBOL(hpsb_read); EXPORT_SYMBOL(hpsb_write); -EXPORT_SYMBOL(hpsb_lock); EXPORT_SYMBOL(hpsb_packet_success); /** highlevel.c **/ diff --git a/trunk/drivers/ieee1394/ieee1394_transactions.c b/trunk/drivers/ieee1394/ieee1394_transactions.c index 675b3135d5f1..10c3d9f8c038 100644 --- a/trunk/drivers/ieee1394/ieee1394_transactions.c +++ b/trunk/drivers/ieee1394/ieee1394_transactions.c @@ -501,6 +501,8 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation, if (length == 0) return -EINVAL; + BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet + packet = hpsb_make_readpacket(host, node, addr, length); if (!packet) { @@ -548,6 +550,8 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, if (length == 0) return -EINVAL; + BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet + packet = hpsb_make_writepacket(host, node, addr, buffer, length); if (!packet) @@ -566,30 +570,3 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, return retval; } - -int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, - u64 addr, int extcode, quadlet_t *data, quadlet_t arg) -{ - struct hpsb_packet *packet; - int retval = 0; - - packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); - if (!packet) - return -ENOMEM; - - packet->generation = generation; - retval = hpsb_send_packet_and_wait(packet); - if (retval < 0) - goto hpsb_lock_fail; - - retval = hpsb_packet_success(packet); - - if (retval == 0) - *data = packet->data[0]; - -hpsb_lock_fail: - hpsb_free_tlabel(packet); - hpsb_free_packet(packet); - - return retval; -} diff --git a/trunk/drivers/ieee1394/ieee1394_transactions.h b/trunk/drivers/ieee1394/ieee1394_transactions.h index 20b693be14b2..d2d5bc3546d7 100644 --- a/trunk/drivers/ieee1394/ieee1394_transactions.h +++ b/trunk/drivers/ieee1394/ieee1394_transactions.h @@ -30,8 +30,6 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation, u64 addr, quadlet_t *buffer, size_t length); int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, u64 addr, quadlet_t *buffer, size_t length); -int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, - u64 addr, int extcode, quadlet_t *data, quadlet_t arg); #ifdef HPSB_DEBUG_TLABELS extern spinlock_t hpsb_tlabel_lock; diff --git a/trunk/drivers/ieee1394/iso.h b/trunk/drivers/ieee1394/iso.h index c2089c093aa7..b5de5f21ef78 100644 --- a/trunk/drivers/ieee1394/iso.h +++ b/trunk/drivers/ieee1394/iso.h @@ -13,7 +13,6 @@ #define IEEE1394_ISO_H #include -#include #include #include diff --git a/trunk/drivers/ieee1394/nodemgr.c b/trunk/drivers/ieee1394/nodemgr.c index 53aada5bbe1e..906c5a98d814 100644 --- a/trunk/drivers/ieee1394/nodemgr.c +++ b/trunk/drivers/ieee1394/nodemgr.c @@ -971,9 +971,6 @@ static struct unit_directory *nodemgr_process_unit_directory ud->ud_kv = ud_kv; ud->id = (*id)++; - /* inherit vendor_id from root directory if none exists in unit dir */ - ud->vendor_id = ne->vendor_id; - csr1212_for_each_dir_entry(ne->csr, kv, ud_kv, dentry) { switch (kv->key.id) { case CSR1212_KV_ID_VENDOR: @@ -1268,8 +1265,7 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, csr1212_destroy_csr(csr); } - /* Finally, mark the node current */ - smp_wmb(); + /* Mark the node current */ ne->generation = generation; if (ne->in_limbo) { @@ -1802,7 +1798,7 @@ void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet) { packet->host = ne->host; packet->generation = ne->generation; - smp_rmb(); + barrier(); packet->node_id = ne->nodeid; } @@ -1811,7 +1807,7 @@ int hpsb_node_write(struct node_entry *ne, u64 addr, { unsigned int generation = ne->generation; - smp_rmb(); + barrier(); return hpsb_write(ne->host, ne->nodeid, generation, addr, buffer, length); } diff --git a/trunk/drivers/ieee1394/nodemgr.h b/trunk/drivers/ieee1394/nodemgr.h index ee5acdbd114a..15ea09733e84 100644 --- a/trunk/drivers/ieee1394/nodemgr.h +++ b/trunk/drivers/ieee1394/nodemgr.h @@ -21,11 +21,9 @@ #define _IEEE1394_NODEMGR_H #include -#include #include #include "ieee1394_core.h" -#include "ieee1394_transactions.h" #include "ieee1394_types.h" struct csr1212_csr; @@ -156,22 +154,6 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne) void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet); int hpsb_node_write(struct node_entry *ne, u64 addr, quadlet_t *buffer, size_t length); -static inline int hpsb_node_read(struct node_entry *ne, u64 addr, - quadlet_t *buffer, size_t length) -{ - unsigned int g = ne->generation; - - smp_rmb(); - return hpsb_read(ne->host, ne->nodeid, g, addr, buffer, length); -} -static inline int hpsb_node_lock(struct node_entry *ne, u64 addr, int extcode, - quadlet_t *buffer, quadlet_t arg) -{ - unsigned int g = ne->generation; - - smp_rmb(); - return hpsb_lock(ne->host, ne->nodeid, g, addr, extcode, buffer, arg); -} int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)); int init_ieee1394_nodemgr(void); diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index 45470f18d7e9..c3c8b9bc40ae 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -839,7 +839,7 @@ static void atkbd_disconnect(struct serio *serio) */ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) { - static const unsigned int forced_release_keys[] = { + const unsigned int forced_release_keys[] = { 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, }; int i; @@ -856,7 +856,7 @@ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) */ static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) { - static const unsigned int forced_release_keys[] = { + const unsigned int forced_release_keys[] = { 0x94, }; int i; diff --git a/trunk/drivers/input/keyboard/bf54x-keys.c b/trunk/drivers/input/keyboard/bf54x-keys.c index ee855c5202e8..19284016e0f4 100644 --- a/trunk/drivers/input/keyboard/bf54x-keys.c +++ b/trunk/drivers/input/keyboard/bf54x-keys.c @@ -209,8 +209,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) goto out; } - if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT || - !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) { + if (!pdata->debounce_time || !pdata->debounce_time > MAX_MULT || + !pdata->coldrive_time || !pdata->coldrive_time > MAX_MULT) { printk(KERN_ERR DRV_NAME ": Invalid Debounce/Columdrive Time from pdata\n"); bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ diff --git a/trunk/drivers/input/keyboard/corgikbd.c b/trunk/drivers/input/keyboard/corgikbd.c index abb04c82c622..c8ed065ea0cb 100644 --- a/trunk/drivers/input/keyboard/corgikbd.c +++ b/trunk/drivers/input/keyboard/corgikbd.c @@ -288,7 +288,7 @@ static int corgikbd_resume(struct platform_device *dev) #define corgikbd_resume NULL #endif -static int __devinit corgikbd_probe(struct platform_device *pdev) +static int __init corgikbd_probe(struct platform_device *pdev) { struct corgikbd *corgikbd; struct input_dev *input_dev; @@ -368,7 +368,7 @@ static int __devinit corgikbd_probe(struct platform_device *pdev) return err; } -static int __devexit corgikbd_remove(struct platform_device *pdev) +static int corgikbd_remove(struct platform_device *pdev) { int i; struct corgikbd *corgikbd = platform_get_drvdata(pdev); @@ -388,7 +388,7 @@ static int __devexit corgikbd_remove(struct platform_device *pdev) static struct platform_driver corgikbd_driver = { .probe = corgikbd_probe, - .remove = __devexit_p(corgikbd_remove), + .remove = corgikbd_remove, .suspend = corgikbd_suspend, .resume = corgikbd_resume, .driver = { @@ -397,7 +397,7 @@ static struct platform_driver corgikbd_driver = { }, }; -static int __init corgikbd_init(void) +static int __devinit corgikbd_init(void) { return platform_driver_register(&corgikbd_driver); } diff --git a/trunk/drivers/input/keyboard/omap-keypad.c b/trunk/drivers/input/keyboard/omap-keypad.c index 058fa8b02c21..3f3d1198cdb1 100644 --- a/trunk/drivers/input/keyboard/omap-keypad.c +++ b/trunk/drivers/input/keyboard/omap-keypad.c @@ -279,7 +279,7 @@ static int omap_kp_resume(struct platform_device *dev) #define omap_kp_resume NULL #endif -static int __devinit omap_kp_probe(struct platform_device *pdev) +static int __init omap_kp_probe(struct platform_device *pdev) { struct omap_kp *omap_kp; struct input_dev *input_dev; @@ -422,7 +422,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) return -EINVAL; } -static int __devexit omap_kp_remove(struct platform_device *pdev) +static int omap_kp_remove(struct platform_device *pdev) { struct omap_kp *omap_kp = platform_get_drvdata(pdev); @@ -454,7 +454,7 @@ static int __devexit omap_kp_remove(struct platform_device *pdev) static struct platform_driver omap_kp_driver = { .probe = omap_kp_probe, - .remove = __devexit_p(omap_kp_remove), + .remove = omap_kp_remove, .suspend = omap_kp_suspend, .resume = omap_kp_resume, .driver = { @@ -463,7 +463,7 @@ static struct platform_driver omap_kp_driver = { }, }; -static int __init omap_kp_init(void) +static int __devinit omap_kp_init(void) { printk(KERN_INFO "OMAP Keypad Driver\n"); return platform_driver_register(&omap_kp_driver); diff --git a/trunk/drivers/input/keyboard/spitzkbd.c b/trunk/drivers/input/keyboard/spitzkbd.c index 9d1781a618e9..c48b76a46a58 100644 --- a/trunk/drivers/input/keyboard/spitzkbd.c +++ b/trunk/drivers/input/keyboard/spitzkbd.c @@ -343,7 +343,7 @@ static int spitzkbd_resume(struct platform_device *dev) #define spitzkbd_resume NULL #endif -static int __devinit spitzkbd_probe(struct platform_device *dev) +static int __init spitzkbd_probe(struct platform_device *dev) { struct spitzkbd *spitzkbd; struct input_dev *input_dev; @@ -444,7 +444,7 @@ static int __devinit spitzkbd_probe(struct platform_device *dev) return err; } -static int __devexit spitzkbd_remove(struct platform_device *dev) +static int spitzkbd_remove(struct platform_device *dev) { int i; struct spitzkbd *spitzkbd = platform_get_drvdata(dev); @@ -470,7 +470,7 @@ static int __devexit spitzkbd_remove(struct platform_device *dev) static struct platform_driver spitzkbd_driver = { .probe = spitzkbd_probe, - .remove = __devexit_p(spitzkbd_remove), + .remove = spitzkbd_remove, .suspend = spitzkbd_suspend, .resume = spitzkbd_resume, .driver = { @@ -479,7 +479,7 @@ static struct platform_driver spitzkbd_driver = { }, }; -static int __init spitzkbd_init(void) +static int __devinit spitzkbd_init(void) { return platform_driver_register(&spitzkbd_driver); } diff --git a/trunk/drivers/input/mouse/Kconfig b/trunk/drivers/input/mouse/Kconfig index 9705f3a00a3d..093c8c1bca74 100644 --- a/trunk/drivers/input/mouse/Kconfig +++ b/trunk/drivers/input/mouse/Kconfig @@ -70,7 +70,7 @@ config MOUSE_PS2_SYNAPTICS config MOUSE_PS2_LIFEBOOK bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED default y - depends on MOUSE_PS2 && X86 + depends on MOUSE_PS2 help Say Y here if you have a Fujitsu B-series Lifebook PS/2 TouchScreen connected to your system. diff --git a/trunk/drivers/input/mouse/elantech.c b/trunk/drivers/input/mouse/elantech.c index 6ab0eb1ada1c..b9a25d57bc5e 100644 --- a/trunk/drivers/input/mouse/elantech.c +++ b/trunk/drivers/input/mouse/elantech.c @@ -542,7 +542,7 @@ int elantech_detect(struct psmouse *psmouse, int set_properties) ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { - pr_debug("elantech.c: sending Elantech magic knock failed.\n"); + pr_err("elantech.c: sending Elantech magic knock failed.\n"); return -1; } @@ -551,27 +551,8 @@ int elantech_detect(struct psmouse *psmouse, int set_properties) * set of magic numbers */ if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { - pr_debug("elantech.c: " - "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", - param[0], param[1], param[2]); - return -1; - } - - /* - * Query touchpad's firmware version and see if it reports known - * value to avoid mis-detection. Logitech mice are known to respond - * to Elantech magic knock and there might be more. - */ - if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { - pr_debug("elantech.c: failed to query firmware version.\n"); - return -1; - } - - pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", - param[0], param[1], param[2]); - - if (param[0] == 0 || param[1] != 0) { - pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); + pr_info("elantech.c: unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", + param[0], param[1], param[2]); return -1; } @@ -619,7 +600,8 @@ int elantech_init(struct psmouse *psmouse) int i, error; unsigned char param[3]; - psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); + etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); + psmouse->private = etd; if (!etd) return -1; @@ -628,12 +610,14 @@ int elantech_init(struct psmouse *psmouse) etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; /* - * Do the version query again so we can store the result + * Find out what version hardware this is */ if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { pr_err("elantech.c: failed to query firmware version.\n"); goto init_fail; } + pr_info("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", + param[0], param[1], param[2]); etd->fw_version_maj = param[0]; etd->fw_version_min = param[2]; diff --git a/trunk/drivers/input/mouse/pxa930_trkball.c b/trunk/drivers/input/mouse/pxa930_trkball.c index 1e827ad0afbe..d297accf9a7f 100644 --- a/trunk/drivers/input/mouse/pxa930_trkball.c +++ b/trunk/drivers/input/mouse/pxa930_trkball.c @@ -83,7 +83,7 @@ static int write_tbcr(struct pxa930_trkball *trkball, int v) __raw_writel(v, trkball->mmio_base + TBCR); - while (--i) { + while (i--) { if (__raw_readl(trkball->mmio_base + TBCR) == v) break; msleep(1); diff --git a/trunk/drivers/input/mouse/synaptics.c b/trunk/drivers/input/mouse/synaptics.c index f3e4f7b0240d..865fc69e9bc3 100644 --- a/trunk/drivers/input/mouse/synaptics.c +++ b/trunk/drivers/input/mouse/synaptics.c @@ -182,6 +182,11 @@ static int synaptics_identify(struct psmouse *psmouse) static int synaptics_query_hardware(struct psmouse *psmouse) { + int retries = 0; + + while ((retries++ < 3) && psmouse_reset(psmouse)) + /* empty */; + if (synaptics_identify(psmouse)) return -1; if (synaptics_model_id(psmouse)) @@ -577,8 +582,6 @@ static int synaptics_reconnect(struct psmouse *psmouse) struct synaptics_data *priv = psmouse->private; struct synaptics_data old_priv = *priv; - psmouse_reset(psmouse); - if (synaptics_detect(psmouse, 0)) return -1; @@ -637,8 +640,6 @@ int synaptics_init(struct psmouse *psmouse) if (!priv) return -1; - psmouse_reset(psmouse); - if (synaptics_query_hardware(psmouse)) { printk(KERN_ERR "Unable to query Synaptics hardware.\n"); goto init_fail; diff --git a/trunk/drivers/input/serio/ambakmi.c b/trunk/drivers/input/serio/ambakmi.c index e29cdc13a199..b10ffae7c39b 100644 --- a/trunk/drivers/input/serio/ambakmi.c +++ b/trunk/drivers/input/serio/ambakmi.c @@ -57,7 +57,7 @@ static int amba_kmi_write(struct serio *io, unsigned char val) struct amba_kmi_port *kmi = io->port_data; unsigned int timeleft = 10000; /* timeout in 100ms */ - while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && --timeleft) + while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--) udelay(10); if (timeleft) @@ -129,8 +129,8 @@ static int amba_kmi_probe(struct amba_device *dev, void *id) io->write = amba_kmi_write; io->open = amba_kmi_open; io->close = amba_kmi_close; - strlcpy(io->name, dev_name(&dev->dev), sizeof(io->name)); - strlcpy(io->phys, dev_name(&dev->dev), sizeof(io->phys)); + strlcpy(io->name, dev->dev.bus_id, sizeof(io->name)); + strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys)); io->port_data = kmi; io->dev.parent = &dev->dev; diff --git a/trunk/drivers/input/serio/gscps2.c b/trunk/drivers/input/serio/gscps2.c index bd0f92d9f40f..adc3bd6e7f7b 100644 --- a/trunk/drivers/input/serio/gscps2.c +++ b/trunk/drivers/input/serio/gscps2.c @@ -359,7 +359,7 @@ static int __init gscps2_probe(struct parisc_device *dev) snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s", (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse"); - strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); + strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); serio->id.type = SERIO_8042; serio->write = gscps2_write; serio->open = gscps2_open; diff --git a/trunk/drivers/input/serio/sa1111ps2.c b/trunk/drivers/input/serio/sa1111ps2.c index 57953c0eb82f..2ad88780a170 100644 --- a/trunk/drivers/input/serio/sa1111ps2.c +++ b/trunk/drivers/input/serio/sa1111ps2.c @@ -246,8 +246,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev) serio->write = ps2_write; serio->open = ps2_open; serio->close = ps2_close; - strlcpy(serio->name, dev_name(&dev->dev), sizeof(serio->name)); - strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); + strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name)); + strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); serio->port_data = ps2if; serio->dev.parent = &dev->dev; ps2if->io = serio; diff --git a/trunk/drivers/input/touchscreen/atmel_tsadcc.c b/trunk/drivers/input/touchscreen/atmel_tsadcc.c index 055969e8be13..a89a6a8f05e6 100644 --- a/trunk/drivers/input/touchscreen/atmel_tsadcc.c +++ b/trunk/drivers/input/touchscreen/atmel_tsadcc.c @@ -236,7 +236,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev) ts_dev->bufferedmeasure = 0; snprintf(ts_dev->phys, sizeof(ts_dev->phys), - "%s/input0", dev_name(&pdev->dev)); + "%s/input0", pdev->dev.bus_id); input_dev->name = "atmel touch screen controller"; input_dev->phys = ts_dev->phys; diff --git a/trunk/drivers/input/touchscreen/corgi_ts.c b/trunk/drivers/input/touchscreen/corgi_ts.c index 3fb51b54fe61..65202c9f63ff 100644 --- a/trunk/drivers/input/touchscreen/corgi_ts.c +++ b/trunk/drivers/input/touchscreen/corgi_ts.c @@ -268,7 +268,7 @@ static int corgits_resume(struct platform_device *dev) #define corgits_resume NULL #endif -static int __devinit corgits_probe(struct platform_device *pdev) +static int __init corgits_probe(struct platform_device *pdev) { struct corgi_ts *corgi_ts; struct input_dev *input_dev; @@ -343,7 +343,7 @@ static int __devinit corgits_probe(struct platform_device *pdev) return err; } -static int __devexit corgits_remove(struct platform_device *pdev) +static int corgits_remove(struct platform_device *pdev) { struct corgi_ts *corgi_ts = platform_get_drvdata(pdev); @@ -352,13 +352,12 @@ static int __devexit corgits_remove(struct platform_device *pdev) corgi_ts->machinfo->put_hsync(); input_unregister_device(corgi_ts->input); kfree(corgi_ts); - return 0; } static struct platform_driver corgits_driver = { .probe = corgits_probe, - .remove = __devexit_p(corgits_remove), + .remove = corgits_remove, .suspend = corgits_suspend, .resume = corgits_resume, .driver = { @@ -367,7 +366,7 @@ static struct platform_driver corgits_driver = { }, }; -static int __init corgits_init(void) +static int __devinit corgits_init(void) { return platform_driver_register(&corgits_driver); } diff --git a/trunk/drivers/input/touchscreen/tsc2007.c b/trunk/drivers/input/touchscreen/tsc2007.c index 4ab070246892..b75dc2990574 100644 --- a/trunk/drivers/input/touchscreen/tsc2007.c +++ b/trunk/drivers/input/touchscreen/tsc2007.c @@ -289,8 +289,7 @@ static int tsc2007_probe(struct i2c_client *client, pdata->init_platform_hw(); - snprintf(ts->phys, sizeof(ts->phys), - "%s/input0", dev_name(&client->dev)); + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", client->dev.bus_id); input_dev->name = "TSC2007 Touchscreen"; input_dev->phys = ts->phys; diff --git a/trunk/drivers/input/touchscreen/usbtouchscreen.c b/trunk/drivers/input/touchscreen/usbtouchscreen.c index fb7cb9bdfbd5..5080b26ba160 100644 --- a/trunk/drivers/input/touchscreen/usbtouchscreen.c +++ b/trunk/drivers/input/touchscreen/usbtouchscreen.c @@ -60,10 +60,6 @@ static int swap_xy; module_param(swap_xy, bool, 0644); MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); -static int hwcalib_xy; -module_param(hwcalib_xy, bool, 0644); -MODULE_PARM_DESC(hwcalib_xy, "If set hw-calibrated X/Y are used if available"); - /* device specifc data/functions */ struct usbtouch_usb; struct usbtouch_device_info { @@ -122,7 +118,6 @@ enum { #define USB_DEVICE_HID_CLASS(vend, prod) \ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \ - | USB_DEVICE_ID_MATCH_INT_PROTOCOL \ | USB_DEVICE_ID_MATCH_DEVICE, \ .idVendor = (vend), \ .idProduct = (prod), \ @@ -265,13 +260,8 @@ static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt) static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) { - if (hwcalib_xy) { - dev->x = (pkt[4] << 8) | pkt[3]; - dev->y = 0xffff - ((pkt[6] << 8) | pkt[5]); - } else { - dev->x = (pkt[8] << 8) | pkt[7]; - dev->y = (pkt[10] << 8) | pkt[9]; - } + dev->x = (pkt[8] << 8) | pkt[7]; + dev->y = (pkt[10] << 8) | pkt[9]; dev->touch = (pkt[2] & 0x40) ? 1 : 0; return 1; @@ -304,12 +294,6 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) return ret; } - /* Default min/max xy are the raw values, override if using hw-calib */ - if (hwcalib_xy) { - input_set_abs_params(usbtouch->input, ABS_X, 0, 0xffff, 0, 0); - input_set_abs_params(usbtouch->input, ABS_Y, 0, 0xffff, 0, 0); - } - return 0; } #endif diff --git a/trunk/drivers/md/dm-io.c b/trunk/drivers/md/dm-io.c index f14813be4eff..a34338567a2a 100644 --- a/trunk/drivers/md/dm-io.c +++ b/trunk/drivers/md/dm-io.c @@ -328,7 +328,7 @@ static void dispatch_io(int rw, unsigned int num_regions, struct dpages old_pages = *dp; if (sync) - rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); + rw |= (1 << BIO_RW_SYNC); /* * For multiple regions we need to be careful to rewind diff --git a/trunk/drivers/md/dm-kcopyd.c b/trunk/drivers/md/dm-kcopyd.c index 0a225da21272..3073618269ea 100644 --- a/trunk/drivers/md/dm-kcopyd.c +++ b/trunk/drivers/md/dm-kcopyd.c @@ -344,7 +344,7 @@ static int run_io_job(struct kcopyd_job *job) { int r; struct dm_io_request io_req = { - .bi_rw = job->rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG), + .bi_rw = job->rw | (1 << BIO_RW_SYNC), .mem.type = DM_IO_PAGE_LIST, .mem.ptr.pl = job->pages, .mem.offset = job->offset, diff --git a/trunk/drivers/md/linear.c b/trunk/drivers/md/linear.c index 09658b218474..1e3aea9eecf1 100644 --- a/trunk/drivers/md/linear.c +++ b/trunk/drivers/md/linear.c @@ -25,13 +25,13 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) { dev_info_t *hash; linear_conf_t *conf = mddev_to_conf(mddev); - sector_t idx = sector >> conf->sector_shift; /* * sector_div(a,b) returns the remainer and sets a to a/b */ - (void)sector_div(idx, conf->spacing); - hash = conf->hash_table[idx]; + sector >>= conf->sector_shift; + (void)sector_div(sector, conf->spacing); + hash = conf->hash_table[sector]; while (sector >= hash->num_sectors + hash->start_sector) hash++; diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 03b4cd0a6344..41e2509bf896 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -474,7 +474,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, * causes ENOTSUPP, we allocate a spare bio... */ struct bio *bio = bio_alloc(GFP_NOIO, 1); - int rw = (1<bi_bdev = rdev->bdev; bio->bi_sector = sector; @@ -531,7 +531,7 @@ int sync_page_io(struct block_device *bdev, sector_t sector, int size, struct completion event; int ret; - rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); + rw |= (1 << BIO_RW_SYNC); bio->bi_bdev = bdev; bio->bi_sector = sector; @@ -1481,11 +1481,6 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) if (find_rdev_nr(mddev, rdev->desc_nr)) return -EBUSY; } - if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) { - printk(KERN_WARNING "md: %s: array is limited to %d devices\n", - mdname(mddev), mddev->max_disks); - return -EBUSY; - } bdevname(rdev->bdev,b); while ( (s=strchr(b, '/')) != NULL) *s = '!'; @@ -2446,15 +2441,6 @@ static void analyze_sbs(mddev_t * mddev) i = 0; rdev_for_each(rdev, tmp, mddev) { - if (rdev->desc_nr >= mddev->max_disks || - i > mddev->max_disks) { - printk(KERN_WARNING - "md: %s: %s: only %d devices permitted\n", - mdname(mddev), bdevname(rdev->bdev, b), - mddev->max_disks); - kick_rdev_from_array(rdev); - continue; - } if (rdev != freshest) if (super_types[mddev->major_version]. validate_super(mddev, rdev)) { @@ -4628,6 +4614,13 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) * noticed in interrupt contexts ... */ + if (rdev->desc_nr == mddev->max_disks) { + printk(KERN_WARNING "%s: can not hot-add to full array!\n", + mdname(mddev)); + err = -EBUSY; + goto abort_unbind_export; + } + rdev->raid_disk = -1; md_update_sb(mddev, 1); @@ -4641,6 +4634,9 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) md_new_event(mddev); return 0; +abort_unbind_export: + unbind_rdev_from_array(rdev); + abort_export: export_rdev(rdev); return err; diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index e2466425d9ca..7b4f5f7155d8 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -1237,9 +1237,8 @@ static void end_sync_write(struct bio *bio, int error) update_head_pos(mirror, r1_bio); if (atomic_dec_and_test(&r1_bio->remaining)) { - sector_t s = r1_bio->sectors; + md_done_sync(mddev, r1_bio->sectors, uptodate); put_buf(r1_bio); - md_done_sync(mddev, s, uptodate); } } @@ -1641,8 +1640,7 @@ static void raid1d(mddev_t *mddev) } bio = r1_bio->bios[r1_bio->read_disk]; - if ((disk=read_balance(conf, r1_bio)) == -1 || - disk == r1_bio->read_disk) { + if ((disk=read_balance(conf, r1_bio)) == -1) { printk(KERN_ALERT "raid1: %s: unrecoverable I/O" " read error for block %llu\n", bdevname(bio->bi_bdev,b), diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 7301631abe04..6736d6dff981 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -1236,7 +1236,6 @@ static void end_sync_read(struct bio *bio, int error) /* for reconstruct, we always reschedule after a read. * for resync, only after all reads */ - rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); if (test_bit(R10BIO_IsRecover, &r10_bio->state) || atomic_dec_and_test(&r10_bio->remaining)) { /* we have read all the blocks, @@ -1244,6 +1243,7 @@ static void end_sync_read(struct bio *bio, int error) */ reschedule_retry(r10_bio); } + rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); } static void end_sync_write(struct bio *bio, int error) @@ -1264,13 +1264,11 @@ static void end_sync_write(struct bio *bio, int error) update_head_pos(i, r10_bio); - rdev_dec_pending(conf->mirrors[d].rdev, mddev); while (atomic_dec_and_test(&r10_bio->remaining)) { if (r10_bio->master_bio == NULL) { /* the primary of several recovery bios */ - sector_t s = r10_bio->sectors; + md_done_sync(mddev, r10_bio->sectors, 1); put_buf(r10_bio); - md_done_sync(mddev, s, 1); break; } else { r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio; @@ -1278,6 +1276,7 @@ static void end_sync_write(struct bio *bio, int error) r10_bio = r10_bio2; } } + rdev_dec_pending(conf->mirrors[d].rdev, mddev); } /* @@ -1750,6 +1749,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i if (!go_faster && conf->nr_waiting) msleep_interruptible(1000); + bitmap_cond_end_sync(mddev->bitmap, sector_nr); + /* Again, very different code for resync and recovery. * Both must result in an r10bio with a list of bios that * have bi_end_io, bi_sector, bi_bdev set, @@ -1885,8 +1886,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i /* resync. Schedule a read for every block at this virt offset */ int count = 0; - bitmap_cond_end_sync(mddev->bitmap, sector_nr); - if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) && !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { @@ -2011,13 +2010,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i /* There is nowhere to write, so all non-sync * drives must be failed, so try the next chunk... */ - if (sector_nr + max_sync < max_sector) - max_sector = sector_nr + max_sync; - - sectors_skipped += (max_sector - sector_nr); + { + sector_t sec = max_sector - sector_nr; + sectors_skipped += sec; chunks_skipped ++; sector_nr = max_sector; goto skipped; + } } static int run(mddev_t *mddev) diff --git a/trunk/drivers/media/common/tuners/tuner-simple.c b/trunk/drivers/media/common/tuners/tuner-simple.c index 78412c9c424a..de7adaf5fa5b 100644 --- a/trunk/drivers/media/common/tuners/tuner-simple.c +++ b/trunk/drivers/media/common/tuners/tuner-simple.c @@ -318,6 +318,7 @@ static int simple_std_setup(struct dvb_frontend *fe, u8 *config, u8 *cb) { struct tuner_simple_priv *priv = fe->tuner_priv; + u8 tuneraddr; int rc; /* tv norm specific stuff for multi-norm tuners */ @@ -386,7 +387,6 @@ static int simple_std_setup(struct dvb_frontend *fe, case TUNER_PHILIPS_TUV1236D: { - struct tuner_i2c_props i2c = priv->i2c_props; /* 0x40 -> ATSC antenna input 1 */ /* 0x48 -> ATSC antenna input 2 */ /* 0x00 -> NTSC antenna input 1 */ @@ -398,15 +398,17 @@ static int simple_std_setup(struct dvb_frontend *fe, buffer[1] = 0x04; } /* set to the correct mode (analog or digital) */ - i2c.addr = 0x0a; - rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2); + tuneraddr = priv->i2c_props.addr; + priv->i2c_props.addr = 0x0a; + rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[0], 2); if (2 != rc) tuner_warn("i2c i/o error: rc == %d " "(should be 2)\n", rc); - rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2); + rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[2], 2); if (2 != rc) tuner_warn("i2c i/o error: rc == %d " "(should be 2)\n", rc); + priv->i2c_props.addr = tuneraddr; break; } } diff --git a/trunk/drivers/media/dvb/Kconfig b/trunk/drivers/media/dvb/Kconfig index b0198691892a..40ebde53b3ce 100644 --- a/trunk/drivers/media/dvb/Kconfig +++ b/trunk/drivers/media/dvb/Kconfig @@ -51,10 +51,6 @@ comment "Supported SDMC DM1105 Adapters" depends on DVB_CORE && PCI && I2C source "drivers/media/dvb/dm1105/Kconfig" -comment "Supported FireWire (IEEE 1394) Adapters" - depends on DVB_CORE && IEEE1394 -source "drivers/media/dvb/firewire/Kconfig" - comment "Supported DVB Frontends" depends on DVB_CORE source "drivers/media/dvb/frontends/Kconfig" diff --git a/trunk/drivers/media/dvb/Makefile b/trunk/drivers/media/dvb/Makefile index 6092a5bb5a7d..f91e9eb15e52 100644 --- a/trunk/drivers/media/dvb/Makefile +++ b/trunk/drivers/media/dvb/Makefile @@ -3,5 +3,3 @@ # obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ - -obj-$(CONFIG_DVB_FIREDTV) += firewire/ diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/trunk/drivers/media/dvb/b2c2/flexcop-hw-filter.c index 451974ba32f3..b386cc66c6b3 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-hw-filter.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-hw-filter.c @@ -192,7 +192,6 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d return 0; } -EXPORT_SYMBOL(flexcop_pid_feed_control); void flexcop_hw_filter_init(struct flexcop_device *fc) { diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c index 76e37fd96bb6..5b30dfc7846b 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c @@ -13,9 +13,9 @@ static int enable_pid_filtering = 1; module_param(enable_pid_filtering, int, 0444); MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); -static int irq_chk_intv = 100; +static int irq_chk_intv; module_param(irq_chk_intv, int, 0644); -MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog."); +MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging)."); #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG #define dprintk(level,args...) \ @@ -34,9 +34,7 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog."); static int debug; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, - "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))." - DEBSTATUS); +MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS); #define DRIVER_VERSION "0.1" #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" @@ -60,8 +58,6 @@ struct flexcop_pci { int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ int count; - int count_prev; - int stream_problem; spinlock_t irq_lock; @@ -107,32 +103,18 @@ static void flexcop_pci_irq_check_work(struct work_struct *work) container_of(work, struct flexcop_pci, irq_check_work.work); struct flexcop_device *fc = fc_pci->fc_dev; - if (fc->feedcount) { - - if (fc_pci->count == fc_pci->count_prev) { - deb_chk("no IRQ since the last check\n"); - if (fc_pci->stream_problem++ == 3) { - struct dvb_demux_feed *feed; - - spin_lock_irq(&fc->demux.lock); - list_for_each_entry(feed, &fc->demux.feed_list, - list_head) { - flexcop_pid_feed_control(fc, feed, 0); - } - - list_for_each_entry(feed, &fc->demux.feed_list, - list_head) { - flexcop_pid_feed_control(fc, feed, 1); - } - spin_unlock_irq(&fc->demux.lock); - - fc_pci->stream_problem = 0; - } - } else { - fc_pci->stream_problem = 0; - fc_pci->count_prev = fc_pci->count; - } - } + flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); + + flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4); + + if (v.sram_dest_reg_714.net_ovflow_error) + deb_chk("sram net_ovflow_error\n"); + if (v.sram_dest_reg_714.media_ovflow_error) + deb_chk("sram media_ovflow_error\n"); + if (v.sram_dest_reg_714.cai_ovflow_error) + deb_chk("sram cai_ovflow_error\n"); + if (v.sram_dest_reg_714.cai_ovflow_error) + deb_chk("sram cai_ovflow_error\n"); schedule_delayed_work(&fc_pci->irq_check_work, msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); @@ -234,12 +216,16 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff) flexcop_dma_control_timer_irq(fc,FC_DMA_1,1); deb_irq("IRQ enabled\n"); - fc_pci->count_prev = fc_pci->count; - // fc_pci->active_dma1_addr = 0; // flexcop_dma_control_size_irq(fc,FC_DMA_1,1); + if (irq_chk_intv > 0) + schedule_delayed_work(&fc_pci->irq_check_work, + msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); } else { + if (irq_chk_intv > 0) + cancel_delayed_work(&fc_pci->irq_check_work); + flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); deb_irq("IRQ disabled\n"); @@ -313,6 +299,8 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) goto err_pci_iounmap; + + fc_pci->init_state |= FC_PCI_INIT; return ret; @@ -387,10 +375,6 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); - if (irq_chk_intv > 0) - schedule_delayed_work(&fc_pci->irq_check_work, - msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); - return ret; err_fc_exit: @@ -409,9 +393,6 @@ static void flexcop_pci_remove(struct pci_dev *pdev) { struct flexcop_pci *fc_pci = pci_get_drvdata(pdev); - if (irq_chk_intv > 0) - cancel_delayed_work(&fc_pci->irq_check_work); - flexcop_pci_dma_exit(fc_pci); flexcop_device_exit(fc_pci->fc_dev); flexcop_pci_exit(fc_pci); diff --git a/trunk/drivers/media/dvb/b2c2/flexcop.c b/trunk/drivers/media/dvb/b2c2/flexcop.c index 91068952b502..676413a915b4 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop.c @@ -212,7 +212,8 @@ void flexcop_reset_block_300(struct flexcop_device *fc) v210.sw_reset_210.Block_reset_enable = 0xb2; fc->write_ibi_reg(fc,sw_reset_210,v210); - udelay(1000); + msleep(1); + fc->write_ibi_reg(fc,ctrl_208,v208_save); } diff --git a/trunk/drivers/media/dvb/dvb-core/dmxdev.c b/trunk/drivers/media/dvb/dvb-core/dmxdev.c index 069d847ba887..0c733c66a441 100644 --- a/trunk/drivers/media/dvb/dvb-core/dmxdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dmxdev.c @@ -364,15 +364,16 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, enum dmx_success success) { struct dmxdev_filter *dmxdevfilter = filter->priv; + unsigned long flags; int ret; if (dmxdevfilter->buffer.error) { wake_up(&dmxdevfilter->buffer.queue); return 0; } - spin_lock(&dmxdevfilter->dev->lock); + spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); if (dmxdevfilter->state != DMXDEV_STATE_GO) { - spin_unlock(&dmxdevfilter->dev->lock); + spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); return 0; } del_timer(&dmxdevfilter->timer); @@ -391,7 +392,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, } if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) dmxdevfilter->state = DMXDEV_STATE_DONE; - spin_unlock(&dmxdevfilter->dev->lock); + spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); wake_up(&dmxdevfilter->buffer.queue); return 0; } @@ -403,11 +404,12 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, { struct dmxdev_filter *dmxdevfilter = feed->priv; struct dvb_ringbuffer *buffer; + unsigned long flags; int ret; - spin_lock(&dmxdevfilter->dev->lock); + spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { - spin_unlock(&dmxdevfilter->dev->lock); + spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); return 0; } @@ -417,7 +419,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, else buffer = &dmxdevfilter->dev->dvr_buffer; if (buffer->error) { - spin_unlock(&dmxdevfilter->dev->lock); + spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); wake_up(&buffer->queue); return 0; } @@ -428,7 +430,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, dvb_ringbuffer_flush(buffer); buffer->error = ret; } - spin_unlock(&dmxdevfilter->dev->lock); + spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); wake_up(&buffer->queue); return 0; } diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_demux.c b/trunk/drivers/media/dvb/dvb-core/dvb_demux.c index e2eca0b1fe7c..a2c1fd5d2f67 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_demux.c @@ -399,7 +399,9 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count) { - spin_lock(&demux->lock); + unsigned long flags; + + spin_lock_irqsave(&demux->lock, flags); while (count--) { if (buf[0] == 0x47) @@ -407,16 +409,17 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, buf += 188; } - spin_unlock(&demux->lock); + spin_unlock_irqrestore(&demux->lock, flags); } EXPORT_SYMBOL(dvb_dmx_swfilter_packets); void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) { + unsigned long flags; int p = 0, i, j; - spin_lock(&demux->lock); + spin_lock_irqsave(&demux->lock, flags); if (demux->tsbufp) { i = demux->tsbufp; @@ -449,17 +452,18 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock(&demux->lock); + spin_unlock_irqrestore(&demux->lock, flags); } EXPORT_SYMBOL(dvb_dmx_swfilter); void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) { + unsigned long flags; int p = 0, i, j; u8 tmppack[188]; - spin_lock(&demux->lock); + spin_lock_irqsave(&demux->lock, flags); if (demux->tsbufp) { i = demux->tsbufp; @@ -500,7 +504,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock(&demux->lock); + spin_unlock_irqrestore(&demux->lock, flags); } EXPORT_SYMBOL(dvb_dmx_swfilter_204); diff --git a/trunk/drivers/media/dvb/firewire/Kconfig b/trunk/drivers/media/dvb/firewire/Kconfig deleted file mode 100644 index 69028253e984..000000000000 --- a/trunk/drivers/media/dvb/firewire/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -config DVB_FIREDTV - tristate "FireDTV and FloppyDTV" - depends on DVB_CORE && IEEE1394 - help - Support for DVB receivers from Digital Everywhere - which are connected via IEEE 1394 (FireWire). - - These devices don't have an MPEG decoder built in, - so you need an external software decoder to watch TV. - - To compile this driver as a module, say M here: - the module will be called firedtv. - -if DVB_FIREDTV - -config DVB_FIREDTV_IEEE1394 - def_bool IEEE1394 - -config DVB_FIREDTV_INPUT - def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m) - -endif # DVB_FIREDTV diff --git a/trunk/drivers/media/dvb/firewire/Makefile b/trunk/drivers/media/dvb/firewire/Makefile deleted file mode 100644 index 2034695ba194..000000000000 --- a/trunk/drivers/media/dvb/firewire/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -obj-$(CONFIG_DVB_FIREDTV) += firedtv.o - -firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o -firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o -firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o - -ccflags-y += -Idrivers/media/dvb/dvb-core -ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394 diff --git a/trunk/drivers/media/dvb/firewire/firedtv-1394.c b/trunk/drivers/media/dvb/firewire/firedtv-1394.c deleted file mode 100644 index 4e207658c5d9..000000000000 --- a/trunk/drivers/media/dvb/firewire/firedtv-1394.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2007-2008 Ben Backx - * Copyright (C) 2008 Henrik Kurelid - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "firedtv.h" - -static LIST_HEAD(node_list); -static DEFINE_SPINLOCK(node_list_lock); - -#define FIREWIRE_HEADER_SIZE 4 -#define CIP_HEADER_SIZE 8 - -static void rawiso_activity_cb(struct hpsb_iso *iso) -{ - struct firedtv *f, *fdtv = NULL; - unsigned int i, num, packet; - unsigned char *buf; - unsigned long flags; - int count; - - spin_lock_irqsave(&node_list_lock, flags); - list_for_each_entry(f, &node_list, list) - if (f->backend_data == iso) { - fdtv = f; - break; - } - spin_unlock_irqrestore(&node_list_lock, flags); - - packet = iso->first_packet; - num = hpsb_iso_n_ready(iso); - - if (!fdtv) { - dev_err(fdtv->device, "received at unknown iso channel\n"); - goto out; - } - - for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) { - buf = dma_region_i(&iso->data_buf, unsigned char, - iso->infos[packet].offset + CIP_HEADER_SIZE); - count = (iso->infos[packet].len - CIP_HEADER_SIZE) / - (188 + FIREWIRE_HEADER_SIZE); - - /* ignore empty packet */ - if (iso->infos[packet].len <= CIP_HEADER_SIZE) - continue; - - while (count--) { - if (buf[FIREWIRE_HEADER_SIZE] == 0x47) - dvb_dmx_swfilter_packets(&fdtv->demux, - &buf[FIREWIRE_HEADER_SIZE], 1); - else - dev_err(fdtv->device, - "skipping invalid packet\n"); - buf += 188 + FIREWIRE_HEADER_SIZE; - } - } -out: - hpsb_iso_recv_release_packets(iso, num); -} - -static inline struct node_entry *node_of(struct firedtv *fdtv) -{ - return container_of(fdtv->device, struct unit_directory, device)->ne; -} - -static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg) -{ - return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data, - (__force quadlet_t)arg); -} - -static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) -{ - return hpsb_node_read(node_of(fdtv), addr, data, len); -} - -static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) -{ - return hpsb_node_write(node_of(fdtv), addr, data, len); -} - -#define FDTV_ISO_BUFFER_PACKETS 256 -#define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200) - -static int start_iso(struct firedtv *fdtv) -{ - struct hpsb_iso *iso_handle; - int ret; - - iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host, - FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS, - fdtv->isochannel, HPSB_ISO_DMA_DEFAULT, - -1, /* stat.config.irq_interval */ - rawiso_activity_cb); - if (iso_handle == NULL) { - dev_err(fdtv->device, "cannot initialize iso receive\n"); - return -ENOMEM; - } - fdtv->backend_data = iso_handle; - - ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0); - if (ret != 0) { - dev_err(fdtv->device, "cannot start iso receive\n"); - hpsb_iso_shutdown(iso_handle); - fdtv->backend_data = NULL; - } - return ret; -} - -static void stop_iso(struct firedtv *fdtv) -{ - struct hpsb_iso *iso_handle = fdtv->backend_data; - - if (iso_handle != NULL) { - hpsb_iso_stop(iso_handle); - hpsb_iso_shutdown(iso_handle); - } - fdtv->backend_data = NULL; -} - -static const struct firedtv_backend fdtv_1394_backend = { - .lock = node_lock, - .read = node_read, - .write = node_write, - .start_iso = start_iso, - .stop_iso = stop_iso, -}; - -static void fcp_request(struct hpsb_host *host, int nodeid, int direction, - int cts, u8 *data, size_t length) -{ - struct firedtv *f, *fdtv = NULL; - unsigned long flags; - int su; - - if (length == 0 || (data[0] & 0xf0) != 0) - return; - - su = data[1] & 0x7; - - spin_lock_irqsave(&node_list_lock, flags); - list_for_each_entry(f, &node_list, list) - if (node_of(f)->host == host && - node_of(f)->nodeid == nodeid && - (f->subunit == su || (f->subunit == 0 && su == 0x7))) { - fdtv = f; - break; - } - spin_unlock_irqrestore(&node_list_lock, flags); - - if (fdtv) - avc_recv(fdtv, data, length); -} - -static int node_probe(struct device *dev) -{ - struct unit_directory *ud = - container_of(dev, struct unit_directory, device); - struct firedtv *fdtv; - int kv_len, err; - void *kv_str; - - kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); - kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); - - fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len); - if (!fdtv) - return -ENOMEM; - - /* - * Work around a bug in udev's path_id script: Use the fw-host's dev - * instead of the unit directory's dev as parent of the input device. - */ - err = fdtv_register_rc(fdtv, dev->parent->parent); - if (err) - goto fail_free; - - spin_lock_irq(&node_list_lock); - list_add_tail(&fdtv->list, &node_list); - spin_unlock_irq(&node_list_lock); - - err = avc_identify_subunit(fdtv); - if (err) - goto fail; - - err = fdtv_dvb_register(fdtv); - if (err) - goto fail; - - avc_register_remote_control(fdtv); - return 0; -fail: - spin_lock_irq(&node_list_lock); - list_del(&fdtv->list); - spin_unlock_irq(&node_list_lock); - fdtv_unregister_rc(fdtv); -fail_free: - kfree(fdtv); - return err; -} - -static int node_remove(struct device *dev) -{ - struct firedtv *fdtv = dev->driver_data; - - fdtv_dvb_unregister(fdtv); - - spin_lock_irq(&node_list_lock); - list_del(&fdtv->list); - spin_unlock_irq(&node_list_lock); - - cancel_work_sync(&fdtv->remote_ctrl_work); - fdtv_unregister_rc(fdtv); - - kfree(fdtv); - return 0; -} - -static int node_update(struct unit_directory *ud) -{ - struct firedtv *fdtv = ud->device.driver_data; - - if (fdtv->isochannel >= 0) - cmp_establish_pp_connection(fdtv, fdtv->subunit, - fdtv->isochannel); - return 0; -} - -static struct hpsb_protocol_driver fdtv_driver = { - .name = "firedtv", - .update = node_update, - .driver = { - .probe = node_probe, - .remove = node_remove, - }, -}; - -static struct hpsb_highlevel fdtv_highlevel = { - .name = "firedtv", - .fcp_request = fcp_request, -}; - -int __init fdtv_1394_init(struct ieee1394_device_id id_table[]) -{ - int ret; - - hpsb_register_highlevel(&fdtv_highlevel); - fdtv_driver.id_table = id_table; - ret = hpsb_register_protocol(&fdtv_driver); - if (ret) { - printk(KERN_ERR "firedtv: failed to register protocol\n"); - hpsb_unregister_highlevel(&fdtv_highlevel); - } - return ret; -} - -void __exit fdtv_1394_exit(void) -{ - hpsb_unregister_protocol(&fdtv_driver); - hpsb_unregister_highlevel(&fdtv_highlevel); -} diff --git a/trunk/drivers/media/dvb/firewire/firedtv-avc.c b/trunk/drivers/media/dvb/firewire/firedtv-avc.c deleted file mode 100644 index b55d9ccaf33e..000000000000 --- a/trunk/drivers/media/dvb/firewire/firedtv-avc.c +++ /dev/null @@ -1,1315 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Ben Backx - * Copyright (C) 2008 Henrik Kurelid - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "firedtv.h" - -#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL - -#define AVC_CTYPE_CONTROL 0x0 -#define AVC_CTYPE_STATUS 0x1 -#define AVC_CTYPE_NOTIFY 0x3 - -#define AVC_RESPONSE_ACCEPTED 0x9 -#define AVC_RESPONSE_STABLE 0xc -#define AVC_RESPONSE_CHANGED 0xd -#define AVC_RESPONSE_INTERIM 0xf - -#define AVC_SUBUNIT_TYPE_TUNER (0x05 << 3) -#define AVC_SUBUNIT_TYPE_UNIT (0x1f << 3) - -#define AVC_OPCODE_VENDOR 0x00 -#define AVC_OPCODE_READ_DESCRIPTOR 0x09 -#define AVC_OPCODE_DSIT 0xc8 -#define AVC_OPCODE_DSD 0xcb - -#define DESCRIPTOR_TUNER_STATUS 0x80 -#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00 - -#define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */ -#define SFE_VENDOR_DE_COMPANYID_1 0x12 -#define SFE_VENDOR_DE_COMPANYID_2 0x87 - -#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a -#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52 -#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 /* for DVB-S */ - -#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00 -#define SFE_VENDOR_OPCODE_HOST2CA 0x56 -#define SFE_VENDOR_OPCODE_CA2HOST 0x57 -#define SFE_VENDOR_OPCODE_CISTATUS 0x59 -#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 /* for DVB-S2 */ - -#define SFE_VENDOR_TAG_CA_RESET 0x00 -#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01 -#define SFE_VENDOR_TAG_CA_PMT 0x02 -#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04 -#define SFE_VENDOR_TAG_CA_MMI 0x05 -#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07 - -#define EN50221_LIST_MANAGEMENT_ONLY 0x03 -#define EN50221_TAG_APP_INFO 0x9f8021 -#define EN50221_TAG_CA_INFO 0x9f8031 - -struct avc_command_frame { - int length; - u8 ctype; - u8 subunit; - u8 opcode; - u8 operand[509]; -}; - -struct avc_response_frame { - int length; - u8 response; - u8 subunit; - u8 opcode; - u8 operand[509]; -}; - -#define AVC_DEBUG_FCP_SUBACTIONS 1 -#define AVC_DEBUG_FCP_PAYLOADS 2 - -static int avc_debug; -module_param_named(debug, avc_debug, int, 0644); -MODULE_PARM_DESC(debug, "Verbose logging (default = 0" - ", FCP subactions = " __stringify(AVC_DEBUG_FCP_SUBACTIONS) - ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS) - ", or all = -1)"); - -static const char *debug_fcp_ctype(unsigned int ctype) -{ - static const char *ctypes[] = { - [0x0] = "CONTROL", [0x1] = "STATUS", - [0x2] = "SPECIFIC INQUIRY", [0x3] = "NOTIFY", - [0x4] = "GENERAL INQUIRY", [0x8] = "NOT IMPLEMENTED", - [0x9] = "ACCEPTED", [0xa] = "REJECTED", - [0xb] = "IN TRANSITION", [0xc] = "IMPLEMENTED/STABLE", - [0xd] = "CHANGED", [0xf] = "INTERIM", - }; - const char *ret = ctype < ARRAY_SIZE(ctypes) ? ctypes[ctype] : NULL; - - return ret ? ret : "?"; -} - -static const char *debug_fcp_opcode(unsigned int opcode, - const u8 *data, size_t length) -{ - switch (opcode) { - case AVC_OPCODE_VENDOR: break; - case AVC_OPCODE_READ_DESCRIPTOR: return "ReadDescriptor"; - case AVC_OPCODE_DSIT: return "DirectSelectInfo.Type"; - case AVC_OPCODE_DSD: return "DirectSelectData"; - default: return "?"; - } - - if (length < 7 || - data[3] != SFE_VENDOR_DE_COMPANYID_0 || - data[4] != SFE_VENDOR_DE_COMPANYID_1 || - data[5] != SFE_VENDOR_DE_COMPANYID_2) - return "Vendor"; - - switch (data[6]) { - case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC"; - case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl"; - case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK"; - case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA"; - case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host"; - } - return "Vendor"; -} - -static void debug_fcp(const u8 *data, size_t length) -{ - unsigned int subunit_type, subunit_id, op; - const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> "; - - if (avc_debug & AVC_DEBUG_FCP_SUBACTIONS) { - subunit_type = data[1] >> 3; - subunit_id = data[1] & 7; - op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2]; - printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n", - prefix, subunit_type, subunit_id, length, - debug_fcp_ctype(data[0]), - debug_fcp_opcode(op, data, length)); - } - - if (avc_debug & AVC_DEBUG_FCP_PAYLOADS) - print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1, - data, length, false); -} - -static int __avc_write(struct firedtv *fdtv, - const struct avc_command_frame *c, struct avc_response_frame *r) -{ - int err, retry; - - if (r) - fdtv->avc_reply_received = false; - - for (retry = 0; retry < 6; retry++) { - if (unlikely(avc_debug)) - debug_fcp(&c->ctype, c->length); - - err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, - (void *)&c->ctype, c->length); - if (err) { - fdtv->avc_reply_received = true; - dev_err(fdtv->device, "FCP command write failed\n"); - return err; - } - - if (!r) - return 0; - - /* - * AV/C specs say that answers should be sent within 150 ms. - * Time out after 200 ms. - */ - if (wait_event_timeout(fdtv->avc_wait, - fdtv->avc_reply_received, - msecs_to_jiffies(200)) != 0) { - r->length = fdtv->response_length; - memcpy(&r->response, fdtv->response, r->length); - - return 0; - } - } - dev_err(fdtv->device, "FCP response timed out\n"); - return -ETIMEDOUT; -} - -static int avc_write(struct firedtv *fdtv, - const struct avc_command_frame *c, struct avc_response_frame *r) -{ - int ret; - - if (mutex_lock_interruptible(&fdtv->avc_mutex)) - return -EINTR; - - ret = __avc_write(fdtv, c, r); - - mutex_unlock(&fdtv->avc_mutex); - return ret; -} - -int avc_recv(struct firedtv *fdtv, void *data, size_t length) -{ - struct avc_response_frame *r = - data - offsetof(struct avc_response_frame, response); - - if (unlikely(avc_debug)) - debug_fcp(data, length); - - if (length >= 8 && - r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && - r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && - r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && - r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { - if (r->response == AVC_RESPONSE_CHANGED) { - fdtv_handle_rc(fdtv, - r->operand[4] << 8 | r->operand[5]); - schedule_work(&fdtv->remote_ctrl_work); - } else if (r->response != AVC_RESPONSE_INTERIM) { - dev_info(fdtv->device, - "remote control result = %d\n", r->response); - } - return 0; - } - - if (fdtv->avc_reply_received) { - dev_err(fdtv->device, "out-of-order AVC response, ignored\n"); - return -EIO; - } - - memcpy(fdtv->response, data, length); - fdtv->response_length = length; - - fdtv->avc_reply_received = true; - wake_up(&fdtv->avc_wait); - - return 0; -} - -/* - * tuning command for setting the relative LNB frequency - * (not supported by the AVC standard) - */ -static void avc_tuner_tuneqpsk(struct firedtv *fdtv, - struct dvb_frontend_parameters *params, - struct avc_command_frame *c) -{ - c->opcode = AVC_OPCODE_VENDOR; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; - - c->operand[4] = (params->frequency >> 24) & 0xff; - c->operand[5] = (params->frequency >> 16) & 0xff; - c->operand[6] = (params->frequency >> 8) & 0xff; - c->operand[7] = params->frequency & 0xff; - - c->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff; - c->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff; - - switch (params->u.qpsk.fec_inner) { - case FEC_1_2: c->operand[10] = 0x1; break; - case FEC_2_3: c->operand[10] = 0x2; break; - case FEC_3_4: c->operand[10] = 0x3; break; - case FEC_5_6: c->operand[10] = 0x4; break; - case FEC_7_8: c->operand[10] = 0x5; break; - case FEC_4_5: - case FEC_8_9: - case FEC_AUTO: - default: c->operand[10] = 0x0; - } - - if (fdtv->voltage == 0xff) - c->operand[11] = 0xff; - else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */ - c->operand[11] = 0; - else - c->operand[11] = 1; - - if (fdtv->tone == 0xff) - c->operand[12] = 0xff; - else if (fdtv->tone == SEC_TONE_ON) /* band */ - c->operand[12] = 1; - else - c->operand[12] = 0; - - if (fdtv->type == FIREDTV_DVB_S2) { - c->operand[13] = 0x1; - c->operand[14] = 0xff; - c->operand[15] = 0xff; - c->length = 20; - } else { - c->length = 16; - } -} - -static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, - struct avc_command_frame *c) -{ - c->opcode = AVC_OPCODE_DSD; - - c->operand[0] = 0; /* source plug */ - c->operand[1] = 0xd2; /* subfunction replace */ - c->operand[2] = 0x20; /* system id = DVB */ - c->operand[3] = 0x00; /* antenna number */ - c->operand[4] = 0x11; /* system_specific_multiplex selection_length */ - - /* multiplex_valid_flags, high byte */ - c->operand[5] = 0 << 7 /* reserved */ - | 0 << 6 /* Polarisation */ - | 0 << 5 /* Orbital_Pos */ - | 1 << 4 /* Frequency */ - | 1 << 3 /* Symbol_Rate */ - | 0 << 2 /* FEC_outer */ - | (params->u.qam.fec_inner != FEC_AUTO ? 1 << 1 : 0) - | (params->u.qam.modulation != QAM_AUTO ? 1 << 0 : 0); - - /* multiplex_valid_flags, low byte */ - c->operand[6] = 0 << 7 /* NetworkID */ - | 0 << 0 /* reserved */ ; - - c->operand[7] = 0x00; - c->operand[8] = 0x00; - c->operand[9] = 0x00; - c->operand[10] = 0x00; - - c->operand[11] = (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6); - c->operand[12] = ((params->frequency / 4000) >> 8) & 0xff; - c->operand[13] = (params->frequency / 4000) & 0xff; - c->operand[14] = ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff; - c->operand[15] = ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff; - c->operand[16] = ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0; - c->operand[17] = 0x00; - - switch (params->u.qpsk.fec_inner) { - case FEC_1_2: c->operand[18] = 0x1; break; - case FEC_2_3: c->operand[18] = 0x2; break; - case FEC_3_4: c->operand[18] = 0x3; break; - case FEC_5_6: c->operand[18] = 0x4; break; - case FEC_7_8: c->operand[18] = 0x5; break; - case FEC_8_9: c->operand[18] = 0x6; break; - case FEC_4_5: c->operand[18] = 0x8; break; - case FEC_AUTO: - default: c->operand[18] = 0x0; - } - - switch (params->u.qam.modulation) { - case QAM_16: c->operand[19] = 0x08; break; - case QAM_32: c->operand[19] = 0x10; break; - case QAM_64: c->operand[19] = 0x18; break; - case QAM_128: c->operand[19] = 0x20; break; - case QAM_256: c->operand[19] = 0x28; break; - case QAM_AUTO: - default: c->operand[19] = 0x00; - } - - c->operand[20] = 0x00; - c->operand[21] = 0x00; - /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ - c->operand[22] = 0x00; - - c->length = 28; -} - -static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, - struct avc_command_frame *c) -{ - struct dvb_ofdm_parameters *ofdm = ¶ms->u.ofdm; - - c->opcode = AVC_OPCODE_DSD; - - c->operand[0] = 0; /* source plug */ - c->operand[1] = 0xd2; /* subfunction replace */ - c->operand[2] = 0x20; /* system id = DVB */ - c->operand[3] = 0x00; /* antenna number */ - c->operand[4] = 0x0c; /* system_specific_multiplex selection_length */ - - /* multiplex_valid_flags, high byte */ - c->operand[5] = - 0 << 7 /* reserved */ - | 1 << 6 /* CenterFrequency */ - | (ofdm->bandwidth != BANDWIDTH_AUTO ? 1 << 5 : 0) - | (ofdm->constellation != QAM_AUTO ? 1 << 4 : 0) - | (ofdm->hierarchy_information != HIERARCHY_AUTO ? 1 << 3 : 0) - | (ofdm->code_rate_HP != FEC_AUTO ? 1 << 2 : 0) - | (ofdm->code_rate_LP != FEC_AUTO ? 1 << 1 : 0) - | (ofdm->guard_interval != GUARD_INTERVAL_AUTO ? 1 << 0 : 0); - - /* multiplex_valid_flags, low byte */ - c->operand[6] = - 0 << 7 /* NetworkID */ - | (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0) - | 0 << 5 /* OtherFrequencyFlag */ - | 0 << 0 /* reserved */ ; - - c->operand[7] = 0x0; - c->operand[8] = (params->frequency / 10) >> 24; - c->operand[9] = ((params->frequency / 10) >> 16) & 0xff; - c->operand[10] = ((params->frequency / 10) >> 8) & 0xff; - c->operand[11] = (params->frequency / 10) & 0xff; - - switch (ofdm->bandwidth) { - case BANDWIDTH_7_MHZ: c->operand[12] = 0x20; break; - case BANDWIDTH_8_MHZ: - case BANDWIDTH_6_MHZ: /* not defined by AVC spec */ - case BANDWIDTH_AUTO: - default: c->operand[12] = 0x00; - } - - switch (ofdm->constellation) { - case QAM_16: c->operand[13] = 1 << 6; break; - case QAM_64: c->operand[13] = 2 << 6; break; - case QPSK: - default: c->operand[13] = 0x00; - } - - switch (ofdm->hierarchy_information) { - case HIERARCHY_1: c->operand[13] |= 1 << 3; break; - case HIERARCHY_2: c->operand[13] |= 2 << 3; break; - case HIERARCHY_4: c->operand[13] |= 3 << 3; break; - case HIERARCHY_AUTO: - case HIERARCHY_NONE: - default: break; - } - - switch (ofdm->code_rate_HP) { - case FEC_2_3: c->operand[13] |= 1; break; - case FEC_3_4: c->operand[13] |= 2; break; - case FEC_5_6: c->operand[13] |= 3; break; - case FEC_7_8: c->operand[13] |= 4; break; - case FEC_1_2: - default: break; - } - - switch (ofdm->code_rate_LP) { - case FEC_2_3: c->operand[14] = 1 << 5; break; - case FEC_3_4: c->operand[14] = 2 << 5; break; - case FEC_5_6: c->operand[14] = 3 << 5; break; - case FEC_7_8: c->operand[14] = 4 << 5; break; - case FEC_1_2: - default: c->operand[14] = 0x00; break; - } - - switch (ofdm->guard_interval) { - case GUARD_INTERVAL_1_16: c->operand[14] |= 1 << 3; break; - case GUARD_INTERVAL_1_8: c->operand[14] |= 2 << 3; break; - case GUARD_INTERVAL_1_4: c->operand[14] |= 3 << 3; break; - case GUARD_INTERVAL_1_32: - case GUARD_INTERVAL_AUTO: - default: break; - } - - switch (ofdm->transmission_mode) { - case TRANSMISSION_MODE_8K: c->operand[14] |= 1 << 1; break; - case TRANSMISSION_MODE_2K: - case TRANSMISSION_MODE_AUTO: - default: break; - } - - c->operand[15] = 0x00; /* network_ID[0] */ - c->operand[16] = 0x00; /* network_ID[1] */ - /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ - c->operand[17] = 0x00; - - c->length = 24; -} - -int avc_tuner_dsd(struct firedtv *fdtv, - struct dvb_frontend_parameters *params) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_CONTROL; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - - switch (fdtv->type) { - case FIREDTV_DVB_S: - case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break; - case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break; - case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break; - default: - BUG(); - } - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - msleep(500); -#if 0 - /* FIXME: */ - /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ - if (status) - *status = r->operand[2]; -#endif - return 0; -} - -int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ - int pos, k; - - if (pidc > 16 && pidc != 0xff) - return -EINVAL; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_CONTROL; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_DSD; - - c->operand[0] = 0; /* source plug */ - c->operand[1] = 0xd2; /* subfunction replace */ - c->operand[2] = 0x20; /* system id = DVB */ - c->operand[3] = 0x00; /* antenna number */ - c->operand[4] = 0x00; /* system_specific_multiplex selection_length */ - c->operand[5] = pidc; /* Nr_of_dsd_sel_specs */ - - pos = 6; - if (pidc != 0xff) - for (k = 0; k < pidc; k++) { - c->operand[pos++] = 0x13; /* flowfunction relay */ - c->operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */ - c->operand[pos++] = (pid[k] >> 8) & 0x1f; - c->operand[pos++] = pid[k] & 0xff; - c->operand[pos++] = 0x00; /* tableID */ - c->operand[pos++] = 0x00; /* filter_length */ - } - - c->length = ALIGN(3 + pos, 4); - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - msleep(50); - return 0; -} - -int avc_tuner_get_ts(struct firedtv *fdtv) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ - int sl; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_CONTROL; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_DSIT; - - sl = fdtv->type == FIREDTV_DVB_T ? 0x0c : 0x11; - - c->operand[0] = 0; /* source plug */ - c->operand[1] = 0xd2; /* subfunction replace */ - c->operand[2] = 0xff; /* status */ - c->operand[3] = 0x20; /* system id = DVB */ - c->operand[4] = 0x00; /* antenna number */ - c->operand[5] = 0x0; /* system_specific_search_flags */ - c->operand[6] = sl; /* system_specific_multiplex selection_length */ - c->operand[7] = 0x00; /* valid_flags [0] */ - c->operand[8] = 0x00; /* valid_flags [1] */ - c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */ - - c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28; - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - msleep(250); - return 0; -} - -int avc_identify_subunit(struct firedtv *fdtv) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_CONTROL; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_READ_DESCRIPTOR; - - c->operand[0] = DESCRIPTOR_SUBUNIT_IDENTIFIER; - c->operand[1] = 0xff; - c->operand[2] = 0x00; - c->operand[3] = 0x00; /* length highbyte */ - c->operand[4] = 0x08; /* length lowbyte */ - c->operand[5] = 0x00; /* offset highbyte */ - c->operand[6] = 0x0d; /* offset lowbyte */ - - c->length = 12; - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - if ((r->response != AVC_RESPONSE_STABLE && - r->response != AVC_RESPONSE_ACCEPTED) || - (r->operand[3] << 8) + r->operand[4] != 8) { - dev_err(fdtv->device, "cannot read subunit identifier\n"); - return -EINVAL; - } - return 0; -} - -#define SIZEOF_ANTENNA_INPUT_INFO 22 - -int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; - int length; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_CONTROL; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_READ_DESCRIPTOR; - - c->operand[0] = DESCRIPTOR_TUNER_STATUS; - c->operand[1] = 0xff; /* read_result_status */ - c->operand[2] = 0x00; /* reserved */ - c->operand[3] = 0; /* SIZEOF_ANTENNA_INPUT_INFO >> 8; */ - c->operand[4] = 0; /* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */ - c->operand[5] = 0x00; - c->operand[6] = 0x00; - - c->length = 12; - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - if (r->response != AVC_RESPONSE_STABLE && - r->response != AVC_RESPONSE_ACCEPTED) { - dev_err(fdtv->device, "cannot read tuner status\n"); - return -EINVAL; - } - - length = r->operand[9]; - if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) { - dev_err(fdtv->device, "got invalid tuner status\n"); - return -EINVAL; - } - - stat->active_system = r->operand[10]; - stat->searching = r->operand[11] >> 7 & 1; - stat->moving = r->operand[11] >> 6 & 1; - stat->no_rf = r->operand[11] >> 5 & 1; - stat->input = r->operand[12] >> 7 & 1; - stat->selected_antenna = r->operand[12] & 0x7f; - stat->ber = r->operand[13] << 24 | - r->operand[14] << 16 | - r->operand[15] << 8 | - r->operand[16]; - stat->signal_strength = r->operand[17]; - stat->raster_frequency = r->operand[18] >> 6 & 2; - stat->rf_frequency = (r->operand[18] & 0x3f) << 16 | - r->operand[19] << 8 | - r->operand[20]; - stat->man_dep_info_length = r->operand[21]; - stat->front_end_error = r->operand[22] >> 4 & 1; - stat->antenna_error = r->operand[22] >> 3 & 1; - stat->front_end_power_status = r->operand[22] >> 1 & 1; - stat->power_supply = r->operand[22] & 1; - stat->carrier_noise_ratio = r->operand[23] << 8 | - r->operand[24]; - stat->power_supply_voltage = r->operand[27]; - stat->antenna_voltage = r->operand[28]; - stat->firewire_bus_voltage = r->operand[29]; - stat->ca_mmi = r->operand[30] & 1; - stat->ca_pmt_reply = r->operand[31] >> 7 & 1; - stat->ca_date_time_request = r->operand[31] >> 6 & 1; - stat->ca_application_info = r->operand[31] >> 5 & 1; - stat->ca_module_present_status = r->operand[31] >> 4 & 1; - stat->ca_dvb_flag = r->operand[31] >> 3 & 1; - stat->ca_error_flag = r->operand[31] >> 2 & 1; - stat->ca_initialization_status = r->operand[31] >> 1 & 1; - - return 0; -} - -int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, - char conttone, char nrdiseq, - struct dvb_diseqc_master_cmd *diseqcmd) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; - int i, j, k; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_CONTROL; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_VENDOR; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL; - - c->operand[4] = voltage; - c->operand[5] = nrdiseq; - - i = 6; - - for (j = 0; j < nrdiseq; j++) { - c->operand[i++] = diseqcmd[j].msg_len; - - for (k = 0; k < diseqcmd[j].msg_len; k++) - c->operand[i++] = diseqcmd[j].msg[k]; - } - - c->operand[i++] = burst; - c->operand[i++] = conttone; - - c->length = ALIGN(3 + i, 4); - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - if (r->response != AVC_RESPONSE_ACCEPTED) { - dev_err(fdtv->device, "LNB control failed\n"); - return -EINVAL; - } - - return 0; -} - -int avc_register_remote_control(struct firedtv *fdtv) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_NOTIFY; - c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7; - c->opcode = AVC_OPCODE_VENDOR; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; - - c->length = 8; - - return avc_write(fdtv, c, NULL); -} - -void avc_remote_ctrl_work(struct work_struct *work) -{ - struct firedtv *fdtv = - container_of(work, struct firedtv, remote_ctrl_work); - - /* Should it be rescheduled in failure cases? */ - avc_register_remote_control(fdtv); -} - -#if 0 /* FIXME: unused */ -int avc_tuner_host2ca(struct firedtv *fdtv) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_CONTROL; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_VENDOR; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; - c->operand[4] = 0; /* slot */ - c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ - c->operand[6] = 0; /* more/last */ - c->operand[7] = 0; /* length */ - - c->length = 12; - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - return 0; -} -#endif - -static int get_ca_object_pos(struct avc_response_frame *r) -{ - int length = 1; - - /* Check length of length field */ - if (r->operand[7] & 0x80) - length = (r->operand[7] & 0x7f) + 1; - return length + 7; -} - -static int get_ca_object_length(struct avc_response_frame *r) -{ -#if 0 /* FIXME: unused */ - int size = 0; - int i; - - if (r->operand[7] & 0x80) - for (i = 0; i < (r->operand[7] & 0x7f); i++) { - size <<= 8; - size += r->operand[8 + i]; - } -#endif - return r->operand[7]; -} - -int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; - int pos; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_STATUS; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_VENDOR; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; - c->operand[4] = 0; /* slot */ - c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ - - c->length = 12; - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - /* FIXME: check response code and validate response data */ - - pos = get_ca_object_pos(r); - app_info[0] = (EN50221_TAG_APP_INFO >> 16) & 0xff; - app_info[1] = (EN50221_TAG_APP_INFO >> 8) & 0xff; - app_info[2] = (EN50221_TAG_APP_INFO >> 0) & 0xff; - app_info[3] = 6 + r->operand[pos + 4]; - app_info[4] = 0x01; - memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]); - *len = app_info[3] + 4; - - return 0; -} - -int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; - int pos; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_STATUS; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_VENDOR; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; - c->operand[4] = 0; /* slot */ - c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ - - c->length = 12; - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - pos = get_ca_object_pos(r); - app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; - app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff; - app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff; - app_info[3] = 2; - app_info[4] = r->operand[pos + 0]; - app_info[5] = r->operand[pos + 1]; - *len = app_info[3] + 4; - - return 0; -} - -int avc_ca_reset(struct firedtv *fdtv) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_CONTROL; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_VENDOR; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; - c->operand[4] = 0; /* slot */ - c->operand[5] = SFE_VENDOR_TAG_CA_RESET; /* ca tag */ - c->operand[6] = 0; /* more/last */ - c->operand[7] = 1; /* length */ - c->operand[8] = 0; /* force hardware reset */ - - c->length = 12; - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - return 0; -} - -int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; - int list_management; - int program_info_length; - int pmt_cmd_id; - int read_pos; - int write_pos; - int es_info_length; - int crc32_csum; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_CONTROL; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_VENDOR; - - if (msg[0] != EN50221_LIST_MANAGEMENT_ONLY) { - dev_info(fdtv->device, "forcing list_management to ONLY\n"); - msg[0] = EN50221_LIST_MANAGEMENT_ONLY; - } - /* We take the cmd_id from the programme level only! */ - list_management = msg[0]; - program_info_length = ((msg[4] & 0x0f) << 8) + msg[5]; - if (program_info_length > 0) - program_info_length--; /* Remove pmt_cmd_id */ - pmt_cmd_id = msg[6]; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; - c->operand[4] = 0; /* slot */ - c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */ - c->operand[6] = 0; /* more/last */ - /* c->operand[7] = XXXprogram_info_length + 17; */ /* length */ - c->operand[8] = list_management; - c->operand[9] = 0x01; /* pmt_cmd=OK_descramble */ - - /* TS program map table */ - - c->operand[10] = 0x02; /* Table id=2 */ - c->operand[11] = 0x80; /* Section syntax + length */ - /* c->operand[12] = XXXprogram_info_length + 12; */ - c->operand[13] = msg[1]; /* Program number */ - c->operand[14] = msg[2]; - c->operand[15] = 0x01; /* Version number=0 + current/next=1 */ - c->operand[16] = 0x00; /* Section number=0 */ - c->operand[17] = 0x00; /* Last section number=0 */ - c->operand[18] = 0x1f; /* PCR_PID=1FFF */ - c->operand[19] = 0xff; - c->operand[20] = (program_info_length >> 8); /* Program info length */ - c->operand[21] = (program_info_length & 0xff); - - /* CA descriptors at programme level */ - read_pos = 6; - write_pos = 22; - if (program_info_length > 0) { - pmt_cmd_id = msg[read_pos++]; - if (pmt_cmd_id != 1 && pmt_cmd_id != 4) - dev_err(fdtv->device, - "invalid pmt_cmd_id %d\n", pmt_cmd_id); - - memcpy(&c->operand[write_pos], &msg[read_pos], - program_info_length); - read_pos += program_info_length; - write_pos += program_info_length; - } - while (read_pos < length) { - c->operand[write_pos++] = msg[read_pos++]; - c->operand[write_pos++] = msg[read_pos++]; - c->operand[write_pos++] = msg[read_pos++]; - es_info_length = - ((msg[read_pos] & 0x0f) << 8) + msg[read_pos + 1]; - read_pos += 2; - if (es_info_length > 0) - es_info_length--; /* Remove pmt_cmd_id */ - c->operand[write_pos++] = es_info_length >> 8; - c->operand[write_pos++] = es_info_length & 0xff; - if (es_info_length > 0) { - pmt_cmd_id = msg[read_pos++]; - if (pmt_cmd_id != 1 && pmt_cmd_id != 4) - dev_err(fdtv->device, "invalid pmt_cmd_id %d " - "at stream level\n", pmt_cmd_id); - - memcpy(&c->operand[write_pos], &msg[read_pos], - es_info_length); - read_pos += es_info_length; - write_pos += es_info_length; - } - } - - /* CRC */ - c->operand[write_pos++] = 0x00; - c->operand[write_pos++] = 0x00; - c->operand[write_pos++] = 0x00; - c->operand[write_pos++] = 0x00; - - c->operand[7] = write_pos - 8; - c->operand[12] = write_pos - 13; - - crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1); - c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff; - c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff; - c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff; - c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff; - - c->length = ALIGN(3 + write_pos, 4); - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - if (r->response != AVC_RESPONSE_ACCEPTED) { - dev_err(fdtv->device, - "CA PMT failed with response 0x%x\n", r->response); - return -EFAULT; - } - - return 0; -} - -int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_STATUS; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_VENDOR; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; - c->operand[4] = 0; /* slot */ - c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */ - c->operand[6] = 0; /* more/last */ - c->operand[7] = 0; /* length */ - - c->length = 12; - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - /* FIXME: check response code and validate response data */ - - *interval = r->operand[get_ca_object_pos(r)]; - - return 0; -} - -int avc_ca_enter_menu(struct firedtv *fdtv) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_STATUS; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_VENDOR; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; - c->operand[4] = 0; /* slot */ - c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; - c->operand[6] = 0; /* more/last */ - c->operand[7] = 0; /* length */ - - c->length = 12; - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - return 0; -} - -int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) -{ - char buffer[sizeof(struct avc_command_frame)]; - struct avc_command_frame *c = (void *)buffer; - struct avc_response_frame *r = (void *)buffer; - - memset(c, 0, sizeof(*c)); - - c->ctype = AVC_CTYPE_STATUS; - c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; - c->opcode = AVC_OPCODE_VENDOR; - - c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; - c->operand[4] = 0; /* slot */ - c->operand[5] = SFE_VENDOR_TAG_CA_MMI; - c->operand[6] = 0; /* more/last */ - c->operand[7] = 0; /* length */ - - c->length = 12; - - if (avc_write(fdtv, c, r) < 0) - return -EIO; - - /* FIXME: check response code and validate response data */ - - *len = get_ca_object_length(r); - memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len); - - return 0; -} - -#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL - -static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) -{ - int ret; - - if (mutex_lock_interruptible(&fdtv->avc_mutex)) - return -EINTR; - - ret = fdtv->backend->read(fdtv, addr, buf, len); - if (ret < 0) - dev_err(fdtv->device, "CMP: read I/O error\n"); - - mutex_unlock(&fdtv->avc_mutex); - return ret; -} - -static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg) -{ - int ret; - - if (mutex_lock_interruptible(&fdtv->avc_mutex)) - return -EINTR; - - ret = fdtv->backend->lock(fdtv, addr, data, arg); - if (ret < 0) - dev_err(fdtv->device, "CMP: lock I/O error\n"); - - mutex_unlock(&fdtv->avc_mutex); - return ret; -} - -static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift) -{ - return (be32_to_cpu(opcr) >> shift) & mask; -} - -static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) -{ - *opcr &= ~cpu_to_be32(mask << shift); - *opcr |= cpu_to_be32((value & mask) << shift); -} - -#define get_opcr_online(v) get_opcr((v), 0x1, 31) -#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24) -#define get_opcr_channel(v) get_opcr((v), 0x3f, 16) - -#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24) -#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16) -#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14) -#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10) - -int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) -{ - __be32 old_opcr, opcr; - u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); - int attempts = 0; - int ret; - - ret = cmp_read(fdtv, &opcr, opcr_address, 4); - if (ret < 0) - return ret; - -repeat: - if (!get_opcr_online(opcr)) { - dev_err(fdtv->device, "CMP: output offline\n"); - return -EBUSY; - } - - old_opcr = opcr; - - if (get_opcr_p2p_connections(opcr)) { - if (get_opcr_channel(opcr) != channel) { - dev_err(fdtv->device, "CMP: cannot change channel\n"); - return -EBUSY; - } - dev_info(fdtv->device, "CMP: overlaying connection\n"); - - /* We don't allocate isochronous resources. */ - } else { - set_opcr_channel(&opcr, channel); - set_opcr_data_rate(&opcr, 2); /* S400 */ - - /* FIXME: this is for the worst case - optimize */ - set_opcr_overhead_id(&opcr, 0); - - /* - * FIXME: allocate isochronous channel and bandwidth at IRM - * fdtv->backend->alloc_resources(fdtv, channels_mask, bw); - */ - } - - set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); - - ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr); - if (ret < 0) - return ret; - - if (old_opcr != opcr) { - /* - * FIXME: if old_opcr.P2P_Connections > 0, - * deallocate isochronous channel and bandwidth at IRM - * if (...) - * fdtv->backend->dealloc_resources(fdtv, channel, bw); - */ - - if (++attempts < 6) /* arbitrary limit */ - goto repeat; - return -EBUSY; - } - - return 0; -} - -void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) -{ - __be32 old_opcr, opcr; - u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); - int attempts = 0; - - if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0) - return; - -repeat: - if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || - get_opcr_channel(opcr) != channel) { - dev_err(fdtv->device, "CMP: no connection to break\n"); - return; - } - - old_opcr = opcr; - set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); - - if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0) - return; - - if (old_opcr != opcr) { - /* - * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last - * owner, deallocate isochronous channel and bandwidth at IRM - * if (...) - * fdtv->backend->dealloc_resources(fdtv, channel, bw); - */ - - if (++attempts < 6) /* arbitrary limit */ - goto repeat; - } -} diff --git a/trunk/drivers/media/dvb/firewire/firedtv-ci.c b/trunk/drivers/media/dvb/firewire/firedtv-ci.c deleted file mode 100644 index eeb80d0ea3ff..000000000000 --- a/trunk/drivers/media/dvb/firewire/firedtv-ci.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Henrik Kurelid - * - * 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. - */ - -#include -#include -#include -#include - -#include - -#include "firedtv.h" - -#define EN50221_TAG_APP_INFO_ENQUIRY 0x9f8020 -#define EN50221_TAG_CA_INFO_ENQUIRY 0x9f8030 -#define EN50221_TAG_CA_PMT 0x9f8032 -#define EN50221_TAG_ENTER_MENU 0x9f8022 - -static int fdtv_ca_ready(struct firedtv_tuner_status *stat) -{ - return stat->ca_initialization_status == 1 && - stat->ca_error_flag == 0 && - stat->ca_dvb_flag == 1 && - stat->ca_module_present_status == 1; -} - -static int fdtv_get_ca_flags(struct firedtv_tuner_status *stat) -{ - int flags = 0; - - if (stat->ca_module_present_status == 1) - flags |= CA_CI_MODULE_PRESENT; - if (stat->ca_initialization_status == 1 && - stat->ca_error_flag == 0 && - stat->ca_dvb_flag == 1) - flags |= CA_CI_MODULE_READY; - return flags; -} - -static int fdtv_ca_reset(struct firedtv *fdtv) -{ - return avc_ca_reset(fdtv) ? -EFAULT : 0; -} - -static int fdtv_ca_get_caps(void *arg) -{ - struct ca_caps *cap = arg; - - cap->slot_num = 1; - cap->slot_type = CA_CI; - cap->descr_num = 1; - cap->descr_type = CA_ECD; - return 0; -} - -static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg) -{ - struct firedtv_tuner_status stat; - struct ca_slot_info *slot = arg; - - if (avc_tuner_status(fdtv, &stat)) - return -EFAULT; - - if (slot->num != 0) - return -EFAULT; - - slot->type = CA_CI; - slot->flags = fdtv_get_ca_flags(&stat); - return 0; -} - -static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg) -{ - struct ca_msg *reply = arg; - - return avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; -} - -static int fdtv_ca_info(struct firedtv *fdtv, void *arg) -{ - struct ca_msg *reply = arg; - - return avc_ca_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; -} - -static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg) -{ - struct ca_msg *reply = arg; - - return avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; -} - -static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg) -{ - struct firedtv_tuner_status stat; - int err; - - switch (fdtv->ca_last_command) { - case EN50221_TAG_APP_INFO_ENQUIRY: - err = fdtv_ca_app_info(fdtv, arg); - break; - case EN50221_TAG_CA_INFO_ENQUIRY: - err = fdtv_ca_info(fdtv, arg); - break; - default: - if (avc_tuner_status(fdtv, &stat)) - err = -EFAULT; - else if (stat.ca_mmi == 1) - err = fdtv_ca_get_mmi(fdtv, arg); - else { - dev_info(fdtv->device, "unhandled CA message 0x%08x\n", - fdtv->ca_last_command); - err = -EFAULT; - } - } - fdtv->ca_last_command = 0; - return err; -} - -static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg) -{ - struct ca_msg *msg = arg; - int data_pos; - int data_length; - int i; - - data_pos = 4; - if (msg->msg[3] & 0x80) { - data_length = 0; - for (i = 0; i < (msg->msg[3] & 0x7f); i++) - data_length = (data_length << 8) + msg->msg[data_pos++]; - } else { - data_length = msg->msg[3]; - } - - return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? -EFAULT : 0; -} - -static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) -{ - struct ca_msg *msg = arg; - int err; - - /* Do we need a semaphore for this? */ - fdtv->ca_last_command = - (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2]; - switch (fdtv->ca_last_command) { - case EN50221_TAG_CA_PMT: - err = fdtv_ca_pmt(fdtv, arg); - break; - case EN50221_TAG_APP_INFO_ENQUIRY: - /* handled in ca_get_msg */ - err = 0; - break; - case EN50221_TAG_CA_INFO_ENQUIRY: - /* handled in ca_get_msg */ - err = 0; - break; - case EN50221_TAG_ENTER_MENU: - err = avc_ca_enter_menu(fdtv); - break; - default: - dev_err(fdtv->device, "unhandled CA message 0x%08x\n", - fdtv->ca_last_command); - err = -EFAULT; - } - return err; -} - -static int fdtv_ca_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct dvb_device *dvbdev = file->private_data; - struct firedtv *fdtv = dvbdev->priv; - struct firedtv_tuner_status stat; - int err; - - switch (cmd) { - case CA_RESET: - err = fdtv_ca_reset(fdtv); - break; - case CA_GET_CAP: - err = fdtv_ca_get_caps(arg); - break; - case CA_GET_SLOT_INFO: - err = fdtv_ca_get_slot_info(fdtv, arg); - break; - case CA_GET_MSG: - err = fdtv_ca_get_msg(fdtv, arg); - break; - case CA_SEND_MSG: - err = fdtv_ca_send_msg(fdtv, arg); - break; - default: - dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd); - err = -EOPNOTSUPP; - } - - /* FIXME Is this necessary? */ - avc_tuner_status(fdtv, &stat); - - return err; -} - -static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait) -{ - return POLLIN; -} - -static struct file_operations fdtv_ca_fops = { - .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, - .open = dvb_generic_open, - .release = dvb_generic_release, - .poll = fdtv_ca_io_poll, -}; - -static struct dvb_device fdtv_ca = { - .users = 1, - .readers = 1, - .writers = 1, - .fops = &fdtv_ca_fops, - .kernel_ioctl = fdtv_ca_ioctl, -}; - -int fdtv_ca_register(struct firedtv *fdtv) -{ - struct firedtv_tuner_status stat; - int err; - - if (avc_tuner_status(fdtv, &stat)) - return -EINVAL; - - if (!fdtv_ca_ready(&stat)) - return -EFAULT; - - err = dvb_register_device(&fdtv->adapter, &fdtv->cadev, - &fdtv_ca, fdtv, DVB_DEVICE_CA); - - if (stat.ca_application_info == 0) - dev_err(fdtv->device, "CaApplicationInfo is not set\n"); - if (stat.ca_date_time_request == 1) - avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval); - - return err; -} - -void fdtv_ca_release(struct firedtv *fdtv) -{ - if (fdtv->cadev) - dvb_unregister_device(fdtv->cadev); -} diff --git a/trunk/drivers/media/dvb/firewire/firedtv-dvb.c b/trunk/drivers/media/dvb/firewire/firedtv-dvb.c deleted file mode 100644 index 9d308dd32a5c..000000000000 --- a/trunk/drivers/media/dvb/firewire/firedtv-dvb.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Henrik Kurelid - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "firedtv.h" - -static int alloc_channel(struct firedtv *fdtv) -{ - int i; - - for (i = 0; i < 16; i++) - if (!__test_and_set_bit(i, &fdtv->channel_active)) - break; - return i; -} - -static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[]) -{ - int i, n; - - for (i = 0, n = 0; i < 16; i++) - if (test_bit(i, &fdtv->channel_active)) - pid[n++] = fdtv->channel_pid[i]; - *pidc = n; -} - -static inline void dealloc_channel(struct firedtv *fdtv, int i) -{ - __clear_bit(i, &fdtv->channel_active); -} - -int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct firedtv *fdtv = dvbdmxfeed->demux->priv; - int pidc, c, ret; - u16 pids[16]; - - switch (dvbdmxfeed->type) { - case DMX_TYPE_TS: - case DMX_TYPE_SEC: - break; - default: - dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n", - dvbdmxfeed->type); - return -EINVAL; - } - - if (mutex_lock_interruptible(&fdtv->demux_mutex)) - return -EINTR; - - if (dvbdmxfeed->type == DMX_TYPE_TS) { - switch (dvbdmxfeed->pes_type) { - case DMX_TS_PES_VIDEO: - case DMX_TS_PES_AUDIO: - case DMX_TS_PES_TELETEXT: - case DMX_TS_PES_PCR: - case DMX_TS_PES_OTHER: - c = alloc_channel(fdtv); - break; - default: - dev_err(fdtv->device, - "can't start dmx feed: invalid pes type %u\n", - dvbdmxfeed->pes_type); - ret = -EINVAL; - goto out; - } - } else { - c = alloc_channel(fdtv); - } - - if (c > 15) { - dev_err(fdtv->device, "can't start dmx feed: busy\n"); - ret = -EBUSY; - goto out; - } - - dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c; - fdtv->channel_pid[c] = dvbdmxfeed->pid; - collect_channels(fdtv, &pidc, pids); - - if (dvbdmxfeed->pid == 8192) { - ret = avc_tuner_get_ts(fdtv); - if (ret) { - dealloc_channel(fdtv, c); - dev_err(fdtv->device, "can't get TS\n"); - goto out; - } - } else { - ret = avc_tuner_set_pids(fdtv, pidc, pids); - if (ret) { - dealloc_channel(fdtv, c); - dev_err(fdtv->device, "can't set PIDs\n"); - goto out; - } - } -out: - mutex_unlock(&fdtv->demux_mutex); - - return ret; -} - -int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux *demux = dvbdmxfeed->demux; - struct firedtv *fdtv = demux->priv; - int pidc, c, ret; - u16 pids[16]; - - if (dvbdmxfeed->type == DMX_TYPE_TS && - !((dvbdmxfeed->ts_type & TS_PACKET) && - (demux->dmx.frontend->source != DMX_MEMORY_FE))) { - - if (dvbdmxfeed->ts_type & TS_DECODER) { - if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER || - !demux->pesfilter[dvbdmxfeed->pes_type]) - return -EINVAL; - - demux->pids[dvbdmxfeed->pes_type] |= 0x8000; - demux->pesfilter[dvbdmxfeed->pes_type] = NULL; - } - - if (!(dvbdmxfeed->ts_type & TS_DECODER && - dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) - return 0; - } - - if (mutex_lock_interruptible(&fdtv->demux_mutex)) - return -EINTR; - - c = (unsigned long)dvbdmxfeed->priv; - dealloc_channel(fdtv, c); - collect_channels(fdtv, &pidc, pids); - - ret = avc_tuner_set_pids(fdtv, pidc, pids); - - mutex_unlock(&fdtv->demux_mutex); - - return ret; -} - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -int fdtv_dvb_register(struct firedtv *fdtv) -{ - int err; - - err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type], - THIS_MODULE, fdtv->device, adapter_nr); - if (err < 0) - goto fail_log; - - /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/ - fdtv->demux.dmx.capabilities = 0; - - fdtv->demux.priv = fdtv; - fdtv->demux.filternum = 16; - fdtv->demux.feednum = 16; - fdtv->demux.start_feed = fdtv_start_feed; - fdtv->demux.stop_feed = fdtv_stop_feed; - fdtv->demux.write_to_decoder = NULL; - - err = dvb_dmx_init(&fdtv->demux); - if (err) - goto fail_unreg_adapter; - - fdtv->dmxdev.filternum = 16; - fdtv->dmxdev.demux = &fdtv->demux.dmx; - fdtv->dmxdev.capabilities = 0; - - err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter); - if (err) - goto fail_dmx_release; - - fdtv->frontend.source = DMX_FRONTEND_0; - - err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend); - if (err) - goto fail_dmxdev_release; - - err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx, - &fdtv->frontend); - if (err) - goto fail_rem_frontend; - - dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx); - - fdtv_frontend_init(fdtv); - err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe); - if (err) - goto fail_net_release; - - err = fdtv_ca_register(fdtv); - if (err) - dev_info(fdtv->device, - "Conditional Access Module not enabled\n"); - return 0; - -fail_net_release: - dvb_net_release(&fdtv->dvbnet); - fdtv->demux.dmx.close(&fdtv->demux.dmx); -fail_rem_frontend: - fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend); -fail_dmxdev_release: - dvb_dmxdev_release(&fdtv->dmxdev); -fail_dmx_release: - dvb_dmx_release(&fdtv->demux); -fail_unreg_adapter: - dvb_unregister_adapter(&fdtv->adapter); -fail_log: - dev_err(fdtv->device, "DVB initialization failed\n"); - return err; -} - -void fdtv_dvb_unregister(struct firedtv *fdtv) -{ - fdtv_ca_release(fdtv); - dvb_unregister_frontend(&fdtv->fe); - dvb_net_release(&fdtv->dvbnet); - fdtv->demux.dmx.close(&fdtv->demux.dmx); - fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend); - dvb_dmxdev_release(&fdtv->dmxdev); - dvb_dmx_release(&fdtv->demux); - dvb_unregister_adapter(&fdtv->adapter); -} - -const char *fdtv_model_names[] = { - [FIREDTV_UNKNOWN] = "unknown type", - [FIREDTV_DVB_S] = "FireDTV S/CI", - [FIREDTV_DVB_C] = "FireDTV C/CI", - [FIREDTV_DVB_T] = "FireDTV T/CI", - [FIREDTV_DVB_S2] = "FireDTV S2 ", -}; - -struct firedtv *fdtv_alloc(struct device *dev, - const struct firedtv_backend *backend, - const char *name, size_t name_len) -{ - struct firedtv *fdtv; - int i; - - fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL); - if (!fdtv) - return NULL; - - dev->driver_data = fdtv; - fdtv->device = dev; - fdtv->isochannel = -1; - fdtv->voltage = 0xff; - fdtv->tone = 0xff; - fdtv->backend = backend; - - mutex_init(&fdtv->avc_mutex); - init_waitqueue_head(&fdtv->avc_wait); - fdtv->avc_reply_received = true; - mutex_init(&fdtv->demux_mutex); - INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); - - for (i = ARRAY_SIZE(fdtv_model_names); --i; ) - if (strlen(fdtv_model_names[i]) <= name_len && - strncmp(name, fdtv_model_names[i], name_len) == 0) - break; - fdtv->type = i; - - return fdtv; -} - -#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ - IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION) - -#define DIGITAL_EVERYWHERE_OUI 0x001287 -#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d -#define AVC_SW_VERSION_ENTRY 0x010001 - -static struct ieee1394_device_id fdtv_id_table[] = { - { - /* FloppyDTV S/CI and FloppyDTV S2 */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000024, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - }, { - /* FloppyDTV T/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000025, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - }, { - /* FloppyDTV C/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000026, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - }, { - /* FireDTV S/CI and FloppyDTV S2 */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000034, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - }, { - /* FireDTV T/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000035, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - }, { - /* FireDTV C/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000036, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - }, {} -}; -MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table); - -static int __init fdtv_init(void) -{ - return fdtv_1394_init(fdtv_id_table); -} - -static void __exit fdtv_exit(void) -{ - fdtv_1394_exit(); -} - -module_init(fdtv_init); -module_exit(fdtv_exit); - -MODULE_AUTHOR("Andreas Monitzer "); -MODULE_AUTHOR("Ben Backx "); -MODULE_DESCRIPTION("FireDTV DVB Driver"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("FireDTV DVB"); diff --git a/trunk/drivers/media/dvb/firewire/firedtv-fe.c b/trunk/drivers/media/dvb/firewire/firedtv-fe.c deleted file mode 100644 index 7ba43630a25d..000000000000 --- a/trunk/drivers/media/dvb/firewire/firedtv-fe.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Henrik Kurelid - * - * 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. - */ - -#include -#include -#include -#include -#include - -#include - -#include "firedtv.h" - -static int fdtv_dvb_init(struct dvb_frontend *fe) -{ - struct firedtv *fdtv = fe->sec_priv; - int err; - - /* FIXME - allocate free channel at IRM */ - fdtv->isochannel = fdtv->adapter.num; - - err = cmp_establish_pp_connection(fdtv, fdtv->subunit, - fdtv->isochannel); - if (err) { - dev_err(fdtv->device, - "could not establish point to point connection\n"); - return err; - } - - return fdtv->backend->start_iso(fdtv); -} - -static int fdtv_sleep(struct dvb_frontend *fe) -{ - struct firedtv *fdtv = fe->sec_priv; - - fdtv->backend->stop_iso(fdtv); - cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel); - fdtv->isochannel = -1; - return 0; -} - -#define LNBCONTROL_DONTCARE 0xff - -static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *cmd) -{ - struct firedtv *fdtv = fe->sec_priv; - - return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, - LNBCONTROL_DONTCARE, 1, cmd); -} - -static int fdtv_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t minicmd) -{ - return 0; -} - -static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct firedtv *fdtv = fe->sec_priv; - - fdtv->tone = tone; - return 0; -} - -static int fdtv_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) -{ - struct firedtv *fdtv = fe->sec_priv; - - fdtv->voltage = voltage; - return 0; -} - -static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct firedtv *fdtv = fe->sec_priv; - struct firedtv_tuner_status stat; - - if (avc_tuner_status(fdtv, &stat)) - return -EINVAL; - - if (stat.no_rf) - *status = 0; - else - *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC | - FE_HAS_CARRIER | FE_HAS_LOCK; - return 0; -} - -static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct firedtv *fdtv = fe->sec_priv; - struct firedtv_tuner_status stat; - - if (avc_tuner_status(fdtv, &stat)) - return -EINVAL; - - *ber = stat.ber; - return 0; -} - -static int fdtv_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct firedtv *fdtv = fe->sec_priv; - struct firedtv_tuner_status stat; - - if (avc_tuner_status(fdtv, &stat)) - return -EINVAL; - - *strength = stat.signal_strength << 8; - return 0; -} - -static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct firedtv *fdtv = fe->sec_priv; - struct firedtv_tuner_status stat; - - if (avc_tuner_status(fdtv, &stat)) - return -EINVAL; - - /* C/N[dB] = -10 * log10(snr / 65535) */ - *snr = stat.carrier_noise_ratio * 257; - return 0; -} - -static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - return -EOPNOTSUPP; -} - -#define ACCEPTED 0x9 - -static int fdtv_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct firedtv *fdtv = fe->sec_priv; - - /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */ - if (avc_tuner_dsd(fdtv, params) != ACCEPTED) - return -EINVAL; - else - return 0; /* not sure of this... */ -} - -static int fdtv_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - return -EOPNOTSUPP; -} - -void fdtv_frontend_init(struct firedtv *fdtv) -{ - struct dvb_frontend_ops *ops = &fdtv->fe.ops; - struct dvb_frontend_info *fi = &ops->info; - - ops->init = fdtv_dvb_init; - ops->sleep = fdtv_sleep; - - ops->set_frontend = fdtv_set_frontend; - ops->get_frontend = fdtv_get_frontend; - - ops->read_status = fdtv_read_status; - ops->read_ber = fdtv_read_ber; - ops->read_signal_strength = fdtv_read_signal_strength; - ops->read_snr = fdtv_read_snr; - ops->read_ucblocks = fdtv_read_uncorrected_blocks; - - ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd; - ops->diseqc_send_burst = fdtv_diseqc_send_burst; - ops->set_tone = fdtv_set_tone; - ops->set_voltage = fdtv_set_voltage; - - switch (fdtv->type) { - case FIREDTV_DVB_S: - case FIREDTV_DVB_S2: - fi->type = FE_QPSK; - - fi->frequency_min = 950000; - fi->frequency_max = 2150000; - fi->frequency_stepsize = 125; - fi->symbol_rate_min = 1000000; - fi->symbol_rate_max = 40000000; - - fi->caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | - FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | - FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK; - break; - - case FIREDTV_DVB_C: - fi->type = FE_QAM; - - fi->frequency_min = 47000000; - fi->frequency_max = 866000000; - fi->frequency_stepsize = 62500; - fi->symbol_rate_min = 870000; - fi->symbol_rate_max = 6900000; - - fi->caps = FE_CAN_INVERSION_AUTO | - FE_CAN_QAM_16 | - FE_CAN_QAM_32 | - FE_CAN_QAM_64 | - FE_CAN_QAM_128 | - FE_CAN_QAM_256 | - FE_CAN_QAM_AUTO; - break; - - case FIREDTV_DVB_T: - fi->type = FE_OFDM; - - fi->frequency_min = 49000000; - fi->frequency_max = 861000000; - fi->frequency_stepsize = 62500; - - fi->caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_2_3 | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO; - break; - - default: - dev_err(fdtv->device, "no frontend for model type %d\n", - fdtv->type); - } - strcpy(fi->name, fdtv_model_names[fdtv->type]); - - fdtv->fe.dvb = &fdtv->adapter; - fdtv->fe.sec_priv = fdtv; -} diff --git a/trunk/drivers/media/dvb/firewire/firedtv-rc.c b/trunk/drivers/media/dvb/firewire/firedtv-rc.c deleted file mode 100644 index 46a6324d7b73..000000000000 --- a/trunk/drivers/media/dvb/firewire/firedtv-rc.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * - * 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. - */ - -#include -#include -#include -#include -#include - -#include "firedtv.h" - -/* fixed table with older keycodes, geared towards MythTV */ -const static u16 oldtable[] = { - - /* code from device: 0x4501...0x451f */ - - KEY_ESC, - KEY_F9, - KEY_1, - KEY_2, - KEY_3, - KEY_4, - KEY_5, - KEY_6, - KEY_7, - KEY_8, - KEY_9, - KEY_I, - KEY_0, - KEY_ENTER, - KEY_RED, - KEY_UP, - KEY_GREEN, - KEY_F10, - KEY_SPACE, - KEY_F11, - KEY_YELLOW, - KEY_DOWN, - KEY_BLUE, - KEY_Z, - KEY_P, - KEY_PAGEDOWN, - KEY_LEFT, - KEY_W, - KEY_RIGHT, - KEY_P, - KEY_M, - - /* code from device: 0x4540...0x4542 */ - - KEY_R, - KEY_V, - KEY_C, -}; - -/* user-modifiable table for a remote as sold in 2008 */ -const static u16 keytable[] = { - - /* code from device: 0x0300...0x031f */ - - [0x00] = KEY_POWER, - [0x01] = KEY_SLEEP, - [0x02] = KEY_STOP, - [0x03] = KEY_OK, - [0x04] = KEY_RIGHT, - [0x05] = KEY_1, - [0x06] = KEY_2, - [0x07] = KEY_3, - [0x08] = KEY_LEFT, - [0x09] = KEY_4, - [0x0a] = KEY_5, - [0x0b] = KEY_6, - [0x0c] = KEY_UP, - [0x0d] = KEY_7, - [0x0e] = KEY_8, - [0x0f] = KEY_9, - [0x10] = KEY_DOWN, - [0x11] = KEY_TITLE, /* "OSD" - fixme */ - [0x12] = KEY_0, - [0x13] = KEY_F20, /* "16:9" - fixme */ - [0x14] = KEY_SCREEN, /* "FULL" - fixme */ - [0x15] = KEY_MUTE, - [0x16] = KEY_SUBTITLE, - [0x17] = KEY_RECORD, - [0x18] = KEY_TEXT, - [0x19] = KEY_AUDIO, - [0x1a] = KEY_RED, - [0x1b] = KEY_PREVIOUS, - [0x1c] = KEY_REWIND, - [0x1d] = KEY_PLAYPAUSE, - [0x1e] = KEY_NEXT, - [0x1f] = KEY_VOLUMEUP, - - /* code from device: 0x0340...0x0354 */ - - [0x20] = KEY_CHANNELUP, - [0x21] = KEY_F21, /* "4:3" - fixme */ - [0x22] = KEY_TV, - [0x23] = KEY_DVD, - [0x24] = KEY_VCR, - [0x25] = KEY_AUX, - [0x26] = KEY_GREEN, - [0x27] = KEY_YELLOW, - [0x28] = KEY_BLUE, - [0x29] = KEY_CHANNEL, /* "CH.LIST" */ - [0x2a] = KEY_VENDOR, /* "CI" - fixme */ - [0x2b] = KEY_VOLUMEDOWN, - [0x2c] = KEY_CHANNELDOWN, - [0x2d] = KEY_LAST, - [0x2e] = KEY_INFO, - [0x2f] = KEY_FORWARD, - [0x30] = KEY_LIST, - [0x31] = KEY_FAVORITES, - [0x32] = KEY_MENU, - [0x33] = KEY_EPG, - [0x34] = KEY_EXIT, -}; - -int fdtv_register_rc(struct firedtv *fdtv, struct device *dev) -{ - struct input_dev *idev; - int i, err; - - idev = input_allocate_device(); - if (!idev) - return -ENOMEM; - - fdtv->remote_ctrl_dev = idev; - idev->name = "FireDTV remote control"; - idev->dev.parent = dev; - idev->evbit[0] = BIT_MASK(EV_KEY); - idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL); - if (!idev->keycode) { - err = -ENOMEM; - goto fail; - } - idev->keycodesize = sizeof(keytable[0]); - idev->keycodemax = ARRAY_SIZE(keytable); - - for (i = 0; i < ARRAY_SIZE(keytable); i++) - set_bit(keytable[i], idev->keybit); - - err = input_register_device(idev); - if (err) - goto fail_free_keymap; - - return 0; - -fail_free_keymap: - kfree(idev->keycode); -fail: - input_free_device(idev); - return err; -} - -void fdtv_unregister_rc(struct firedtv *fdtv) -{ - kfree(fdtv->remote_ctrl_dev->keycode); - input_unregister_device(fdtv->remote_ctrl_dev); -} - -void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) -{ - u16 *keycode = fdtv->remote_ctrl_dev->keycode; - - if (code >= 0x0300 && code <= 0x031f) - code = keycode[code - 0x0300]; - else if (code >= 0x0340 && code <= 0x0354) - code = keycode[code - 0x0320]; - else if (code >= 0x4501 && code <= 0x451f) - code = oldtable[code - 0x4501]; - else if (code >= 0x4540 && code <= 0x4542) - code = oldtable[code - 0x4521]; - else { - printk(KERN_DEBUG "firedtv: invalid key code 0x%04x " - "from remote control\n", code); - return; - } - - input_report_key(fdtv->remote_ctrl_dev, code, 1); - input_report_key(fdtv->remote_ctrl_dev, code, 0); -} diff --git a/trunk/drivers/media/dvb/firewire/firedtv.h b/trunk/drivers/media/dvb/firewire/firedtv.h deleted file mode 100644 index d48530b81e61..000000000000 --- a/trunk/drivers/media/dvb/firewire/firedtv.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Henrik Kurelid - * - * 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. - */ - -#ifndef _FIREDTV_H -#define _FIREDTV_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -struct firedtv_tuner_status { - unsigned active_system:8; - unsigned searching:1; - unsigned moving:1; - unsigned no_rf:1; - unsigned input:1; - unsigned selected_antenna:7; - unsigned ber:32; - unsigned signal_strength:8; - unsigned raster_frequency:2; - unsigned rf_frequency:22; - unsigned man_dep_info_length:8; - unsigned front_end_error:1; - unsigned antenna_error:1; - unsigned front_end_power_status:1; - unsigned power_supply:1; - unsigned carrier_noise_ratio:16; - unsigned power_supply_voltage:8; - unsigned antenna_voltage:8; - unsigned firewire_bus_voltage:8; - unsigned ca_mmi:1; - unsigned ca_pmt_reply:1; - unsigned ca_date_time_request:1; - unsigned ca_application_info:1; - unsigned ca_module_present_status:1; - unsigned ca_dvb_flag:1; - unsigned ca_error_flag:1; - unsigned ca_initialization_status:1; -}; - -enum model_type { - FIREDTV_UNKNOWN = 0, - FIREDTV_DVB_S = 1, - FIREDTV_DVB_C = 2, - FIREDTV_DVB_T = 3, - FIREDTV_DVB_S2 = 4, -}; - -struct device; -struct input_dev; -struct firedtv; - -struct firedtv_backend { - int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg); - int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len); - int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); - int (*start_iso)(struct firedtv *fdtv); - void (*stop_iso)(struct firedtv *fdtv); -}; - -struct firedtv { - struct device *device; - struct list_head list; - - struct dvb_adapter adapter; - struct dmxdev dmxdev; - struct dvb_demux demux; - struct dmx_frontend frontend; - struct dvb_net dvbnet; - struct dvb_frontend fe; - - struct dvb_device *cadev; - int ca_last_command; - int ca_time_interval; - - struct mutex avc_mutex; - wait_queue_head_t avc_wait; - bool avc_reply_received; - struct work_struct remote_ctrl_work; - struct input_dev *remote_ctrl_dev; - - enum model_type type; - char subunit; - char isochannel; - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t tone; - - const struct firedtv_backend *backend; - void *backend_data; - - struct mutex demux_mutex; - unsigned long channel_active; - u16 channel_pid[16]; - - size_t response_length; - u8 response[512]; -}; - -/* firedtv-1394.c */ -#ifdef CONFIG_DVB_FIREDTV_IEEE1394 -int fdtv_1394_init(struct ieee1394_device_id id_table[]); -void fdtv_1394_exit(void); -#else -static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; } -static inline void fdtv_1394_exit(void) {} -#endif - -/* firedtv-avc.c */ -int avc_recv(struct firedtv *fdtv, void *data, size_t length); -int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat); -struct dvb_frontend_parameters; -int avc_tuner_dsd(struct firedtv *fdtv, struct dvb_frontend_parameters *params); -int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]); -int avc_tuner_get_ts(struct firedtv *fdtv); -int avc_identify_subunit(struct firedtv *fdtv); -struct dvb_diseqc_master_cmd; -int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, - char conttone, char nrdiseq, - struct dvb_diseqc_master_cmd *diseqcmd); -void avc_remote_ctrl_work(struct work_struct *work); -int avc_register_remote_control(struct firedtv *fdtv); -int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len); -int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len); -int avc_ca_reset(struct firedtv *fdtv); -int avc_ca_pmt(struct firedtv *fdtv, char *app_info, int length); -int avc_ca_get_time_date(struct firedtv *fdtv, int *interval); -int avc_ca_enter_menu(struct firedtv *fdtv); -int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len); -int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel); -void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel); - -/* firedtv-ci.c */ -int fdtv_ca_register(struct firedtv *fdtv); -void fdtv_ca_release(struct firedtv *fdtv); - -/* firedtv-dvb.c */ -int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed); -int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed); -int fdtv_dvb_register(struct firedtv *fdtv); -void fdtv_dvb_unregister(struct firedtv *fdtv); -struct firedtv *fdtv_alloc(struct device *dev, - const struct firedtv_backend *backend, - const char *name, size_t name_len); -extern const char *fdtv_model_names[]; - -/* firedtv-fe.c */ -void fdtv_frontend_init(struct firedtv *fdtv); - -/* firedtv-rc.c */ -#ifdef CONFIG_DVB_FIREDTV_INPUT -int fdtv_register_rc(struct firedtv *fdtv, struct device *dev); -void fdtv_unregister_rc(struct firedtv *fdtv); -void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code); -#else -static inline int fdtv_register_rc(struct firedtv *fdtv, - struct device *dev) { return 0; } -static inline void fdtv_unregister_rc(struct firedtv *fdtv) {} -static inline void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) {} -#endif - -#endif /* _FIREDTV_H */ diff --git a/trunk/drivers/media/radio/radio-si470x.c b/trunk/drivers/media/radio/radio-si470x.c index 4dfed6aa2dbc..67cbce82cb91 100644 --- a/trunk/drivers/media/radio/radio-si470x.c +++ b/trunk/drivers/media/radio/radio-si470x.c @@ -98,16 +98,11 @@ * - blacklisted KWorld radio in hid-core.c and hid-ids.h * 2008-12-03 Mark Lord * - add support for DealExtreme USB Radio - * 2009-01-31 Bob Ross - * - correction of stereo detection/setting - * - correction of signal strength indicator scaling - * 2009-01-31 Rick Bronson - * Tobias Lorenz - * - add LED status output * * ToDo: * - add firmware download/update support * - RDS support: interrupt mode, instead of polling + * - add LED status output (check if that's not already done in firmware) */ @@ -886,30 +881,6 @@ static int si470x_rds_on(struct si470x_device *radio) -/************************************************************************** - * General Driver Functions - LED_REPORT - **************************************************************************/ - -/* - * si470x_set_led_state - sets the led state - */ -static int si470x_set_led_state(struct si470x_device *radio, - unsigned char led_state) -{ - unsigned char buf[LED_REPORT_SIZE]; - int retval; - - buf[0] = LED_REPORT; - buf[1] = LED_COMMAND; - buf[2] = led_state; - - retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); - - return (retval < 0) ? -EINVAL : 0; -} - - - /************************************************************************** * RDS Driver Functions **************************************************************************/ @@ -1414,22 +1385,20 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, }; /* stereo indicator == stereo (instead of mono) */ - if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0) - tuner->rxsubchans = V4L2_TUNER_SUB_MONO; - else + if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1) tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; + else + tuner->rxsubchans = V4L2_TUNER_SUB_MONO; /* mono/stereo selector */ - if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0) - tuner->audmode = V4L2_TUNER_MODE_STEREO; - else + if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1) tuner->audmode = V4L2_TUNER_MODE_MONO; + else + tuner->audmode = V4L2_TUNER_MODE_STEREO; /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */ - /* measured in units of dbµV in 1 db increments (max at ~75 dbµV) */ - tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI); - /* the ideal factor is 0xffff/75 = 873,8 */ - tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10); + tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI) + * 0x0101; /* automatic frequency control: -1: freq to low, 1 freq to high */ /* AFCRL does only indicate that freq. differs, not if too low/high */ @@ -1663,9 +1632,6 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, /* set initial frequency */ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ - /* set led to connect state */ - si470x_set_led_state(radio, BLINK_GREEN_LED); - /* rds buffer allocation */ radio->buf_size = rds_buf * 3; radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); @@ -1749,9 +1715,6 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) cancel_delayed_work_sync(&radio->work); usb_set_intfdata(intf, NULL); if (radio->users == 0) { - /* set led to disconnect state */ - si470x_set_led_state(radio, BLINK_ORANGE_LED); - video_unregister_device(radio->videodev); kfree(radio->buffer); kfree(radio); diff --git a/trunk/drivers/media/video/em28xx/em28xx-audio.c b/trunk/drivers/media/video/em28xx/em28xx-audio.c index 2ac738fa6a07..5d882a44e3ee 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-audio.c +++ b/trunk/drivers/media/video/em28xx/em28xx-audio.c @@ -463,8 +463,6 @@ static int em28xx_audio_init(struct em28xx *dev) pcm->info_flags = 0; pcm->private_data = dev; strcpy(pcm->name, "Empia 28xx Capture"); - - snd_card_set_dev(card, &dev->udev->dev); strcpy(card->driver, "Empia Em28xx Audio"); strcpy(card->shortname, "Em28xx Audio"); strcpy(card->longname, "Empia Em28xx Audio"); diff --git a/trunk/drivers/media/video/gspca/gspca.c b/trunk/drivers/media/video/gspca/gspca.c index 65e4901f4db7..2ed24527ecd6 100644 --- a/trunk/drivers/media/video/gspca/gspca.c +++ b/trunk/drivers/media/video/gspca/gspca.c @@ -422,7 +422,6 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) if (urb == NULL) break; - BUG_ON(!gspca_dev->dev); gspca_dev->urb[i] = NULL; if (!gspca_dev->present) usb_kill_urb(urb); @@ -1951,12 +1950,8 @@ void gspca_disconnect(struct usb_interface *intf) { struct gspca_dev *gspca_dev = usb_get_intfdata(intf); - mutex_lock(&gspca_dev->usb_lock); gspca_dev->present = 0; - mutex_unlock(&gspca_dev->usb_lock); - destroy_urbs(gspca_dev); - gspca_dev->dev = NULL; usb_set_intfdata(intf, NULL); /* release the device */ diff --git a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c index c13bd2aa0bea..f6b3ef6e691b 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c @@ -393,7 +393,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo return 0; } - v4l2_subdev_call(itv->sd_video, video, g_fmt, fmt); + v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); vbifmt->service_set = ivtv_get_service_set(vbifmt); return 0; } @@ -1748,18 +1748,6 @@ static long ivtv_default(struct file *file, void *fh, int cmd, void *arg) break; } - case IVTV_IOC_DMA_FRAME: - case VIDEO_GET_PTS: - case VIDEO_GET_FRAME_COUNT: - case VIDEO_GET_EVENT: - case VIDEO_PLAY: - case VIDEO_STOP: - case VIDEO_FREEZE: - case VIDEO_CONTINUE: - case VIDEO_COMMAND: - case VIDEO_TRY_COMMAND: - return ivtv_decoder_ioctls(file, cmd, (void *)arg); - default: return -EINVAL; } @@ -1802,6 +1790,18 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); return 0; + case IVTV_IOC_DMA_FRAME: + case VIDEO_GET_PTS: + case VIDEO_GET_FRAME_COUNT: + case VIDEO_GET_EVENT: + case VIDEO_PLAY: + case VIDEO_STOP: + case VIDEO_FREEZE: + case VIDEO_CONTINUE: + case VIDEO_COMMAND: + case VIDEO_TRY_COMMAND: + return ivtv_decoder_ioctls(filp, cmd, (void *)arg); + default: break; } diff --git a/trunk/drivers/media/video/pxa_camera.c b/trunk/drivers/media/video/pxa_camera.c index 07c334f25aae..a1d6008efcbb 100644 --- a/trunk/drivers/media/video/pxa_camera.c +++ b/trunk/drivers/media/video/pxa_camera.c @@ -1155,24 +1155,24 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct pxa_camera_dev *pcdev = ici->priv; - const struct soc_camera_data_format *cam_fmt = NULL; - const struct soc_camera_format_xlate *xlate = NULL; + const struct soc_camera_data_format *host_fmt, *cam_fmt = NULL; + const struct soc_camera_format_xlate *xlate; struct soc_camera_sense sense = { .master_clock = pcdev->mclk, .pixel_clock_max = pcdev->ciclk / 4, }; - int ret; - - if (pixfmt) { - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); - if (!xlate) { - dev_warn(&ici->dev, "Format %x not found\n", pixfmt); - return -EINVAL; - } + int ret, buswidth; - cam_fmt = xlate->cam_fmt; + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (!xlate) { + dev_warn(&ici->dev, "Format %x not found\n", pixfmt); + return -EINVAL; } + buswidth = xlate->buswidth; + host_fmt = xlate->host_fmt; + cam_fmt = xlate->cam_fmt; + /* If PCLK is used to latch data from the sensor, check sense */ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) icd->sense = &sense; @@ -1201,8 +1201,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, } if (pixfmt && !ret) { - icd->buswidth = xlate->buswidth; - icd->current_fmt = xlate->host_fmt; + icd->buswidth = buswidth; + icd->current_fmt = host_fmt; } return ret; diff --git a/trunk/drivers/media/video/sh_mobile_ceu_camera.c b/trunk/drivers/media/video/sh_mobile_ceu_camera.c index ddcb81d0b81a..9a2586b07a05 100644 --- a/trunk/drivers/media/video/sh_mobile_ceu_camera.c +++ b/trunk/drivers/media/video/sh_mobile_ceu_camera.c @@ -603,18 +603,21 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, const struct soc_camera_format_xlate *xlate; int ret; - if (!pixfmt) - return icd->ops->set_fmt(icd, pixfmt, rect); - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { dev_warn(&ici->dev, "Format %x not found\n", pixfmt); return -EINVAL; } - ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); + switch (pixfmt) { + case 0: /* Only geometry change */ + ret = icd->ops->set_fmt(icd, pixfmt, rect); + break; + default: + ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); + } - if (!ret) { + if (pixfmt && !ret) { icd->buswidth = xlate->buswidth; icd->current_fmt = xlate->host_fmt; pcdev->camera_fmt = xlate->cam_fmt; diff --git a/trunk/drivers/media/video/uvc/uvc_status.c b/trunk/drivers/media/video/uvc/uvc_status.c index c705f248da88..c1e4ae27c613 100644 --- a/trunk/drivers/media/video/uvc/uvc_status.c +++ b/trunk/drivers/media/video/uvc/uvc_status.c @@ -46,8 +46,8 @@ static int uvc_input_init(struct uvc_device *dev) usb_to_input_id(udev, &input->id); input->dev.parent = &dev->intf->dev; - __set_bit(EV_KEY, input->evbit); - __set_bit(KEY_CAMERA, input->keybit); + set_bit(EV_KEY, input->evbit); + set_bit(BTN_0, input->keybit); if ((ret = input_register_device(input)) < 0) goto error; @@ -70,10 +70,8 @@ static void uvc_input_cleanup(struct uvc_device *dev) static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, int value) { - if (dev->input) { + if (dev->input) input_report_key(dev->input, code, value); - input_sync(dev->input); - } } #else @@ -98,7 +96,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) return; uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", data[1], data[3] ? "pressed" : "released", len); - uvc_input_report_key(dev, KEY_CAMERA, data[3]); + uvc_input_report_key(dev, BTN_0, data[3]); } else { uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " "len %d.\n", data[1], data[2], data[3], len); diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c index ea3aafbbda44..96ac88317b8e 100644 --- a/trunk/drivers/message/fusion/mptbase.c +++ b/trunk/drivers/message/fusion/mptbase.c @@ -91,9 +91,9 @@ MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \ controllers (default=0)"); static int mpt_msi_enable_sas; -module_param(mpt_msi_enable_sas, int, 0); +module_param(mpt_msi_enable_sas, int, 1); MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \ - controllers (default=0)"); + controllers (default=1)"); static int mpt_channel_mapping; diff --git a/trunk/drivers/mfd/htc-egpio.c b/trunk/drivers/mfd/htc-egpio.c index aa266e1f69b2..1a4d04664d6d 100644 --- a/trunk/drivers/mfd/htc-egpio.c +++ b/trunk/drivers/mfd/htc-egpio.c @@ -286,7 +286,7 @@ static int __init egpio_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) goto fail; - ei->base_addr = ioremap_nocache(res->start, resource_size(res)); + ei->base_addr = ioremap_nocache(res->start, res->end - res->start); if (!ei->base_addr) goto fail; pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr); @@ -307,7 +307,7 @@ static int __init egpio_probe(struct platform_device *pdev) ei->nchips = pdata->num_chips; ei->chip = kzalloc(sizeof(struct egpio_chip) * ei->nchips, GFP_KERNEL); - if (!ei->chip) { + if (!ei) { ret = -ENOMEM; goto fail; } diff --git a/trunk/drivers/mfd/pcf50633-core.c b/trunk/drivers/mfd/pcf50633-core.c index 2e36057659e1..24508e28e3fb 100644 --- a/trunk/drivers/mfd/pcf50633-core.c +++ b/trunk/drivers/mfd/pcf50633-core.c @@ -626,6 +626,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client, } if (client->irq) { + set_irq_handler(client->irq, handle_level_irq); ret = request_irq(client->irq, pcf50633_irq, IRQF_TRIGGER_LOW, "pcf50633", pcf); @@ -678,7 +679,6 @@ static int __devexit pcf50633_remove(struct i2c_client *client) static struct i2c_device_id pcf50633_id_table[] = { {"pcf50633", 0x73}, - {/* end of list */} }; static struct i2c_driver pcf50633_driver = { diff --git a/trunk/drivers/mfd/sm501.c b/trunk/drivers/mfd/sm501.c index 4c7b7962f6b8..0e5761f12634 100644 --- a/trunk/drivers/mfd/sm501.c +++ b/trunk/drivers/mfd/sm501.c @@ -1050,7 +1050,7 @@ static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm, return gpiochip_add(gchip); } -static int __devinit sm501_register_gpio(struct sm501_devdata *sm) +static int sm501_register_gpio(struct sm501_devdata *sm) { struct sm501_gpio *gpio = &sm->gpio; resource_size_t iobase = sm->io_res->start + SM501_GPIO; @@ -1321,7 +1321,7 @@ static unsigned int sm501_mem_local[] = { * Common init code for an SM501 */ -static int __devinit sm501_init_dev(struct sm501_devdata *sm) +static int sm501_init_dev(struct sm501_devdata *sm) { struct sm501_initdata *idata; struct sm501_platdata *pdata; @@ -1397,7 +1397,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm) return 0; } -static int __devinit sm501_plat_probe(struct platform_device *dev) +static int sm501_plat_probe(struct platform_device *dev) { struct sm501_devdata *sm; int ret; @@ -1586,8 +1586,8 @@ static struct sm501_platdata sm501_pci_platdata = { .gpio_base = -1, }; -static int __devinit sm501_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) +static int sm501_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) { struct sm501_devdata *sm; int err; @@ -1693,7 +1693,7 @@ static void sm501_dev_remove(struct sm501_devdata *sm) sm501_gpio_remove(sm); } -static void __devexit sm501_pci_remove(struct pci_dev *dev) +static void sm501_pci_remove(struct pci_dev *dev) { struct sm501_devdata *sm = pci_get_drvdata(dev); @@ -1727,16 +1727,16 @@ static struct pci_device_id sm501_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, sm501_pci_tbl); -static struct pci_driver sm501_pci_driver = { +static struct pci_driver sm501_pci_drv = { .name = "sm501", .id_table = sm501_pci_tbl, .probe = sm501_pci_probe, - .remove = __devexit_p(sm501_pci_remove), + .remove = sm501_pci_remove, }; MODULE_ALIAS("platform:sm501"); -static struct platform_driver sm501_plat_driver = { +static struct platform_driver sm501_plat_drv = { .driver = { .name = "sm501", .owner = THIS_MODULE, @@ -1749,14 +1749,14 @@ static struct platform_driver sm501_plat_driver = { static int __init sm501_base_init(void) { - platform_driver_register(&sm501_plat_driver); - return pci_register_driver(&sm501_pci_driver); + platform_driver_register(&sm501_plat_drv); + return pci_register_driver(&sm501_pci_drv); } static void __exit sm501_base_exit(void) { - platform_driver_unregister(&sm501_plat_driver); - pci_unregister_driver(&sm501_pci_driver); + platform_driver_unregister(&sm501_plat_drv); + pci_unregister_driver(&sm501_pci_drv); } module_init(sm501_base_init); diff --git a/trunk/drivers/mfd/twl4030-core.c b/trunk/drivers/mfd/twl4030-core.c index 68826f1e36bc..e7ab0035d305 100644 --- a/trunk/drivers/mfd/twl4030-core.c +++ b/trunk/drivers/mfd/twl4030-core.c @@ -38,7 +38,7 @@ #include #include -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) +#ifdef CONFIG_ARM #include #endif diff --git a/trunk/drivers/mfd/wm8350-core.c b/trunk/drivers/mfd/wm8350-core.c index 84d5ea1ec171..f92595c8f165 100644 --- a/trunk/drivers/mfd/wm8350-core.c +++ b/trunk/drivers/mfd/wm8350-core.c @@ -1111,7 +1111,7 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) do { schedule_timeout_interruptible(1); reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); - } while (--tries && (reg & WM8350_AUXADC_POLL)); + } while (tries-- && (reg & WM8350_AUXADC_POLL)); if (!tries) dev_err(wm8350->dev, "adc chn %d read timeout\n", channel); @@ -1297,29 +1297,14 @@ static void wm8350_client_dev_register(struct wm8350 *wm8350, int wm8350_device_init(struct wm8350 *wm8350, int irq, struct wm8350_platform_data *pdata) { - int ret; + int ret = -EINVAL; u16 id1, id2, mask_rev; u16 cust_id, mode, chip_rev; /* get WM8350 revision and config mode */ - ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); - if (ret != 0) { - dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); - goto err; - } - - ret = wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2); - if (ret != 0) { - dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); - goto err; - } - - ret = wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), - &mask_rev); - if (ret != 0) { - dev_err(wm8350->dev, "Failed to read revision: %d\n", ret); - goto err; - } + wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); + wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2); + wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), &mask_rev); id1 = be16_to_cpu(id1); id2 = be16_to_cpu(id2); @@ -1419,12 +1404,14 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, return ret; } - wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF); - wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF); - wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF); - wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF); - wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF); - wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF); + if (pdata && pdata->init) { + ret = pdata->init(wm8350); + if (ret != 0) { + dev_err(wm8350->dev, "Platform init() failed: %d\n", + ret); + goto err; + } + } mutex_init(&wm8350->auxadc_mutex); mutex_init(&wm8350->irq_mutex); @@ -1443,15 +1430,6 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, } wm8350->chip_irq = irq; - if (pdata && pdata->init) { - ret = pdata->init(wm8350); - if (ret != 0) { - dev_err(wm8350->dev, "Platform init() failed: %d\n", - ret); - goto err; - } - } - wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0x0); wm8350_client_dev_register(wm8350, "wm8350-codec", diff --git a/trunk/drivers/mfd/wm8350-regmap.c b/trunk/drivers/mfd/wm8350-regmap.c index 9a4cc954cb7c..68887b817d17 100644 --- a/trunk/drivers/mfd/wm8350-regmap.c +++ b/trunk/drivers/mfd/wm8350-regmap.c @@ -3188,7 +3188,7 @@ const struct wm8350_reg_access wm8350_reg_io_map[] = { { 0x7CFF, 0x0C00, 0x7FFF }, /* R1 - ID */ { 0x0000, 0x0000, 0x0000 }, /* R2 */ { 0xBE3B, 0xBE3B, 0x8000 }, /* R3 - System Control 1 */ - { 0xFEF7, 0xFEF7, 0xF800 }, /* R4 - System Control 2 */ + { 0xFCF7, 0xFCF7, 0xF800 }, /* R4 - System Control 2 */ { 0x80FF, 0x80FF, 0x8000 }, /* R5 - System Hibernate */ { 0xFB0E, 0xFB0E, 0x0000 }, /* R6 - Interface Control */ { 0x0000, 0x0000, 0x0000 }, /* R7 */ diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index c64e6798878a..56073199ceba 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -217,7 +217,6 @@ config DELL_LAPTOP depends on EXPERIMENTAL depends on BACKLIGHT_CLASS_DEVICE depends on RFKILL - depends on POWER_SUPPLY default n ---help--- This driver adds support for rfkill and backlight control to Dell diff --git a/trunk/drivers/misc/atmel-ssc.c b/trunk/drivers/misc/atmel-ssc.c index 558bf3f2c276..bf5e4d065436 100644 --- a/trunk/drivers/misc/atmel-ssc.c +++ b/trunk/drivers/misc/atmel-ssc.c @@ -35,7 +35,7 @@ struct ssc_device *ssc_request(unsigned int ssc_num) if (!ssc_valid) { spin_unlock(&user_lock); - pr_err("ssc: ssc%d platform device is missing\n", ssc_num); + dev_dbg(&ssc->pdev->dev, "could not find requested device\n"); return ERR_PTR(-ENODEV); } diff --git a/trunk/drivers/misc/hpilo.c b/trunk/drivers/misc/hpilo.c index cf991850f01b..10c421b73eaf 100644 --- a/trunk/drivers/misc/hpilo.c +++ b/trunk/drivers/misc/hpilo.c @@ -207,7 +207,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) &device_ccb->recv_ctrl); /* give iLO some time to process stop request */ - for (retries = MAX_WAIT; retries > 0; retries--) { + for (retries = 1000; retries > 0; retries--) { doorbell_set(driver_ccb); udelay(1); if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A)) @@ -309,7 +309,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) doorbell_clr(driver_ccb); /* make sure iLO is really handling requests */ - for (i = MAX_WAIT; i > 0; i--) { + for (i = 1000; i > 0; i--) { if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL)) break; udelay(1); @@ -326,7 +326,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) return 0; free: - ilo_ccb_close(pdev, data); + pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa); out: return error; } @@ -710,7 +710,6 @@ static int __devinit ilo_probe(struct pci_dev *pdev, static struct pci_device_id ilo_devices[] = { { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) }, - { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3307) }, { } }; MODULE_DEVICE_TABLE(pci, ilo_devices); @@ -759,7 +758,7 @@ static void __exit ilo_exit(void) class_destroy(ilo_class); } -MODULE_VERSION("1.0"); +MODULE_VERSION("0.06"); MODULE_ALIAS(ILO_NAME); MODULE_DESCRIPTION(ILO_NAME); MODULE_AUTHOR("David Altobelli "); diff --git a/trunk/drivers/misc/hpilo.h b/trunk/drivers/misc/hpilo.h index b64a20ef07e3..a281207696c1 100644 --- a/trunk/drivers/misc/hpilo.h +++ b/trunk/drivers/misc/hpilo.h @@ -19,8 +19,6 @@ #define MAX_ILO_DEV 1 /* max number of files */ #define MAX_OPEN (MAX_CCB * MAX_ILO_DEV) -/* spin counter for open/close delay */ -#define MAX_WAIT 10000 /* * Per device, used to track global memory allocations. diff --git a/trunk/drivers/misc/sgi-xp/xpc.h b/trunk/drivers/misc/sgi-xp/xpc.h index 275b78896a73..a5bd658c2e83 100644 --- a/trunk/drivers/misc/sgi-xp/xpc.h +++ b/trunk/drivers/misc/sgi-xp/xpc.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. */ /* @@ -514,8 +514,7 @@ struct xpc_channel_uv { /* partition's notify mq */ struct xpc_send_msg_slot_uv *send_msg_slots; - void *recv_msg_slots; /* each slot will hold a xpc_notify_mq_msg_uv */ - /* structure plus the user's payload */ + struct xpc_notify_mq_msg_uv *recv_msg_slots; struct xpc_fifo_head_uv msg_slot_free_list; struct xpc_fifo_head_uv recv_msg_list; /* deliverable payloads */ diff --git a/trunk/drivers/misc/sgi-xp/xpc_uv.c b/trunk/drivers/misc/sgi-xp/xpc_uv.c index 29c0502a96b2..f17f7d40ea2c 100644 --- a/trunk/drivers/misc/sgi-xp/xpc_uv.c +++ b/trunk/drivers/misc/sgi-xp/xpc_uv.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. */ /* @@ -1010,8 +1010,8 @@ xpc_allocate_recv_msg_slot_uv(struct xpc_channel *ch) continue; for (entry = 0; entry < nentries; entry++) { - msg_slot = ch_uv->recv_msg_slots + - entry * ch->entry_size; + msg_slot = ch_uv->recv_msg_slots + entry * + ch->entry_size; msg_slot->hdr.msg_slot_number = entry; } @@ -1308,8 +1308,9 @@ xpc_handle_notify_mq_msg_uv(struct xpc_partition *part, /* we're dealing with a normal message sent via the notify_mq */ ch_uv = &ch->sn.uv; - msg_slot = ch_uv->recv_msg_slots + - (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size; + msg_slot = (struct xpc_notify_mq_msg_uv *)((u64)ch_uv->recv_msg_slots + + (msg->hdr.msg_slot_number % ch->remote_nentries) * + ch->entry_size); BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number); BUG_ON(msg_slot->hdr.size != 0); diff --git a/trunk/drivers/mmc/card/block.c b/trunk/drivers/mmc/card/block.c index 513eb09a638f..45b1f430685f 100644 --- a/trunk/drivers/mmc/card/block.c +++ b/trunk/drivers/mmc/card/block.c @@ -584,7 +584,7 @@ static int mmc_blk_probe(struct mmc_card *card) if (err) goto out; - string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2, + string_get_size(get_capacity(md->disk) << 9, STRING_UNITS_2, cap_str, sizeof(cap_str)); printk(KERN_INFO "%s: %s %s %s %s\n", md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), diff --git a/trunk/drivers/mmc/card/mmc_test.c b/trunk/drivers/mmc/card/mmc_test.c index b9f1e84897cc..b92b172074ee 100644 --- a/trunk/drivers/mmc/card/mmc_test.c +++ b/trunk/drivers/mmc/card/mmc_test.c @@ -494,7 +494,7 @@ static int mmc_test_basic_read(struct mmc_test_card *test) sg_init_one(&sg, test->buffer, 512); - ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 0); + ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1); if (ret) return ret; diff --git a/trunk/drivers/mmc/host/atmel-mci.c b/trunk/drivers/mmc/host/atmel-mci.c index 2b1196e6142c..76bfe16c09b1 100644 --- a/trunk/drivers/mmc/host/atmel-mci.c +++ b/trunk/drivers/mmc/host/atmel-mci.c @@ -1548,10 +1548,9 @@ static bool filter(struct dma_chan *chan, void *slave) { struct dw_dma_slave *dws = slave; - if (dws->dma_dev == chan->device->dev) { - chan->private = dws; + if (dws->dma_dev == chan->device->dev) return true; - } else + else return false; } #endif diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index a631c81dce12..db37490f67ec 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -55,7 +55,6 @@ #define VS30 (1 << 25) #define SDVS18 (0x5 << 9) #define SDVS30 (0x6 << 9) -#define SDVS33 (0x7 << 9) #define SDVSCLR 0xFFFFF1FF #define SDVSDET 0x00000400 #define AUTOIDLE 0x1 @@ -376,32 +375,6 @@ static void mmc_omap_report_irq(struct mmc_omap_host *host, u32 status) } #endif /* CONFIG_MMC_DEBUG */ -/* - * MMC controller internal state machines reset - * - * Used to reset command or data internal state machines, using respectively - * SRC or SRD bit of SYSCTL register - * Can be called from interrupt context - */ -static inline void mmc_omap_reset_controller_fsm(struct mmc_omap_host *host, - unsigned long bit) -{ - unsigned long i = 0; - unsigned long limit = (loops_per_jiffy * - msecs_to_jiffies(MMC_TIMEOUT_MS)); - - OMAP_HSMMC_WRITE(host->base, SYSCTL, - OMAP_HSMMC_READ(host->base, SYSCTL) | bit); - - while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) && - (i++ < limit)) - cpu_relax(); - - if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit) - dev_err(mmc_dev(host->mmc), - "Timeout waiting on controller reset in %s\n", - __func__); -} /* * MMC controller IRQ handler @@ -430,17 +403,21 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) (status & CMD_CRC)) { if (host->cmd) { if (status & CMD_TIMEOUT) { - mmc_omap_reset_controller_fsm(host, SRC); + OMAP_HSMMC_WRITE(host->base, SYSCTL, + OMAP_HSMMC_READ(host->base, + SYSCTL) | SRC); + while (OMAP_HSMMC_READ(host->base, + SYSCTL) & SRC) + ; + host->cmd->error = -ETIMEDOUT; } else { host->cmd->error = -EILSEQ; } end_cmd = 1; } - if (host->data) { + if (host->data) mmc_dma_cleanup(host); - mmc_omap_reset_controller_fsm(host, SRD); - } } if ((status & DATA_TIMEOUT) || (status & DATA_CRC)) { @@ -449,7 +426,12 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) mmc_dma_cleanup(host); else host->data->error = -EILSEQ; - mmc_omap_reset_controller_fsm(host, SRD); + OMAP_HSMMC_WRITE(host->base, SYSCTL, + OMAP_HSMMC_READ(host->base, + SYSCTL) | SRD); + while (OMAP_HSMMC_READ(host->base, + SYSCTL) & SRD) + ; end_trans = 1; } } @@ -474,20 +456,13 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } /* - * Switch MMC interface voltage ... only relevant for MMC1. - * - * MMC2 and MMC3 use fixed 1.8V levels, and maybe a transceiver. - * The MMC2 transceiver controls are used instead of DAT4..DAT7. - * Some chips, like eMMC ones, use internal transceivers. + * Switch MMC operating voltage */ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd) { u32 reg_val = 0; int ret; - if (host->id != OMAP_MMC1_DEVID) - return 0; - /* Disable the clocks */ clk_disable(host->fclk); clk_disable(host->iclk); @@ -510,26 +485,19 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd) OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR); reg_val = OMAP_HSMMC_READ(host->base, HCTL); - /* * If a MMC dual voltage card is detected, the set_ios fn calls * this fn with VDD bit set for 1.8V. Upon card removal from the * slot, omap_mmc_set_ios sets the VDD back to 3V on MMC_POWER_OFF. * - * Cope with a bit of slop in the range ... per data sheets: - * - "1.8V" for vdds_mmc1/vdds_mmc1a can be up to 2.45V max, - * but recommended values are 1.71V to 1.89V - * - "3.0V" for vdds_mmc1/vdds_mmc1a can be up to 3.5V max, - * but recommended values are 2.7V to 3.3V - * - * Board setup code shouldn't permit anything very out-of-range. - * TWL4030-family VMMC1 and VSIM regulators are fine (avoiding the - * middle range) but VSIM can't power DAT4..DAT7 at more than 3V. + * Only MMC1 supports 3.0V. MMC2 will not function if SDVS30 is + * set in HCTL. */ - if ((1 << vdd) <= MMC_VDD_23_24) - reg_val |= SDVS18; - else + if (host->id == OMAP_MMC1_DEVID && (((1 << vdd) == MMC_VDD_32_33) || + ((1 << vdd) == MMC_VDD_33_34))) reg_val |= SDVS30; + if ((1 << vdd) == MMC_VDD_165_195) + reg_val |= SDVS18; OMAP_HSMMC_WRITE(host->base, HCTL, reg_val); @@ -549,15 +517,16 @@ static void mmc_omap_detect(struct work_struct *work) { struct mmc_omap_host *host = container_of(work, struct mmc_omap_host, mmc_carddetect_work); - struct omap_mmc_slot_data *slot = &mmc_slot(host); - - host->carddetect = slot->card_detect(slot->card_detect_irq); sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); if (host->carddetect) { mmc_detect_change(host->mmc, (HZ * 200) / 1000); } else { - mmc_omap_reset_controller_fsm(host, SRD); + OMAP_HSMMC_WRITE(host->base, SYSCTL, + OMAP_HSMMC_READ(host->base, SYSCTL) | SRD); + while (OMAP_HSMMC_READ(host->base, SYSCTL) & SRD) + ; + mmc_detect_change(host->mmc, (HZ * 50) / 1000); } } @@ -569,6 +538,7 @@ static irqreturn_t omap_mmc_cd_handler(int irq, void *dev_id) { struct mmc_omap_host *host = (struct mmc_omap_host *)dev_id; + host->carddetect = mmc_slot(host).card_detect(irq); schedule_work(&host->mmc_carddetect_work); return IRQ_HANDLED; @@ -787,14 +757,10 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) case MMC_POWER_OFF: mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); /* - * Reset interface voltage to 3V if it's 1.8V now; - * only relevant on MMC-1, the others always use 1.8V. - * + * Reset bus voltage to 3V if it got set to 1.8V earlier. * REVISIT: If we are able to detect cards after unplugging * a 1.8V card, this code should not be needed. */ - if (host->id != OMAP_MMC1_DEVID) - break; if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) { int vdd = fls(host->mmc->ocr_avail) - 1; if (omap_mmc_switch_opcond(host, vdd) != 0) @@ -818,9 +784,7 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) } if (host->id == OMAP_MMC1_DEVID) { - /* Only MMC1 can interface at 3V without some flavor - * of external transceiver; but they all handle 1.8V. - */ + /* Only MMC1 can operate at 3V/1.8V */ if ((OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET) && (ios->vdd == DUAL_VOLT_OCR_BIT)) { /* @@ -1173,9 +1137,7 @@ static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state) " level suspend\n"); } - if (host->id == OMAP_MMC1_DEVID - && !(OMAP_HSMMC_READ(host->base, HCTL) - & SDVSDET)) { + if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) { OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR); diff --git a/trunk/drivers/mmc/host/s3cmci.c b/trunk/drivers/mmc/host/s3cmci.c index f4a67c65d301..35a98eec7414 100644 --- a/trunk/drivers/mmc/host/s3cmci.c +++ b/trunk/drivers/mmc/host/s3cmci.c @@ -329,7 +329,7 @@ static void do_pio_write(struct s3cmci_host *host) to_ptr = host->base + host->sdidata; - while ((fifo = fifo_free(host)) > 3) { + while ((fifo = fifo_free(host))) { if (!host->pio_bytes) { res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr); diff --git a/trunk/drivers/mmc/host/sdhci-pci.c b/trunk/drivers/mmc/host/sdhci-pci.c index 8cff5f5e7f86..f07255cb17ee 100644 --- a/trunk/drivers/mmc/host/sdhci-pci.c +++ b/trunk/drivers/mmc/host/sdhci-pci.c @@ -144,7 +144,8 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE | SDHCI_QUIRK_RESET_AFTER_REQUEST | - SDHCI_QUIRK_BROKEN_SMALL_PIO; + SDHCI_QUIRK_BROKEN_SMALL_PIO | + SDHCI_QUIRK_FORCE_HIGHSPEED; } /* diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index f52f3053ed92..6b2d1f99af67 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -1636,7 +1636,8 @@ int sdhci_add_host(struct sdhci_host *host) mmc->f_max = host->max_clk; mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; - if (caps & SDHCI_CAN_DO_HISPD) + if ((caps & SDHCI_CAN_DO_HISPD) || + (host->quirks & SDHCI_QUIRK_FORCE_HIGHSPEED)) mmc->caps |= MMC_CAP_SD_HIGHSPEED; mmc->ocr_avail = 0; @@ -1722,9 +1723,7 @@ int sdhci_add_host(struct sdhci_host *host) #endif #ifdef SDHCI_USE_LEDS_CLASS - snprintf(host->led_name, sizeof(host->led_name), - "%s::", mmc_hostname(mmc)); - host->led.name = host->led_name; + host->led.name = mmc_hostname(mmc); host->led.brightness = LED_OFF; host->led.default_trigger = mmc_hostname(mmc); host->led.brightness_set = sdhci_led_control; diff --git a/trunk/drivers/mmc/host/sdhci.h b/trunk/drivers/mmc/host/sdhci.h index ebb83657e27a..3efba2363941 100644 --- a/trunk/drivers/mmc/host/sdhci.h +++ b/trunk/drivers/mmc/host/sdhci.h @@ -208,6 +208,8 @@ struct sdhci_host { #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) /* Controller has an issue with buffer bits for small transfers */ #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) +/* Controller supports high speed but doesn't have the caps bit set */ +#define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */ @@ -220,7 +222,6 @@ struct sdhci_host { #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) struct led_classdev led; /* LED control */ - char led_name[32]; #endif spinlock_t lock; /* Mutex */ diff --git a/trunk/drivers/mtd/chips/map_rom.c b/trunk/drivers/mtd/chips/map_rom.c index c76d6e5f47ee..821d0ed6bae3 100644 --- a/trunk/drivers/mtd/chips/map_rom.c +++ b/trunk/drivers/mtd/chips/map_rom.c @@ -19,7 +19,6 @@ static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static void maprom_nop (struct mtd_info *); static struct mtd_info *map_rom_probe(struct map_info *map); -static int maprom_erase (struct mtd_info *mtd, struct erase_info *info); static struct mtd_chip_driver maprom_chipdrv = { .probe = map_rom_probe, @@ -43,7 +42,6 @@ static struct mtd_info *map_rom_probe(struct map_info *map) mtd->read = maprom_read; mtd->write = maprom_write; mtd->sync = maprom_nop; - mtd->erase = maprom_erase; mtd->flags = MTD_CAP_ROM; mtd->erasesize = map->size; mtd->writesize = 1; @@ -73,12 +71,6 @@ static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *re return -EIO; } -static int maprom_erase (struct mtd_info *mtd, struct erase_info *info) -{ - /* We do our best 8) */ - return -EROFS; -} - static int __init map_rom_init(void) { register_mtd_chip_driver(&maprom_chipdrv); diff --git a/trunk/drivers/mtd/devices/slram.c b/trunk/drivers/mtd/devices/slram.c index 00248e81ecd5..a425d09f35a0 100644 --- a/trunk/drivers/mtd/devices/slram.c +++ b/trunk/drivers/mtd/devices/slram.c @@ -267,28 +267,22 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) if (*(szlength) != '+') { devlength = simple_strtoul(szlength, &buffer, 0); devlength = handle_unit(devlength, buffer) - devstart; - if (devlength < devstart) - goto err_out; - - devlength -= devstart; } else { devlength = simple_strtoul(szlength + 1, &buffer, 0); devlength = handle_unit(devlength, buffer); } T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", devname, devstart, devlength); - if (devlength % SLRAM_BLK_SZ != 0) - goto err_out; + if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) { + E("slram: Illegal start / length parameter.\n"); + return(-EINVAL); + } if ((devstart = register_device(devname, devstart, devlength))){ unregister_devices(); return((int)devstart); } return(0); - -err_out: - E("slram: Illegal length parameter.\n"); - return(-EINVAL); } #ifndef MODULE diff --git a/trunk/drivers/mtd/lpddr/Kconfig b/trunk/drivers/mtd/lpddr/Kconfig index 5a401d8047ab..acd4ea9b2278 100644 --- a/trunk/drivers/mtd/lpddr/Kconfig +++ b/trunk/drivers/mtd/lpddr/Kconfig @@ -12,7 +12,6 @@ config MTD_LPDDR DDR memories, intended for battery-operated systems. config MTD_QINFO_PROBE - depends on MTD_LPDDR tristate "Detect flash chips by QINFO probe" help Device Information for LPDDR chips is offered through the Overlay diff --git a/trunk/drivers/mtd/maps/Kconfig b/trunk/drivers/mtd/maps/Kconfig index 043d50fb6ef6..0225cbbf22de 100644 --- a/trunk/drivers/mtd/maps/Kconfig +++ b/trunk/drivers/mtd/maps/Kconfig @@ -491,7 +491,7 @@ config MTD_PCMCIA_ANONYMOUS config MTD_BFIN_ASYNC tristate "Blackfin BF533-STAMP Flash Chip Support" - depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS + depends on BFIN533_STAMP && MTD_CFI select MTD_PARTITIONS default y help diff --git a/trunk/drivers/mtd/maps/bfin-async-flash.c b/trunk/drivers/mtd/maps/bfin-async-flash.c index 576611f605db..6fec86aaed7e 100644 --- a/trunk/drivers/mtd/maps/bfin-async-flash.c +++ b/trunk/drivers/mtd/maps/bfin-async-flash.c @@ -152,18 +152,14 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev) if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); - kfree(state); return -EBUSY; } gpio_direction_output(state->enet_flash_pin, 1); pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); state->mtd = do_map_probe(memory->name, &state->map); - if (!state->mtd) { - gpio_free(state->enet_flash_pin); - kfree(state); + if (!state->mtd) return -ENXIO; - } #ifdef CONFIG_MTD_PARTITIONS ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); diff --git a/trunk/drivers/mtd/maps/ck804xrom.c b/trunk/drivers/mtd/maps/ck804xrom.c index 424f17d6ffd1..5f7a245ed132 100644 --- a/trunk/drivers/mtd/maps/ck804xrom.c +++ b/trunk/drivers/mtd/maps/ck804xrom.c @@ -342,9 +342,9 @@ static struct pci_device_id ck804xrom_pci_tbl[] = { { 0, } }; -#if 0 MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl); +#if 0 static struct pci_driver ck804xrom_driver = { .name = MOD_NAME, .id_table = ck804xrom_pci_tbl, diff --git a/trunk/drivers/mtd/maps/physmap.c b/trunk/drivers/mtd/maps/physmap.c index 4b122e7ab4b3..87743661d48e 100644 --- a/trunk/drivers/mtd/maps/physmap.c +++ b/trunk/drivers/mtd/maps/physmap.c @@ -29,7 +29,6 @@ struct physmap_flash_info { struct map_info map[MAX_RESOURCES]; #ifdef CONFIG_MTD_PARTITIONS int nr_parts; - struct mtd_partition *parts; #endif }; @@ -46,26 +45,25 @@ static int physmap_flash_remove(struct platform_device *dev) physmap_data = dev->dev.platform_data; -#ifdef CONFIG_MTD_PARTITIONS - if (info->nr_parts) { - del_mtd_partitions(info->cmtd); - kfree(info->parts); - } else if (physmap_data->nr_parts) - del_mtd_partitions(info->cmtd); - else - del_mtd_device(info->cmtd); -#else - del_mtd_device(info->cmtd); -#endif - #ifdef CONFIG_MTD_CONCAT - if (info->cmtd != info->mtd[0]) + if (info->cmtd != info->mtd[0]) { + del_mtd_device(info->cmtd); mtd_concat_destroy(info->cmtd); + } #endif for (i = 0; i < MAX_RESOURCES; i++) { - if (info->mtd[i] != NULL) + if (info->mtd[i] != NULL) { +#ifdef CONFIG_MTD_PARTITIONS + if (info->nr_parts || physmap_data->nr_parts) + del_mtd_partitions(info->mtd[i]); + else + del_mtd_device(info->mtd[i]); +#else + del_mtd_device(info->mtd[i]); +#endif map_destroy(info->mtd[i]); + } } return 0; } @@ -88,6 +86,9 @@ static int physmap_flash_probe(struct platform_device *dev) int err = 0; int i; int devices_found = 0; +#ifdef CONFIG_MTD_PARTITIONS + struct mtd_partition *parts; +#endif physmap_data = dev->dev.platform_data; if (physmap_data == NULL) @@ -166,11 +167,10 @@ static int physmap_flash_probe(struct platform_device *dev) goto err_out; #ifdef CONFIG_MTD_PARTITIONS - err = parse_mtd_partitions(info->cmtd, part_probe_types, - &info->parts, 0); + err = parse_mtd_partitions(info->cmtd, part_probe_types, &parts, 0); if (err > 0) { - add_mtd_partitions(info->cmtd, info->parts, err); - info->nr_parts = err; + add_mtd_partitions(info->cmtd, parts, err); + kfree(parts); return 0; } diff --git a/trunk/drivers/mtd/maps/sa1100-flash.c b/trunk/drivers/mtd/maps/sa1100-flash.c index 6f6a0f6dafd6..7df6bbf0e4d9 100644 --- a/trunk/drivers/mtd/maps/sa1100-flash.c +++ b/trunk/drivers/mtd/maps/sa1100-flash.c @@ -453,7 +453,7 @@ static struct platform_driver sa1100_mtd_driver = { .resume = sa1100_mtd_resume, .shutdown = sa1100_mtd_shutdown, .driver = { - .name = "sa1100-mtd", + .name = "flash", .owner = THIS_MODULE, }, }; @@ -474,4 +474,4 @@ module_exit(sa1100_mtd_exit); MODULE_AUTHOR("Nicolas Pitre"); MODULE_DESCRIPTION("SA1100 CFI map driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:sa1100-mtd"); +MODULE_ALIAS("platform:flash"); diff --git a/trunk/drivers/mtd/nand/atmel_nand.c b/trunk/drivers/mtd/nand/atmel_nand.c index 47a33cec3793..c98c1570a40b 100644 --- a/trunk/drivers/mtd/nand/atmel_nand.c +++ b/trunk/drivers/mtd/nand/atmel_nand.c @@ -139,8 +139,7 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) struct nand_chip *nand_chip = mtd->priv; struct atmel_nand_host *host = nand_chip->priv; - return gpio_get_value(host->board->rdy_pin) ^ - !!host->board->rdy_pin_active_low; + return gpio_get_value(host->board->rdy_pin); } /* diff --git a/trunk/drivers/net/arm/etherh.c b/trunk/drivers/net/arm/etherh.c index 54b52e5b1821..d15d8b79d8e5 100644 --- a/trunk/drivers/net/arm/etherh.c +++ b/trunk/drivers/net/arm/etherh.c @@ -646,7 +646,7 @@ static const struct net_device_ops etherh_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_set_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index 9f33e442f403..f42581157f4e 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -795,9 +795,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * See if the firmware gave us a virtual-physical port mapping. */ adapter->physical_port = adapter->portnum; - i = adapter->pci_read_normalize(adapter, CRB_V2P(adapter->portnum)); - if (i != 0x55555555) - adapter->physical_port = i; + if (adapter->fw_major < 4) { + i = adapter->pci_read_normalize(adapter, + CRB_V2P(adapter->portnum)); + if (i != 0x55555555) + adapter->physical_port = i; + } adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c index ab13ff22a8c0..b0ee86c62685 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -148,7 +148,7 @@ static void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) pci_unmap_single(dev, pci_unmap_addr(&txq->cmd[index]->meta, mapping), pci_unmap_len(&txq->cmd[index]->meta, len), - PCI_DMA_BIDIRECTIONAL); + PCI_DMA_TODEVICE); /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) { @@ -964,7 +964,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) * within command buffer array. */ txcmd_phys = pci_map_single(priv->pci_dev, out_cmd, sizeof(struct iwl_cmd), - PCI_DMA_BIDIRECTIONAL); + PCI_DMA_TODEVICE); pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd)); /* Add buffer containing Tx command and MAC(!) header to TFD's @@ -1115,7 +1115,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd); phys_addr = pci_map_single(priv->pci_dev, out_cmd, - len, PCI_DMA_BIDIRECTIONAL); + len, PCI_DMA_TODEVICE); pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr); pci_unmap_len_set(&out_cmd->meta, len, len); phys_addr += offsetof(struct iwl_cmd, hdr); @@ -1212,7 +1212,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, pci_unmap_single(priv->pci_dev, pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping), pci_unmap_len(&txq->cmd[cmd_idx]->meta, len), - PCI_DMA_BIDIRECTIONAL); + PCI_DMA_TODEVICE); for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { diff --git a/trunk/drivers/parport/parport_atari.c b/trunk/drivers/parport/parport_atari.c index 0b28fccec03f..ad4cdd256137 100644 --- a/trunk/drivers/parport/parport_atari.c +++ b/trunk/drivers/parport/parport_atari.c @@ -84,7 +84,7 @@ parport_atari_frob_control(struct parport *p, unsigned char mask, static unsigned char parport_atari_read_status(struct parport *p) { - return ((st_mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) | + return ((mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) | PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR); } @@ -193,9 +193,9 @@ static int __init parport_atari_init(void) sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5); local_irq_restore(flags); /* MFP port I0 as input. */ - st_mfp.data_dir &= ~1; + mfp.data_dir &= ~1; /* MFP port I0 interrupt on high->low edge. */ - st_mfp.active_edge &= ~1; + mfp.active_edge &= ~1; p = parport_register_port((unsigned long)&sound_ym.wd_data, IRQ_MFP_BUSY, PARPORT_DMA_NONE, &parport_atari_ops); diff --git a/trunk/drivers/parport/parport_serial.c b/trunk/drivers/parport/parport_serial.c index 032db815b0f9..101ed49a2d15 100644 --- a/trunk/drivers/parport/parport_serial.c +++ b/trunk/drivers/parport/parport_serial.c @@ -64,11 +64,6 @@ struct parport_pc_pci { static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma) { - /* the rule described below doesn't hold for this device */ - if (dev->device == PCI_DEVICE_ID_NETMOS_9835 && - dev->subsystem_vendor == PCI_VENDOR_ID_IBM && - dev->subsystem_device == 0x0299) - return -ENODEV; /* * Netmos uses the subdevice ID to indicate the number of parallel * and serial ports. The form is 0x00PS, where

is the number of diff --git a/trunk/drivers/pci/dmar.c b/trunk/drivers/pci/dmar.c index 26c536b51c5a..f5a662a50acb 100644 --- a/trunk/drivers/pci/dmar.c +++ b/trunk/drivers/pci/dmar.c @@ -330,14 +330,6 @@ parse_dmar_table(void) entry_header = (struct acpi_dmar_header *)(dmar + 1); while (((unsigned long)entry_header) < (((unsigned long)dmar) + dmar_tbl->length)) { - /* Avoid looping forever on bad ACPI tables */ - if (entry_header->length == 0) { - printk(KERN_WARNING PREFIX - "Invalid 0-length structure\n"); - ret = -EINVAL; - break; - } - dmar_table_print_dmar_entry(entry_header); switch (entry_header->type) { @@ -499,7 +491,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) int map_size; u32 ver; static int iommu_allocated = 0; - int agaw = 0; + int agaw; iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); if (!iommu) @@ -515,7 +507,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); -#ifdef CONFIG_DMAR agaw = iommu_calculate_agaw(iommu); if (agaw < 0) { printk(KERN_ERR @@ -523,7 +514,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->seq_id); goto error; } -#endif iommu->agaw = agaw; /* the registers might be more than one page */ @@ -581,49 +571,19 @@ static inline void reclaim_free_desc(struct q_inval *qi) } } -static int qi_check_fault(struct intel_iommu *iommu, int index) -{ - u32 fault; - int head; - struct q_inval *qi = iommu->qi; - int wait_index = (index + 1) % QI_LENGTH; - - fault = readl(iommu->reg + DMAR_FSTS_REG); - - /* - * If IQE happens, the head points to the descriptor associated - * with the error. No new descriptors are fetched until the IQE - * is cleared. - */ - if (fault & DMA_FSTS_IQE) { - head = readl(iommu->reg + DMAR_IQH_REG); - if ((head >> 4) == index) { - memcpy(&qi->desc[index], &qi->desc[wait_index], - sizeof(struct qi_desc)); - __iommu_flush_cache(iommu, &qi->desc[index], - sizeof(struct qi_desc)); - writel(DMA_FSTS_IQE, iommu->reg + DMAR_FSTS_REG); - return -EINVAL; - } - } - - return 0; -} - /* * Submit the queued invalidation descriptor to the remapping * hardware unit and wait for its completion. */ -int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) +void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) { - int rc = 0; struct q_inval *qi = iommu->qi; struct qi_desc *hw, wait_desc; int wait_index, index; unsigned long flags; if (!qi) - return 0; + return; hw = qi->desc; @@ -641,8 +601,7 @@ int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) hw[index] = *desc; - wait_desc.low = QI_IWD_STATUS_DATA(QI_DONE) | - QI_IWD_STATUS_WRITE | QI_IWD_TYPE; + wait_desc.low = QI_IWD_STATUS_DATA(2) | QI_IWD_STATUS_WRITE | QI_IWD_TYPE; wait_desc.high = virt_to_phys(&qi->desc_status[wait_index]); hw[wait_index] = wait_desc; @@ -653,11 +612,13 @@ int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) qi->free_head = (qi->free_head + 2) % QI_LENGTH; qi->free_cnt -= 2; + spin_lock(&iommu->register_lock); /* * update the HW tail register indicating the presence of * new descriptors. */ writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG); + spin_unlock(&iommu->register_lock); while (qi->desc_status[wait_index] != QI_DONE) { /* @@ -667,21 +628,15 @@ int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) * a deadlock where the interrupt context can wait indefinitely * for free slots in the queue. */ - rc = qi_check_fault(iommu, index); - if (rc) - goto out; - spin_unlock(&qi->q_lock); cpu_relax(); spin_lock(&qi->q_lock); } -out: - qi->desc_status[index] = qi->desc_status[wait_index] = QI_DONE; + + qi->desc_status[index] = QI_DONE; reclaim_free_desc(qi); spin_unlock_irqrestore(&qi->q_lock, flags); - - return rc; } /* @@ -694,13 +649,13 @@ void qi_global_iec(struct intel_iommu *iommu) desc.low = QI_IEC_TYPE; desc.high = 0; - /* should never fail */ qi_submit_sync(&desc, iommu); } int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm, u64 type, int non_present_entry_flush) { + struct qi_desc desc; if (non_present_entry_flush) { @@ -714,7 +669,10 @@ int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm, | QI_CC_GRAN(type) | QI_CC_TYPE; desc.high = 0; - return qi_submit_sync(&desc, iommu); + qi_submit_sync(&desc, iommu); + + return 0; + } int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, @@ -744,7 +702,10 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih) | QI_IOTLB_AM(size_order); - return qi_submit_sync(&desc, iommu); + qi_submit_sync(&desc, iommu); + + return 0; + } /* diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index 39ae37589fda..db85284ffb62 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -111,7 +111,6 @@ struct controller { int cmd_busy; unsigned int no_cmd_complete:1; unsigned int link_active_reporting:1; - unsigned int notification_enabled:1; }; #define INT_BUTTON_IGNORE 0 @@ -171,7 +170,6 @@ extern int pciehp_configure_device(struct slot *p_slot); extern int pciehp_unconfigure_device(struct slot *p_slot); extern void pciehp_queue_pushbutton_work(struct work_struct *work); struct controller *pcie_init(struct pcie_device *dev); -int pcie_init_notification(struct controller *ctrl); int pciehp_enable_slot(struct slot *p_slot); int pciehp_disable_slot(struct slot *p_slot); int pcie_enable_notification(struct controller *ctrl); diff --git a/trunk/drivers/pci/hotplug/pciehp_core.c b/trunk/drivers/pci/hotplug/pciehp_core.c index 681e3912b821..c2485542f543 100644 --- a/trunk/drivers/pci/hotplug/pciehp_core.c +++ b/trunk/drivers/pci/hotplug/pciehp_core.c @@ -434,13 +434,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ goto err_out_release_ctlr; } - /* Enable events after we have setup the data structures */ - rc = pcie_init_notification(ctrl); - if (rc) { - ctrl_err(ctrl, "Notification initialization failed\n"); - goto err_out_release_ctlr; - } - /* Check if slot is occupied */ t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); t_slot->hpc_ops->get_adapter_status(t_slot, &value); diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index 7a16c6897bb9..71a8012886b0 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl) ctrl_warn(ctrl, "Cannot disable software notification\n"); } -int pcie_init_notification(struct controller *ctrl) +static int pcie_init_notification(struct controller *ctrl) { if (pciehp_request_irq(ctrl)) return -1; @@ -942,17 +942,13 @@ int pcie_init_notification(struct controller *ctrl) pciehp_free_irq(ctrl); return -1; } - ctrl->notification_enabled = 1; return 0; } static void pcie_shutdown_notification(struct controller *ctrl) { - if (ctrl->notification_enabled) { - pcie_disable_notification(ctrl); - pciehp_free_irq(ctrl); - ctrl->notification_enabled = 0; - } + pcie_disable_notification(ctrl); + pciehp_free_irq(ctrl); } static int pcie_init_slot(struct controller *ctrl) @@ -1114,8 +1110,13 @@ struct controller *pcie_init(struct pcie_device *dev) if (pcie_init_slot(ctrl)) goto abort_ctrl; + if (pcie_init_notification(ctrl)) + goto abort_slot; + return ctrl; +abort_slot: + pcie_cleanup_slot(ctrl); abort_ctrl: kfree(ctrl); abort: diff --git a/trunk/drivers/pci/intel-iommu.c b/trunk/drivers/pci/intel-iommu.c index f3f686581a90..3dfecb20d5e7 100644 --- a/trunk/drivers/pci/intel-iommu.c +++ b/trunk/drivers/pci/intel-iommu.c @@ -61,8 +61,6 @@ /* global iommu list, set NULL for ignored DMAR units */ static struct intel_iommu **g_iommus; -static int rwbf_quirk; - /* * 0: Present * 1-11: Reserved @@ -270,12 +268,7 @@ static long list_size; static void domain_remove_dev_info(struct dmar_domain *domain); -#ifdef CONFIG_DMAR_DEFAULT_ON -int dmar_disabled = 0; -#else -int dmar_disabled = 1; -#endif /*CONFIG_DMAR_DEFAULT_ON*/ - +int dmar_disabled; static int __initdata dmar_map_gfx = 1; static int dmar_forcedac; static int intel_iommu_strict; @@ -291,12 +284,9 @@ static int __init intel_iommu_setup(char *str) if (!str) return -EINVAL; while (*str) { - if (!strncmp(str, "on", 2)) { - dmar_disabled = 0; - printk(KERN_INFO "Intel-IOMMU: enabled\n"); - } else if (!strncmp(str, "off", 3)) { + if (!strncmp(str, "off", 3)) { dmar_disabled = 1; - printk(KERN_INFO "Intel-IOMMU: disabled\n"); + printk(KERN_INFO"Intel-IOMMU: disabled\n"); } else if (!strncmp(str, "igfx_off", 8)) { dmar_map_gfx = 0; printk(KERN_INFO @@ -787,7 +777,7 @@ static void iommu_flush_write_buffer(struct intel_iommu *iommu) u32 val; unsigned long flag; - if (!rwbf_quirk && !cap_rwbf(iommu->cap)) + if (!cap_rwbf(iommu->cap)) return; val = iommu->gcmd | DMA_GCMD_WBF; @@ -3139,15 +3129,3 @@ static struct iommu_ops intel_iommu_ops = { .unmap = intel_iommu_unmap_range, .iova_to_phys = intel_iommu_iova_to_phys, }; - -static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) -{ - /* - * Mobile 4 Series Chipset neglects to set RWBF capability, - * but needs it: - */ - printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); - rwbf_quirk = 1; -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); diff --git a/trunk/drivers/pci/intr_remapping.c b/trunk/drivers/pci/intr_remapping.c index 45effc5726c0..f78371b22529 100644 --- a/trunk/drivers/pci/intr_remapping.c +++ b/trunk/drivers/pci/intr_remapping.c @@ -207,7 +207,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) return index; } -static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask) +static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask) { struct qi_desc desc; @@ -215,7 +215,7 @@ static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask) | QI_IEC_SELECTIVE; desc.high = 0; - return qi_submit_sync(&desc, iommu); + qi_submit_sync(&desc, iommu); } int map_irq_to_irte_handle(int irq, u16 *sub_handle) @@ -283,7 +283,6 @@ int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) int modify_irte(int irq, struct irte *irte_modified) { - int rc; int index; struct irte *irte; struct intel_iommu *iommu; @@ -304,15 +303,14 @@ int modify_irte(int irq, struct irte *irte_modified) set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); __iommu_flush_cache(iommu, irte, sizeof(*irte)); - rc = qi_flush_iec(iommu, index, 0); - spin_unlock(&irq_2_ir_lock); + qi_flush_iec(iommu, index, 0); - return rc; + spin_unlock(&irq_2_ir_lock); + return 0; } int flush_irte(int irq) { - int rc; int index; struct intel_iommu *iommu; struct irq_2_iommu *irq_iommu; @@ -328,10 +326,10 @@ int flush_irte(int irq) index = irq_iommu->irte_index + irq_iommu->sub_handle; - rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); + qi_flush_iec(iommu, index, irq_iommu->irte_mask); spin_unlock(&irq_2_ir_lock); - return rc; + return 0; } struct intel_iommu *map_ioapic_to_ir(int apic) @@ -357,7 +355,6 @@ struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) int free_irte(int irq) { - int rc = 0; int index, i; struct irte *irte; struct intel_iommu *iommu; @@ -378,7 +375,7 @@ int free_irte(int irq) if (!irq_iommu->sub_handle) { for (i = 0; i < (1 << irq_iommu->irte_mask); i++) set_64bit((unsigned long *)irte, 0); - rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); + qi_flush_iec(iommu, index, irq_iommu->irte_mask); } irq_iommu->iommu = NULL; @@ -388,7 +385,7 @@ int free_irte(int irq) spin_unlock(&irq_2_ir_lock); - return rc; + return 0; } static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index baba2eb5367d..44f15ff70c1d 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -103,12 +103,14 @@ static void msix_set_enable(struct pci_dev *dev, int enable) } } +/* + * Essentially, this is ((1 << (1 << x)) - 1), but without the + * undefinedness of a << 32. + */ static inline __attribute_const__ u32 msi_mask(unsigned x) { - /* Don't shift by >= width of type */ - if (x >= 5) - return 0xffffffff; - return (1 << (1 << x)) - 1; + static const u32 mask[] = { 1, 2, 4, 0xf, 0xff, 0xffff, 0xffffffff }; + return mask[x]; } static void msix_flush_writes(struct irq_desc *desc) diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 93eac1423585..ab1d615425a8 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -355,8 +355,6 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state) int i = 0; if (drv && drv->suspend) { - pci_power_t prev = pci_dev->current_state; - pci_dev->state_saved = false; i = drv->suspend(pci_dev, state); @@ -367,16 +365,12 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state) if (pci_dev->state_saved) goto Fixup; - if (pci_dev->current_state != PCI_D0 - && pci_dev->current_state != PCI_UNKNOWN) { - WARN_ONCE(pci_dev->current_state != prev, - "PCI PM: Device state not saved by %pF\n", - drv->suspend); + if (WARN_ON_ONCE(pci_dev->current_state != PCI_D0)) goto Fixup; - } } pci_save_state(pci_dev); + pci_dev->state_saved = true; /* * This is for compatibility with existing code with legacy PM support. */ @@ -430,20 +424,35 @@ static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) pci_fixup_device(pci_fixup_resume_early, pci_dev); } -static void pci_pm_default_resume(struct pci_dev *pci_dev) +static int pci_pm_default_resume(struct pci_dev *pci_dev) { pci_fixup_device(pci_fixup_resume, pci_dev); if (!pci_is_bridge(pci_dev)) pci_enable_wake(pci_dev, PCI_D0, false); + + return pci_pm_reenable_device(pci_dev); +} + +static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev) +{ + /* If device is enabled at this point, disable it */ + pci_disable_enabled_device(pci_dev); + /* + * Save state with interrupts enabled, because in principle the bus the + * device is on may be put into a low power state after this code runs. + */ + pci_save_state(pci_dev); } static void pci_pm_default_suspend(struct pci_dev *pci_dev) { - /* Disable non-bridge devices without PM support */ + pci_pm_default_suspend_generic(pci_dev); + if (!pci_is_bridge(pci_dev)) - pci_disable_enabled_device(pci_dev); - pci_save_state(pci_dev); + pci_prepare_to_sleep(pci_dev); + + pci_fixup_device(pci_fixup_suspend, pci_dev); } static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) @@ -488,49 +497,21 @@ static void pci_pm_complete(struct device *dev) static int pci_pm_suspend(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + struct device_driver *drv = dev->driver; + int error = 0; if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_suspend(dev, PMSG_SUSPEND); - if (!pm) { - pci_pm_default_suspend(pci_dev); - goto Fixup; + if (drv && drv->pm && drv->pm->suspend) { + error = drv->pm->suspend(dev); + suspend_report_result(drv->pm->suspend, error); } - pci_dev->state_saved = false; - - if (pm->suspend) { - pci_power_t prev = pci_dev->current_state; - int error; - - error = pm->suspend(dev); - suspend_report_result(pm->suspend, error); - if (error) - return error; - - if (pci_dev->state_saved) - goto Fixup; - - if (pci_dev->current_state != PCI_D0 - && pci_dev->current_state != PCI_UNKNOWN) { - WARN_ONCE(pci_dev->current_state != prev, - "PCI PM: State of device not saved by %pF\n", - pm->suspend); - goto Fixup; - } - } - - if (!pci_dev->state_saved) { - pci_save_state(pci_dev); - if (!pci_is_bridge(pci_dev)) - pci_prepare_to_sleep(pci_dev); - } - - Fixup: - pci_fixup_device(pci_fixup_suspend, pci_dev); + if (!error) + pci_pm_default_suspend(pci_dev); - return 0; + return error; } static int pci_pm_suspend_noirq(struct device *dev) @@ -573,7 +554,7 @@ static int pci_pm_resume_noirq(struct device *dev) static int pci_pm_resume(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + struct device_driver *drv = dev->driver; int error = 0; /* @@ -586,16 +567,12 @@ static int pci_pm_resume(struct device *dev) if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume(dev); - pci_pm_default_resume(pci_dev); + error = pci_pm_default_resume(pci_dev); - if (pm) { - if (pm->resume) - error = pm->resume(dev); - } else { - pci_pm_reenable_device(pci_dev); - } + if (!error && drv && drv->pm && drv->pm->resume) + error = drv->pm->resume(dev); - return 0; + return error; } #else /* !CONFIG_SUSPEND */ @@ -612,31 +589,21 @@ static int pci_pm_resume(struct device *dev) static int pci_pm_freeze(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + struct device_driver *drv = dev->driver; + int error = 0; if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_suspend(dev, PMSG_FREEZE); - if (!pm) { - pci_pm_default_suspend(pci_dev); - return 0; + if (drv && drv->pm && drv->pm->freeze) { + error = drv->pm->freeze(dev); + suspend_report_result(drv->pm->freeze, error); } - pci_dev->state_saved = false; - - if (pm->freeze) { - int error; - - error = pm->freeze(dev); - suspend_report_result(pm->freeze, error); - if (error) - return error; - } - - if (!pci_dev->state_saved) - pci_save_state(pci_dev); + if (!error) + pci_pm_default_suspend_generic(pci_dev); - return 0; + return error; } static int pci_pm_freeze_noirq(struct device *dev) @@ -679,18 +646,16 @@ static int pci_pm_thaw_noirq(struct device *dev) static int pci_pm_thaw(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + struct device_driver *drv = dev->driver; int error = 0; if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume(dev); - if (pm) { - if (pm->thaw) - error = pm->thaw(dev); - } else { - pci_pm_reenable_device(pci_dev); - } + pci_pm_reenable_device(pci_dev); + + if (drv && drv->pm && drv->pm->thaw) + error = drv->pm->thaw(dev); return error; } @@ -698,29 +663,22 @@ static int pci_pm_thaw(struct device *dev) static int pci_pm_poweroff(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + struct device_driver *drv = dev->driver; int error = 0; if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_suspend(dev, PMSG_HIBERNATE); - if (!pm) { - pci_pm_default_suspend(pci_dev); - goto Fixup; - } - - pci_dev->state_saved = false; + if (!drv || !drv->pm) + return 0; - if (pm->poweroff) { - error = pm->poweroff(dev); - suspend_report_result(pm->poweroff, error); + if (drv->pm->poweroff) { + error = drv->pm->poweroff(dev); + suspend_report_result(drv->pm->poweroff, error); } - if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) - pci_prepare_to_sleep(pci_dev); - - Fixup: - pci_fixup_device(pci_fixup_suspend, pci_dev); + if (!error) + pci_pm_default_suspend(pci_dev); return error; } @@ -761,7 +719,7 @@ static int pci_pm_restore_noirq(struct device *dev) static int pci_pm_restore(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + struct device_driver *drv = dev->driver; int error = 0; /* @@ -774,14 +732,10 @@ static int pci_pm_restore(struct device *dev) if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume(dev); - pci_pm_default_resume(pci_dev); + error = pci_pm_default_resume(pci_dev); - if (pm) { - if (pm->restore) - error = pm->restore(dev); - } else { - pci_pm_reenable_device(pci_dev); - } + if (!error && drv && drv->pm && drv->pm->restore) + error = drv->pm->restore(dev); return error; } diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index dfc4e0ddf241..db7ec14fa719 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -768,8 +768,8 @@ pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr, return -EINVAL; rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */ - if (!rom || !size) - return -EIO; + if (!rom) + return 0; if (off >= size) count = 0; diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 6d6120007af4..48807556b47a 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -1418,10 +1418,10 @@ int pci_restore_standard_config(struct pci_dev *dev) break; } - pci_update_current_state(dev, PCI_D0); + dev->current_state = PCI_D0; Restore: - return dev->state_saved ? pci_restore_state(dev) : 0; + return pci_restore_state(dev); } /** @@ -1540,21 +1540,16 @@ void pci_release_region(struct pci_dev *pdev, int bar) } /** - * __pci_request_region - Reserved PCI I/O and memory resource + * pci_request_region - Reserved PCI I/O and memory resource * @pdev: PCI device whose resources are to be reserved * @bar: BAR to be reserved * @res_name: Name to be associated with resource. - * @exclusive: whether the region access is exclusive or not * * Mark the PCI region associated with PCI device @pdev BR @bar as * being reserved by owner @res_name. Do not access any * address inside the PCI regions unless this call returns * successfully. * - * If @exclusive is set, then the region is marked so that userspace - * is explicitly not allowed to map the resource via /dev/mem or - * sysfs MMIO access. - * * Returns 0 on success, or %EBUSY on error. A warning * message is also printed on failure. */ @@ -1593,12 +1588,12 @@ static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_n } /** - * pci_request_region - Reserve PCI I/O and memory resource + * pci_request_region - Reserved PCI I/O and memory resource * @pdev: PCI device whose resources are to be reserved * @bar: BAR to be reserved - * @res_name: Name to be associated with resource + * @res_name: Name to be associated with resource. * - * Mark the PCI region associated with PCI device @pdev BAR @bar as + * Mark the PCI region associated with PCI device @pdev BR @bar as * being reserved by owner @res_name. Do not access any * address inside the PCI regions unless this call returns * successfully. diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index 07c0aa5275e6..26ddf78ac300 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -16,21 +16,21 @@ extern int pci_mmap_fits(struct pci_dev *pdev, int resno, #endif /** - * struct pci_platform_pm_ops - Firmware PM callbacks + * Firmware PM callbacks * - * @is_manageable: returns 'true' if given device is power manageable by the - * platform firmware + * @is_manageable - returns 'true' if given device is power manageable by the + * platform firmware * - * @set_state: invokes the platform firmware to set the device's power state + * @set_state - invokes the platform firmware to set the device's power state * - * @choose_state: returns PCI power state of given device preferred by the - * platform; to be used during system-wide transitions from a - * sleeping state to the working state and vice versa + * @choose_state - returns PCI power state of given device preferred by the + * platform; to be used during system-wide transitions from a + * sleeping state to the working state and vice versa * - * @can_wakeup: returns 'true' if given device is capable of waking up the - * system from a sleeping state + * @can_wakeup - returns 'true' if given device is capable of waking up the + * system from a sleeping state * - * @sleep_wake: enables/disables the system wake up capability of given device + * @sleep_wake - enables/disables the system wake up capability of given device * * If given platform is generally capable of power managing PCI devices, all of * these callbacks are mandatory. diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index d0c973685868..aac7006949f1 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -108,34 +108,6 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) } #endif /* 0 */ - -static void set_device_error_reporting(struct pci_dev *dev, void *data) -{ - bool enable = *((bool *)data); - - if (dev->pcie_type != PCIE_RC_PORT && - dev->pcie_type != PCIE_SW_UPSTREAM_PORT && - dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT) - return; - - if (enable) - pci_enable_pcie_error_reporting(dev); - else - pci_disable_pcie_error_reporting(dev); -} - -/** - * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports. - * @dev: pointer to root port's pci_dev data structure - * @enable: true = enable error reporting, false = disable error reporting. - */ -static void set_downstream_devices_error_reporting(struct pci_dev *dev, - bool enable) -{ - set_device_error_reporting(dev, &enable); - pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable); -} - static int find_device_iter(struct device *device, void *data) { struct pci_dev *dev; @@ -553,11 +525,15 @@ void aer_enable_rootport(struct aer_rpc *rpc) pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); - /* - * Enable error reporting for the root port device and downstream port - * devices. - */ - set_downstream_devices_error_reporting(pdev, true); + /* Enable Root Port device reporting error itself */ + pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, ®16); + reg16 = reg16 | + PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE; + pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL, + reg16); /* Enable Root Port's interrupt in response to error messages */ pci_write_config_dword(pdev, @@ -577,12 +553,6 @@ static void disable_root_aer(struct aer_rpc *rpc) u32 reg32; int pos; - /* - * Disable error reporting for the root port device and downstream port - * devices. - */ - set_downstream_devices_error_reporting(pdev, false); - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); /* Disable Root's interrupt in response to error messages */ pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); diff --git a/trunk/drivers/pci/pcie/aspm.c b/trunk/drivers/pci/pcie/aspm.c index b0367f168af4..586b6f75910d 100644 --- a/trunk/drivers/pci/pcie/aspm.c +++ b/trunk/drivers/pci/pcie/aspm.c @@ -718,9 +718,9 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) /* * All PCIe functions are in one slot, remove one function will remove - * the whole slot, so just wait until we are the last function left. + * the the whole slot, so just wait */ - if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices)) + if (!list_empty(&parent->subordinate->devices)) goto out; /* All functions are removed, so just disable ASPM for the link */ diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index 248b4db91552..99a914a027f8 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -55,13 +55,25 @@ static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) } +static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state) +{ + return pci_save_state(dev); +} + +static int pcie_portdrv_resume_early(struct pci_dev *dev) +{ + return pci_restore_state(dev); +} + static int pcie_portdrv_resume(struct pci_dev *dev) { - pci_set_master(dev); + pcie_portdrv_restore_config(dev); return pcie_port_device_resume(dev); } #else #define pcie_portdrv_suspend NULL +#define pcie_portdrv_suspend_late NULL +#define pcie_portdrv_resume_early NULL #define pcie_portdrv_resume NULL #endif @@ -97,6 +109,8 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, pcie_portdrv_save_config(dev); + pci_enable_pcie_error_reporting(dev); + return 0; } @@ -278,6 +292,8 @@ static struct pci_driver pcie_portdriver = { .remove = pcie_portdrv_remove, .suspend = pcie_portdrv_suspend, + .suspend_late = pcie_portdrv_suspend_late, + .resume_early = pcie_portdrv_resume_early, .resume = pcie_portdrv_resume, .err_handler = &pcie_portdrv_err_handler, diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index f20d55368edb..baad093aafe3 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -1584,7 +1584,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_ */ #define AMD_813X_MISC 0x40 #define AMD_813X_NOIOAMODE (1<<0) -#define AMD_813X_REV_B2 0x13 static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) { @@ -1592,8 +1591,6 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) if (noioapicquirk) return; - if (dev->revision == AMD_813X_REV_B2) - return; pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); pci_config_dword &= ~AMD_813X_NOIOAMODE; @@ -1984,6 +1981,7 @@ static void __devinit quirk_msi_ht_cap(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, quirk_msi_ht_cap); + /* The nVidia CK804 chipset may have 2 HT MSI mappings. * MSI are supported if the MSI capability set in any of these mappings. */ @@ -2034,9 +2032,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, ht_enable_msi_mapping); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, - ht_enable_msi_mapping); - /* The P5N32-SLI Premium motherboard from Asus has a problem with msi * for the MCP55 NIC. It is not yet determined whether the msi problem * also affects other devices. As for now, turn off msi for this device. @@ -2053,100 +2048,10 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15, nvenet_msi_disable); -static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev) -{ - struct pci_dev *host_bridge; - int pos; - int i, dev_no; - int found = 0; - - dev_no = dev->devfn >> 3; - for (i = dev_no; i >= 0; i--) { - host_bridge = pci_get_slot(dev->bus, PCI_DEVFN(i, 0)); - if (!host_bridge) - continue; - - pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); - if (pos != 0) { - found = 1; - break; - } - pci_dev_put(host_bridge); - } - - if (!found) - return; - - /* root did that ! */ - if (msi_ht_cap_enabled(host_bridge)) - goto out; - - ht_enable_msi_mapping(dev); - -out: - pci_dev_put(host_bridge); -} - -static void __devinit ht_disable_msi_mapping(struct pci_dev *dev) -{ - int pos, ttl = 48; - - pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); - while (pos && ttl--) { - u8 flags; - - if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, - &flags) == 0) { - dev_info(&dev->dev, "Enabling HT MSI Mapping\n"); - - pci_write_config_byte(dev, pos + HT_MSI_FLAGS, - flags & ~HT_MSI_FLAGS_ENABLE); - } - pos = pci_find_next_ht_capability(dev, pos, - HT_CAPTYPE_MSI_MAPPING); - } -} - -static int __devinit ht_check_msi_mapping(struct pci_dev *dev) -{ - int pos, ttl = 48; - int found = 0; - - /* check if there is HT MSI cap or enabled on this device */ - pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); - while (pos && ttl--) { - u8 flags; - - if (found < 1) - found = 1; - if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, - &flags) == 0) { - if (flags & HT_MSI_FLAGS_ENABLE) { - if (found < 2) { - found = 2; - break; - } - } - } - pos = pci_find_next_ht_capability(dev, pos, - HT_CAPTYPE_MSI_MAPPING); - } - - return found; -} - static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) { struct pci_dev *host_bridge; - int pos; - int found; - - /* check if there is HT MSI cap or enabled on this device */ - found = ht_check_msi_mapping(dev); - - /* no HT MSI CAP */ - if (found == 0) - return; + int pos, ttl = 48; /* * HT MSI mapping should be disabled on devices that are below @@ -2162,19 +2067,24 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); if (pos != 0) { /* Host bridge is to HT */ - if (found == 1) { - /* it is not enabled, try to enable it */ - nv_ht_enable_msi_mapping(dev); - } + ht_enable_msi_mapping(dev); return; } - /* HT MSI is not enabled */ - if (found == 1) - return; - /* Host bridge is not to HT, disable HT MSI mapping on this device */ - ht_disable_msi_mapping(dev); + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + dev_info(&dev->dev, "Disabling HT MSI mapping"); + pci_write_config_byte(dev, pos + HT_MSI_FLAGS, + flags & ~HT_MSI_FLAGS_ENABLE); + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk); diff --git a/trunk/drivers/pci/rom.c b/trunk/drivers/pci/rom.c index 36864a935d68..132a78159b60 100644 --- a/trunk/drivers/pci/rom.c +++ b/trunk/drivers/pci/rom.c @@ -55,7 +55,6 @@ void pci_disable_rom(struct pci_dev *pdev) /** * pci_get_rom_size - obtain the actual size of the ROM image - * @pdev: target PCI device * @rom: kernel virtual pointer to image of ROM * @size: size of PCI window * return: size of actual ROM image @@ -64,7 +63,7 @@ void pci_disable_rom(struct pci_dev *pdev) * The PCI window size could be much larger than the * actual image size. */ -size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) +size_t pci_get_rom_size(void __iomem *rom, size_t size) { void __iomem *image; int last_image; @@ -73,10 +72,8 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) do { void __iomem *pds; /* Standard PCI ROMs start out with these bytes 55 AA */ - if (readb(image) != 0x55) { - dev_err(&pdev->dev, "Invalid ROM contents\n"); + if (readb(image) != 0x55) break; - } if (readb(image + 1) != 0xAA) break; /* get the PCI data structure and check its signature */ @@ -162,7 +159,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) * size is much larger than the actual size of the ROM. * True size is important if the ROM is going to be copied. */ - *size = pci_get_rom_size(pdev, rom, *size); + *size = pci_get_rom_size(rom, *size); return rom; } diff --git a/trunk/drivers/platform/x86/Kconfig b/trunk/drivers/platform/x86/Kconfig index b3866ad50227..1a266d4ab5f1 100644 --- a/trunk/drivers/platform/x86/Kconfig +++ b/trunk/drivers/platform/x86/Kconfig @@ -42,7 +42,6 @@ config ASUS_LAPTOP depends on LEDS_CLASS depends on NEW_LEDS depends on BACKLIGHT_CLASS_DEVICE - depends on INPUT ---help--- This is the new Linux driver for Asus laptops. It may also support some MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate @@ -62,7 +61,6 @@ config DELL_LAPTOP depends on EXPERIMENTAL depends on BACKLIGHT_CLASS_DEVICE depends on RFKILL - depends on POWER_SUPPLY default n ---help--- This driver adds support for rfkill and backlight control to Dell @@ -302,7 +300,6 @@ config INTEL_MENLOW config EEEPC_LAPTOP tristate "Eee PC Hotkey Driver (EXPERIMENTAL)" depends on ACPI - depends on INPUT depends on EXPERIMENTAL select BACKLIGHT_CLASS_DEVICE select HWMON diff --git a/trunk/drivers/platform/x86/asus-laptop.c b/trunk/drivers/platform/x86/asus-laptop.c index 56af6cf385b0..8fb8b3591048 100644 --- a/trunk/drivers/platform/x86/asus-laptop.c +++ b/trunk/drivers/platform/x86/asus-laptop.c @@ -46,7 +46,6 @@ #include #include #include -#include #define ASUS_LAPTOP_VERSION "0.42" @@ -182,8 +181,6 @@ struct asus_hotk { u8 light_level; //light sensor level u8 light_switch; //light sensor switch value u16 event_count[128]; //count for each event TODO make this better - struct input_dev *inputdev; - u16 *keycode_map; }; /* @@ -253,37 +250,6 @@ ASUS_LED(rled, "record"); ASUS_LED(pled, "phone"); ASUS_LED(gled, "gaming"); -struct key_entry { - char type; - u8 code; - u16 keycode; -}; - -enum { KE_KEY, KE_END }; - -static struct key_entry asus_keymap[] = { - {KE_KEY, 0x30, KEY_VOLUMEUP}, - {KE_KEY, 0x31, KEY_VOLUMEDOWN}, - {KE_KEY, 0x32, KEY_MUTE}, - {KE_KEY, 0x33, KEY_SWITCHVIDEOMODE}, - {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE}, - {KE_KEY, 0x40, KEY_PREVIOUSSONG}, - {KE_KEY, 0x41, KEY_NEXTSONG}, - {KE_KEY, 0x43, KEY_STOP}, - {KE_KEY, 0x45, KEY_PLAYPAUSE}, - {KE_KEY, 0x50, KEY_EMAIL}, - {KE_KEY, 0x51, KEY_WWW}, - {KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */ - {KE_KEY, 0x5D, KEY_WLAN}, - {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, - {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ - {KE_KEY, 0x82, KEY_CAMERA}, - {KE_KEY, 0x8A, KEY_TV}, - {KE_KEY, 0x95, KEY_MEDIA}, - {KE_KEY, 0x99, KEY_PHONE}, - {KE_END, 0}, -}; - /* * This function evaluates an ACPI method, given an int as parameter, the * method is searched within the scope of the handle, can be NULL. The output @@ -754,68 +720,8 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr, return store_status(buf, count, NULL, GPS_ON); } -/* - * Hotkey functions - */ -static struct key_entry *asus_get_entry_by_scancode(int code) -{ - struct key_entry *key; - - for (key = asus_keymap; key->type != KE_END; key++) - if (code == key->code) - return key; - - return NULL; -} - -static struct key_entry *asus_get_entry_by_keycode(int code) -{ - struct key_entry *key; - - for (key = asus_keymap; key->type != KE_END; key++) - if (code == key->keycode && key->type == KE_KEY) - return key; - - return NULL; -} - -static int asus_getkeycode(struct input_dev *dev, int scancode, int *keycode) -{ - struct key_entry *key = asus_get_entry_by_scancode(scancode); - - if (key && key->type == KE_KEY) { - *keycode = key->keycode; - return 0; - } - - return -EINVAL; -} - -static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode) -{ - struct key_entry *key; - int old_keycode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - - key = asus_get_entry_by_scancode(scancode); - if (key && key->type == KE_KEY) { - old_keycode = key->keycode; - key->keycode = keycode; - set_bit(keycode, dev->keybit); - if (!asus_get_entry_by_keycode(old_keycode)) - clear_bit(old_keycode, dev->keybit); - return 0; - } - - return -EINVAL; -} - static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) { - static struct key_entry *key; - /* TODO Find a better way to handle events count. */ if (!hotk) return; @@ -832,24 +738,10 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) lcd_blank(FB_BLANK_POWERDOWN); } - acpi_bus_generate_netlink_event(hotk->device->pnp.device_class, - dev_name(&hotk->device->dev), event, - hotk->event_count[event % 128]++); - - if (hotk->inputdev) { - key = asus_get_entry_by_scancode(event); - if (!key) - return ; - - switch (key->type) { - case KE_KEY: - input_report_key(hotk->inputdev, key->keycode, 1); - input_sync(hotk->inputdev); - input_report_key(hotk->inputdev, key->keycode, 0); - input_sync(hotk->inputdev); - break; - } - } + acpi_bus_generate_proc_event(hotk->device, event, + hotk->event_count[event % 128]++); + + return; } #define ASUS_CREATE_DEVICE_ATTR(_name) \ @@ -1067,38 +959,6 @@ static int asus_hotk_get_info(void) return AE_OK; } -static int asus_input_init(void) -{ - const struct key_entry *key; - int result; - - hotk->inputdev = input_allocate_device(); - if (!hotk->inputdev) { - printk(ASUS_INFO "Unable to allocate input device\n"); - return 0; - } - hotk->inputdev->name = "Asus Laptop extra buttons"; - hotk->inputdev->phys = ASUS_HOTK_FILE "/input0"; - hotk->inputdev->id.bustype = BUS_HOST; - hotk->inputdev->getkeycode = asus_getkeycode; - hotk->inputdev->setkeycode = asus_setkeycode; - - for (key = asus_keymap; key->type != KE_END; key++) { - switch (key->type) { - case KE_KEY: - set_bit(EV_KEY, hotk->inputdev->evbit); - set_bit(key->keycode, hotk->inputdev->keybit); - break; - } - } - result = input_register_device(hotk->inputdev); - if (result) { - printk(ASUS_INFO "Unable to register input device\n"); - input_free_device(hotk->inputdev); - } - return result; -} - static int asus_hotk_check(void) { int result = 0; @@ -1184,7 +1044,7 @@ static int asus_hotk_add(struct acpi_device *device) /* GPS is on by default */ write_status(NULL, 1, GPS_ON); -end: + end: if (result) { kfree(hotk->name); kfree(hotk); @@ -1231,17 +1091,10 @@ static void asus_led_exit(void) ASUS_LED_UNREGISTER(gled); } -static void asus_input_exit(void) -{ - if (hotk->inputdev) - input_unregister_device(hotk->inputdev); -} - static void __exit asus_laptop_exit(void) { asus_backlight_exit(); asus_led_exit(); - asus_input_exit(); acpi_bus_unregister_driver(&asus_hotk_driver); sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); @@ -1363,10 +1216,6 @@ static int __init asus_laptop_init(void) printk(ASUS_INFO "Brightness ignored, must be controlled by " "ACPI video driver\n"); - result = asus_input_init(); - if (result) - goto fail_input; - result = asus_led_init(dev); if (result) goto fail_led; @@ -1393,25 +1242,22 @@ static int __init asus_laptop_init(void) return 0; -fail_sysfs: + fail_sysfs: platform_device_del(asuspf_device); -fail_platform_device2: + fail_platform_device2: platform_device_put(asuspf_device); -fail_platform_device1: + fail_platform_device1: platform_driver_unregister(&asuspf_driver); -fail_platform_driver: + fail_platform_driver: asus_led_exit(); -fail_led: - asus_input_exit(); - -fail_input: + fail_led: asus_backlight_exit(); -fail_backlight: + fail_backlight: return result; } diff --git a/trunk/drivers/platform/x86/asus_acpi.c b/trunk/drivers/platform/x86/asus_acpi.c index d63f26e666a4..1e74988c7b2d 100644 --- a/trunk/drivers/platform/x86/asus_acpi.c +++ b/trunk/drivers/platform/x86/asus_acpi.c @@ -143,7 +143,6 @@ struct asus_hotk { S1300N, S5200N*/ A4S, /* Z81sp */ F3Sa, /* (Centrino) */ - R1F, END_MODEL } model; /* Models currently supported */ u16 event_count[128]; /* Count for each event TODO make this better */ @@ -421,18 +420,7 @@ static struct model_data model_conf[END_MODEL] = { .display_get = "\\ADVG", .display_set = "SDSP", }, - { - .name = "R1F", - .mt_bt_switch = "BLED", - .mt_mled = "MLED", - .mt_wled = "WLED", - .mt_lcd_switch = "\\Q10", - .lcd_status = "\\GP06", - .brightness_set = "SPLV", - .brightness_get = "GPLV", - .display_set = "SDSP", - .display_get = "\\INFB" - } + }; /* procdir we use */ @@ -1177,8 +1165,6 @@ static int asus_model_match(char *model) return W3V; else if (strncmp(model, "W5A", 3) == 0) return W5A; - else if (strncmp(model, "R1F", 3) == 0) - return R1F; else if (strncmp(model, "A4S", 3) == 0) return A4S; else if (strncmp(model, "F3Sa", 4) == 0) diff --git a/trunk/drivers/platform/x86/eeepc-laptop.c b/trunk/drivers/platform/x86/eeepc-laptop.c index 786ed8661cb0..9d93cb971e59 100644 --- a/trunk/drivers/platform/x86/eeepc-laptop.c +++ b/trunk/drivers/platform/x86/eeepc-laptop.c @@ -30,7 +30,6 @@ #include #include #include -#include #define EEEPC_LAPTOP_VERSION "0.1" @@ -162,10 +161,6 @@ static struct key_entry eeepc_keymap[] = { {KE_KEY, 0x13, KEY_MUTE }, {KE_KEY, 0x14, KEY_VOLUMEDOWN }, {KE_KEY, 0x15, KEY_VOLUMEUP }, - {KE_KEY, 0x1a, KEY_COFFEE }, - {KE_KEY, 0x1b, KEY_ZOOM }, - {KE_KEY, 0x1c, KEY_PROG2 }, - {KE_KEY, 0x1d, KEY_PROG3 }, {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, @@ -515,43 +510,7 @@ static int eeepc_hotk_check(void) static void notify_brn(void) { struct backlight_device *bd = eeepc_backlight_device; - if (bd) - bd->props.brightness = read_brightness(bd); -} - -static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) -{ - struct pci_dev *dev; - struct pci_bus *bus = pci_find_bus(0, 1); - - if (event != ACPI_NOTIFY_BUS_CHECK) - return; - - if (!bus) { - printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); - return; - } - - if (get_acpi(CM_ASL_WLAN) == 1) { - dev = pci_get_slot(bus, 0); - if (dev) { - /* Device already present */ - pci_dev_put(dev); - return; - } - dev = pci_scan_single_device(bus, 0); - if (dev) { - pci_bus_assign_resources(bus); - if (pci_bus_add_device(dev)) - printk(EEEPC_ERR "Unable to hotplug wifi\n"); - } - } else { - dev = pci_get_slot(bus, 0); - if (dev) { - pci_remove_bus_device(dev); - pci_dev_put(dev); - } - } + bd->props.brightness = read_brightness(bd); } static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) @@ -561,9 +520,8 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) return; if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) notify_brn(); - acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, - dev_name(&ehotk->device->dev), event, - ehotk->event_count[event % 128]++); + acpi_bus_generate_proc_event(ehotk->device, event, + ehotk->event_count[event % 128]++); if (ehotk->inputdev) { key = eepc_get_entry_by_scancode(event); if (key) { @@ -581,45 +539,6 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) } } -static int eeepc_register_rfkill_notifier(char *node) -{ - acpi_status status = AE_OK; - acpi_handle handle; - - status = acpi_get_handle(NULL, node, &handle); - - if (ACPI_SUCCESS(status)) { - status = acpi_install_notify_handler(handle, - ACPI_SYSTEM_NOTIFY, - eeepc_rfkill_notify, - NULL); - if (ACPI_FAILURE(status)) - printk(EEEPC_WARNING - "Failed to register notify on %s\n", node); - } else - return -ENODEV; - - return 0; -} - -static void eeepc_unregister_rfkill_notifier(char *node) -{ - acpi_status status = AE_OK; - acpi_handle handle; - - status = acpi_get_handle(NULL, node, &handle); - - if (ACPI_SUCCESS(status)) { - status = acpi_remove_notify_handler(handle, - ACPI_SYSTEM_NOTIFY, - eeepc_rfkill_notify); - if (ACPI_FAILURE(status)) - printk(EEEPC_ERR - "Error removing rfkill notify handler %s\n", - node); - } -} - static int eeepc_hotk_add(struct acpi_device *device) { acpi_status status = AE_OK; @@ -639,7 +558,7 @@ static int eeepc_hotk_add(struct acpi_device *device) ehotk->device = device; result = eeepc_hotk_check(); if (result) - goto ehotk_fail; + goto end; status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, eeepc_hotk_notify, ehotk); if (ACPI_FAILURE(status)) @@ -650,25 +569,18 @@ static int eeepc_hotk_add(struct acpi_device *device) RFKILL_TYPE_WLAN); if (!ehotk->eeepc_wlan_rfkill) - goto wlan_fail; + goto end; ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; - if (get_acpi(CM_ASL_WLAN) == 1) { + if (get_acpi(CM_ASL_WLAN) == 1) ehotk->eeepc_wlan_rfkill->state = RFKILL_STATE_UNBLOCKED; - rfkill_set_default(RFKILL_TYPE_WLAN, - RFKILL_STATE_UNBLOCKED); - } else { + else ehotk->eeepc_wlan_rfkill->state = RFKILL_STATE_SOFT_BLOCKED; - rfkill_set_default(RFKILL_TYPE_WLAN, - RFKILL_STATE_SOFT_BLOCKED); - } - result = rfkill_register(ehotk->eeepc_wlan_rfkill); - if (result) - goto wlan_fail; + rfkill_register(ehotk->eeepc_wlan_rfkill); } if (get_acpi(CM_ASL_BLUETOOTH) != -1) { @@ -676,47 +588,27 @@ static int eeepc_hotk_add(struct acpi_device *device) rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); if (!ehotk->eeepc_bluetooth_rfkill) - goto bluetooth_fail; + goto end; ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; ehotk->eeepc_bluetooth_rfkill->toggle_radio = eeepc_bluetooth_rfkill_set; ehotk->eeepc_bluetooth_rfkill->get_state = eeepc_bluetooth_rfkill_state; - if (get_acpi(CM_ASL_BLUETOOTH) == 1) { + if (get_acpi(CM_ASL_BLUETOOTH) == 1) ehotk->eeepc_bluetooth_rfkill->state = RFKILL_STATE_UNBLOCKED; - rfkill_set_default(RFKILL_TYPE_BLUETOOTH, - RFKILL_STATE_UNBLOCKED); - } else { + else ehotk->eeepc_bluetooth_rfkill->state = RFKILL_STATE_SOFT_BLOCKED; - rfkill_set_default(RFKILL_TYPE_BLUETOOTH, - RFKILL_STATE_SOFT_BLOCKED); - } - - result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); - if (result) - goto bluetooth_fail; + rfkill_register(ehotk->eeepc_bluetooth_rfkill); } - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); - - return 0; - - bluetooth_fail: - if (ehotk->eeepc_bluetooth_rfkill) - rfkill_free(ehotk->eeepc_bluetooth_rfkill); - rfkill_unregister(ehotk->eeepc_wlan_rfkill); - ehotk->eeepc_wlan_rfkill = NULL; - wlan_fail: - if (ehotk->eeepc_wlan_rfkill) - rfkill_free(ehotk->eeepc_wlan_rfkill); - ehotk_fail: - kfree(ehotk); - ehotk = NULL; - + end: + if (result) { + kfree(ehotk); + ehotk = NULL; + } return result; } @@ -730,10 +622,6 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) eeepc_hotk_notify); if (ACPI_FAILURE(status)) printk(EEEPC_ERR "Error removing notify handler\n"); - - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); - kfree(ehotk); return 0; } @@ -849,21 +737,13 @@ static void eeepc_backlight_exit(void) { if (eeepc_backlight_device) backlight_device_unregister(eeepc_backlight_device); - eeepc_backlight_device = NULL; -} - -static void eeepc_rfkill_exit(void) -{ + if (ehotk->inputdev) + input_unregister_device(ehotk->inputdev); if (ehotk->eeepc_wlan_rfkill) rfkill_unregister(ehotk->eeepc_wlan_rfkill); if (ehotk->eeepc_bluetooth_rfkill) rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); -} - -static void eeepc_input_exit(void) -{ - if (ehotk->inputdev) - input_unregister_device(ehotk->inputdev); + eeepc_backlight_device = NULL; } static void eeepc_hwmon_exit(void) @@ -882,8 +762,6 @@ static void eeepc_hwmon_exit(void) static void __exit eeepc_laptop_exit(void) { eeepc_backlight_exit(); - eeepc_rfkill_exit(); - eeepc_input_exit(); eeepc_hwmon_exit(); acpi_bus_unregister_driver(&eeepc_hotk_driver); sysfs_remove_group(&platform_device->dev.kobj, @@ -987,8 +865,6 @@ static int __init eeepc_laptop_init(void) fail_hwmon: eeepc_backlight_exit(); fail_backlight: - eeepc_input_exit(); - eeepc_rfkill_exit(); return result; } diff --git a/trunk/drivers/platform/x86/fujitsu-laptop.c b/trunk/drivers/platform/x86/fujitsu-laptop.c index 45940f31fe9e..65dc41540c62 100644 --- a/trunk/drivers/platform/x86/fujitsu-laptop.c +++ b/trunk/drivers/platform/x86/fujitsu-laptop.c @@ -166,7 +166,6 @@ struct fujitsu_hotkey_t { struct platform_device *pf_device; struct kfifo *fifo; spinlock_t fifo_lock; - int rfkill_supported; int rfkill_state; int logolamp_registered; int kblamps_registered; @@ -527,7 +526,7 @@ static ssize_t show_lid_state(struct device *dev, struct device_attribute *attr, char *buf) { - if (!(fujitsu_hotkey->rfkill_supported & 0x100)) + if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) return sprintf(buf, "unknown\n"); if (fujitsu_hotkey->rfkill_state & 0x100) return sprintf(buf, "open\n"); @@ -539,7 +538,7 @@ static ssize_t show_dock_state(struct device *dev, struct device_attribute *attr, char *buf) { - if (!(fujitsu_hotkey->rfkill_supported & 0x200)) + if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) return sprintf(buf, "unknown\n"); if (fujitsu_hotkey->rfkill_state & 0x200) return sprintf(buf, "docked\n"); @@ -551,7 +550,7 @@ static ssize_t show_radios_state(struct device *dev, struct device_attribute *attr, char *buf) { - if (!(fujitsu_hotkey->rfkill_supported & 0x20)) + if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) return sprintf(buf, "unknown\n"); if (fujitsu_hotkey->rfkill_state & 0x20) return sprintf(buf, "on\n"); @@ -929,17 +928,8 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) ; /* No action, result is discarded */ vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i); - fujitsu_hotkey->rfkill_supported = - call_fext_func(FUNC_RFKILL, 0x0, 0x0, 0x0); - - /* Make sure our bitmask of supported functions is cleared if the - RFKILL function block is not implemented, like on the S7020. */ - if (fujitsu_hotkey->rfkill_supported == UNSUPPORTED_CMD) - fujitsu_hotkey->rfkill_supported = 0; - - if (fujitsu_hotkey->rfkill_supported) - fujitsu_hotkey->rfkill_state = - call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); + fujitsu_hotkey->rfkill_state = + call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); /* Suspect this is a keymap of the application panel, print it */ printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n", @@ -1015,9 +1005,8 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, input = fujitsu_hotkey->input; - if (fujitsu_hotkey->rfkill_supported) - fujitsu_hotkey->rfkill_state = - call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); + fujitsu_hotkey->rfkill_state = + call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); switch (event) { case ACPI_FUJITSU_NOTIFY_CODE1: diff --git a/trunk/drivers/platform/x86/hp-wmi.c b/trunk/drivers/platform/x86/hp-wmi.c index f41135f2fb29..de91ddab0a86 100644 --- a/trunk/drivers/platform/x86/hp-wmi.c +++ b/trunk/drivers/platform/x86/hp-wmi.c @@ -463,11 +463,9 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) return 0; register_wwan_err: - if (bluetooth_rfkill) - rfkill_unregister(bluetooth_rfkill); + rfkill_unregister(bluetooth_rfkill); register_bluetooth_error: - if (wifi_rfkill) - rfkill_unregister(wifi_rfkill); + rfkill_unregister(wifi_rfkill); add_sysfs_error: cleanup_sysfs(device); return err; diff --git a/trunk/drivers/platform/x86/panasonic-laptop.c b/trunk/drivers/platform/x86/panasonic-laptop.c index c47a44dcb702..f30db367c82e 100644 --- a/trunk/drivers/platform/x86/panasonic-laptop.c +++ b/trunk/drivers/platform/x86/panasonic-laptop.c @@ -507,7 +507,7 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) hkey_num = result & 0xf; - if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) { + if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "hotkey number out of range: %d\n", hkey_num)); diff --git a/trunk/drivers/power/pcf50633-charger.c b/trunk/drivers/power/pcf50633-charger.c index 41aec2acbb91..e988ec130fcd 100644 --- a/trunk/drivers/power/pcf50633-charger.c +++ b/trunk/drivers/power/pcf50633-charger.c @@ -199,8 +199,7 @@ static int adapter_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { - struct pcf50633_mbc *mbc = container_of(psy, - struct pcf50633_mbc, adapter); + struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb); int ret = 0; switch (psp) { diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 81450fbd8b12..cced4d108319 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -241,12 +241,6 @@ config RTC_DRV_M41T80_WDT If you say Y here you will get support for the watchdog timer in the ST M41T60 and M41T80 RTC chips series. -config RTC_DRV_DM355EVM - tristate "TI DaVinci DM355 EVM RTC" - depends on MFD_DM355EVM_MSP - help - Supports the RTC firmware in the MSP430 on the DM355 EVM. - config RTC_DRV_TWL92330 boolean "TI TWL92330/Menelaus" depends on MENELAUS diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index 0e697aa51caa..6e28021abb9d 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -23,7 +23,6 @@ obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o -obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o diff --git a/trunk/drivers/rtc/rtc-au1xxx.c b/trunk/drivers/rtc/rtc-au1xxx.c index 979ed0406ce9..8906a688e6a6 100644 --- a/trunk/drivers/rtc/rtc-au1xxx.c +++ b/trunk/drivers/rtc/rtc-au1xxx.c @@ -81,7 +81,7 @@ static int __devinit au1xtoy_rtc_probe(struct platform_device *pdev) if (au_readl(SYS_TOYTRIM) != 32767) { /* wait until hardware gives access to TRIM register */ t = 0x00100000; - while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && --t) + while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && t--) msleep(1); if (!t) { diff --git a/trunk/drivers/rtc/rtc-dm355evm.c b/trunk/drivers/rtc/rtc-dm355evm.c deleted file mode 100644 index 58d4e18530da..000000000000 --- a/trunk/drivers/rtc/rtc-dm355evm.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * rtc-dm355evm.c - access battery-backed counter in MSP430 firmware - * - * Copyright (c) 2008 by David Brownell - * - * 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. - */ -#include -#include -#include -#include - -#include - - -/* - * The MSP430 firmware on the DM355 EVM uses a watch crystal to feed - * a 1 Hz counter. When a backup battery is supplied, that makes a - * reasonable RTC for applications where alarms and non-NTP drift - * compensation aren't important. - * - * The only real glitch is the inability to read or write all four - * counter bytes atomically: the count may increment in the middle - * of an operation, causing trouble when the LSB rolls over. - * - * This driver was tested with firmware revision A4. - */ -union evm_time { - u8 bytes[4]; - u32 value; -}; - -static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - union evm_time time; - int status; - int tries = 0; - - do { - /* - * Read LSB(0) to MSB(3) bytes. Defend against the counter - * rolling over by re-reading until the value is stable, - * and assuming the four reads take at most a few seconds. - */ - status = dm355evm_msp_read(DM355EVM_MSP_RTC_0); - if (status < 0) - return status; - if (tries && time.bytes[0] == status) - break; - time.bytes[0] = status; - - status = dm355evm_msp_read(DM355EVM_MSP_RTC_1); - if (status < 0) - return status; - if (tries && time.bytes[1] == status) - break; - time.bytes[1] = status; - - status = dm355evm_msp_read(DM355EVM_MSP_RTC_2); - if (status < 0) - return status; - if (tries && time.bytes[2] == status) - break; - time.bytes[2] = status; - - status = dm355evm_msp_read(DM355EVM_MSP_RTC_3); - if (status < 0) - return status; - if (tries && time.bytes[3] == status) - break; - time.bytes[3] = status; - - } while (++tries < 5); - - dev_dbg(dev, "read timestamp %08x\n", time.value); - - rtc_time_to_tm(le32_to_cpu(time.value), tm); - return 0; -} - -static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - union evm_time time; - unsigned long value; - int status; - - rtc_tm_to_time(tm, &value); - time.value = cpu_to_le32(value); - - dev_dbg(dev, "write timestamp %08x\n", time.value); - - /* - * REVISIT handle non-atomic writes ... maybe just retry until - * byte[1] sticks (no rollover)? - */ - status = dm355evm_msp_write(time.bytes[0], DM355EVM_MSP_RTC_0); - if (status < 0) - return status; - - status = dm355evm_msp_write(time.bytes[1], DM355EVM_MSP_RTC_1); - if (status < 0) - return status; - - status = dm355evm_msp_write(time.bytes[2], DM355EVM_MSP_RTC_2); - if (status < 0) - return status; - - status = dm355evm_msp_write(time.bytes[3], DM355EVM_MSP_RTC_3); - if (status < 0) - return status; - - return 0; -} - -static struct rtc_class_ops dm355evm_rtc_ops = { - .read_time = dm355evm_rtc_read_time, - .set_time = dm355evm_rtc_set_time, -}; - -/*----------------------------------------------------------------------*/ - -static int __devinit dm355evm_rtc_probe(struct platform_device *pdev) -{ - struct rtc_device *rtc; - - rtc = rtc_device_register(pdev->name, - &pdev->dev, &dm355evm_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - dev_err(&pdev->dev, "can't register RTC device, err %ld\n", - PTR_ERR(rtc)); - return PTR_ERR(rtc); - } - platform_set_drvdata(pdev, rtc); - - return 0; -} - -static int __devexit dm355evm_rtc_remove(struct platform_device *pdev) -{ - struct rtc_device *rtc = platform_get_drvdata(pdev); - - rtc_device_unregister(rtc); - platform_set_drvdata(pdev, NULL); - return 0; -} - -/* - * I2C is used to talk to the MSP430, but this platform device is - * exposed by an MFD driver that manages I2C communications. - */ -static struct platform_driver rtc_dm355evm_driver = { - .probe = dm355evm_rtc_probe, - .remove = __devexit_p(dm355evm_rtc_remove), - .driver = { - .owner = THIS_MODULE, - .name = "rtc-dm355evm", - }, -}; - -static int __init dm355evm_rtc_init(void) -{ - return platform_driver_register(&rtc_dm355evm_driver); -} -module_init(dm355evm_rtc_init); - -static void __exit dm355evm_rtc_exit(void) -{ - platform_driver_unregister(&rtc_dm355evm_driver); -} -module_exit(dm355evm_rtc_exit); - -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-ds1390.c b/trunk/drivers/rtc/rtc-ds1390.c index e01b955db077..e54b5c619bdf 100644 --- a/trunk/drivers/rtc/rtc-ds1390.c +++ b/trunk/drivers/rtc/rtc-ds1390.c @@ -122,6 +122,7 @@ static const struct rtc_class_ops ds1390_rtc_ops = { static int __devinit ds1390_probe(struct spi_device *spi) { + struct rtc_device *rtc; unsigned char tmp; struct ds1390 *chip; int res; diff --git a/trunk/drivers/rtc/rtc-pxa.c b/trunk/drivers/rtc/rtc-pxa.c index bb8cc05605ac..bd56a033bfd0 100644 --- a/trunk/drivers/rtc/rtc-pxa.c +++ b/trunk/drivers/rtc/rtc-pxa.c @@ -485,7 +485,7 @@ static void __exit pxa_rtc_exit(void) module_init(pxa_rtc_init); module_exit(pxa_rtc_exit); -MODULE_AUTHOR("Robert Jarzmik "); +MODULE_AUTHOR("Robert Jarzmik"); MODULE_DESCRIPTION("PXA27x/PXA3xx Realtime Clock Driver (RTC)"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:pxa-rtc"); diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 08c23a921012..bd5914994142 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -57,8 +57,6 @@ static void dasd_device_tasklet(struct dasd_device *); static void dasd_block_tasklet(struct dasd_block *); static void do_kick_device(struct work_struct *); static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *); -static void dasd_device_timeout(unsigned long); -static void dasd_block_timeout(unsigned long); /* * SECTION: Operations on the device structure. @@ -101,8 +99,6 @@ struct dasd_device *dasd_alloc_device(void) (unsigned long) device); INIT_LIST_HEAD(&device->ccw_queue); init_timer(&device->timer); - device->timer.function = dasd_device_timeout; - device->timer.data = (unsigned long) device; INIT_WORK(&device->kick_work, do_kick_device); device->state = DASD_STATE_NEW; device->target = DASD_STATE_NEW; @@ -142,8 +138,6 @@ struct dasd_block *dasd_alloc_block(void) INIT_LIST_HEAD(&block->ccw_queue); spin_lock_init(&block->queue_lock); init_timer(&block->timer); - block->timer.function = dasd_block_timeout; - block->timer.data = (unsigned long) block; return block; } @@ -921,10 +915,19 @@ static void dasd_device_timeout(unsigned long ptr) */ void dasd_device_set_timer(struct dasd_device *device, int expires) { - if (expires == 0) - del_timer(&device->timer); - else - mod_timer(&device->timer, jiffies + expires); + if (expires == 0) { + if (timer_pending(&device->timer)) + del_timer(&device->timer); + return; + } + if (timer_pending(&device->timer)) { + if (mod_timer(&device->timer, jiffies + expires)) + return; + } + device->timer.function = dasd_device_timeout; + device->timer.data = (unsigned long) device; + device->timer.expires = jiffies + expires; + add_timer(&device->timer); } /* @@ -932,7 +935,8 @@ void dasd_device_set_timer(struct dasd_device *device, int expires) */ void dasd_device_clear_timer(struct dasd_device *device) { - del_timer(&device->timer); + if (timer_pending(&device->timer)) + del_timer(&device->timer); } static void dasd_handle_killed_request(struct ccw_device *cdev, @@ -1582,10 +1586,19 @@ static void dasd_block_timeout(unsigned long ptr) */ void dasd_block_set_timer(struct dasd_block *block, int expires) { - if (expires == 0) - del_timer(&block->timer); - else - mod_timer(&block->timer, jiffies + expires); + if (expires == 0) { + if (timer_pending(&block->timer)) + del_timer(&block->timer); + return; + } + if (timer_pending(&block->timer)) { + if (mod_timer(&block->timer, jiffies + expires)) + return; + } + block->timer.function = dasd_block_timeout; + block->timer.data = (unsigned long) block; + block->timer.expires = jiffies + expires; + add_timer(&block->timer); } /* @@ -1593,7 +1606,8 @@ void dasd_block_set_timer(struct dasd_block *block, int expires) */ void dasd_block_clear_timer(struct dasd_block *block) { - del_timer(&block->timer); + if (timer_pending(&block->timer)) + del_timer(&block->timer); } /* diff --git a/trunk/drivers/s390/block/dasd_devmap.c b/trunk/drivers/s390/block/dasd_devmap.c index 34339902efb9..300e28a531f8 100644 --- a/trunk/drivers/s390/block/dasd_devmap.c +++ b/trunk/drivers/s390/block/dasd_devmap.c @@ -677,7 +677,7 @@ static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr, struct dasd_devmap *devmap; int ff_flag; - devmap = dasd_find_busid(dev_name(dev)); + devmap = dasd_find_busid(dev->bus_id); if (!IS_ERR(devmap)) ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0; else diff --git a/trunk/drivers/s390/char/sclp.c b/trunk/drivers/s390/char/sclp.c index 4377e93a43d7..1fd8f2193ed8 100644 --- a/trunk/drivers/s390/char/sclp.c +++ b/trunk/drivers/s390/char/sclp.c @@ -280,11 +280,8 @@ sclp_dispatch_evbufs(struct sccb_header *sccb) rc = 0; for (offset = sizeof(struct sccb_header); offset < sccb->length; offset += evbuf->length) { - evbuf = (struct evbuf_header *) ((addr_t) sccb + offset); - /* Check for malformed hardware response */ - if (evbuf->length == 0) - break; /* Search for event handler */ + evbuf = (struct evbuf_header *) ((addr_t) sccb + offset); reg = NULL; list_for_each(l, &sclp_reg_list) { reg = list_entry(l, struct sclp_register, list); diff --git a/trunk/drivers/s390/char/sclp_cmd.c b/trunk/drivers/s390/char/sclp_cmd.c index 77ab6e34a100..506390496416 100644 --- a/trunk/drivers/s390/char/sclp_cmd.c +++ b/trunk/drivers/s390/char/sclp_cmd.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "sclp.h" @@ -475,10 +474,6 @@ static void __init add_memory_merged(u16 rn) goto skip_add; if (start + size > VMEM_MAX_PHYS) size = VMEM_MAX_PHYS - start; - if (memory_end_set && (start >= memory_end)) - goto skip_add; - if (memory_end_set && (start + size > memory_end)) - size = memory_end - start; add_memory(0, start, size); skip_add: first_rn = rn; diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i.h b/trunk/drivers/scsi/cxgb3i/cxgb3i.h index a7cf550b9cca..fde6e4c634e7 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i.h +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i.h @@ -20,7 +20,6 @@ #include #include #include -#include #include /* from cxgb3 LLD */ @@ -114,26 +113,6 @@ struct cxgb3i_endpoint { struct cxgb3i_conn *cconn; }; -/** - * struct cxgb3i_task_data - private iscsi task data - * - * @nr_frags: # of coalesced page frags (from scsi sgl) - * @frags: coalesced page frags (from scsi sgl) - * @skb: tx pdu skb - * @offset: data offset for the next pdu - * @count: max. possible pdu payload - * @sgoffset: offset to the first sg entry for a given offset - */ -#define MAX_PDU_FRAGS ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512) -struct cxgb3i_task_data { - unsigned short nr_frags; - skb_frag_t frags[MAX_PDU_FRAGS]; - struct sk_buff *skb; - unsigned int offset; - unsigned int count; - unsigned int sgoffset; -}; - int cxgb3i_iscsi_init(void); void cxgb3i_iscsi_cleanup(void); diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.c index a83d36e4926f..08f3a09d9233 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.c +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.c @@ -639,11 +639,10 @@ static int ddp_init(struct t3cdev *tdev) write_unlock(&cxgb3i_ddp_rwlock); ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x " - "pkt %u/%u, %u/%u.\n", + "pkt %u,%u.\n", ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits, ddp->idx_mask, ddp->rsvd_tag_mask, - ddp->max_txsz, uinfo.max_txsz, - ddp->max_rxsz, uinfo.max_rxsz); + ddp->max_txsz, ddp->max_rxsz); return 0; free_ddp_map: @@ -655,8 +654,8 @@ static int ddp_init(struct t3cdev *tdev) * cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource * @tdev: t3cdev adapter * @tformat: tag format - * @txsz: max tx pdu payload size, filled in by this func. - * @rxsz: max rx pdu payload size, filled in by this func. + * @txsz: max tx pkt size, filled in by this func. + * @rxsz: max rx pkt size, filled in by this func. * initialize the ddp pagepod manager for a given adapter if needed and * setup the tag format for a given iscsi entity */ @@ -686,12 +685,10 @@ int cxgb3i_adapter_ddp_init(struct t3cdev *tdev, tformat->sw_bits, tformat->rsvd_bits, tformat->rsvd_shift, tformat->rsvd_mask); - *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, - ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN); - *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, - ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN); - ddp_log_info("max payload size: %u/%u, %u/%u.\n", - *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz); + *txsz = ddp->max_txsz; + *rxsz = ddp->max_rxsz; + ddp_log_info("ddp max pkt size: %u, %u.\n", + ddp->max_txsz, ddp->max_rxsz); return 0; } EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init); diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.h index 3faae7831c83..5c7c4d95c493 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.h +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.h @@ -13,8 +13,6 @@ #ifndef __CXGB3I_ULP2_DDP_H__ #define __CXGB3I_ULP2_DDP_H__ -#include - /** * struct cxgb3i_tag_format - cxgb3i ulp tag format for an iscsi entity * @@ -87,9 +85,8 @@ struct cxgb3i_ddp_info { struct sk_buff **gl_skb; }; -#define ISCSI_PDU_NONPAYLOAD_LEN 312 /* bhs(48) + ahs(256) + digest(8) */ #define ULP2_MAX_PKT_SIZE 16224 -#define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN) +#define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_MAX) #define PPOD_PAGES_MAX 4 #define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */ diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_init.c b/trunk/drivers/scsi/cxgb3i/cxgb3i_init.c index 1ce9f244e46c..091ecb4d9f3d 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_init.c +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_init.c @@ -12,8 +12,8 @@ #include "cxgb3i.h" #define DRV_MODULE_NAME "cxgb3i" -#define DRV_MODULE_VERSION "1.0.1" -#define DRV_MODULE_RELDATE "Jan. 2009" +#define DRV_MODULE_VERSION "1.0.0" +#define DRV_MODULE_RELDATE "Jun. 1, 2008" static char version[] = "Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/trunk/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index fa2a44f37b36..d83464b9b3f9 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_iscsi.c @@ -364,8 +364,7 @@ cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth, cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost, cmds_max, - sizeof(struct iscsi_tcp_task) + - sizeof(struct cxgb3i_task_data), + sizeof(struct iscsi_tcp_task), initial_cmdsn, ISCSI_MAX_TARGET); if (!cls_session) return NULL; @@ -403,15 +402,17 @@ static inline int cxgb3i_conn_max_xmit_dlength(struct iscsi_conn *conn) { struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct cxgb3i_conn *cconn = tcp_conn->dd_data; - unsigned int max = max(512 * MAX_SKB_FRAGS, SKB_TX_HEADROOM); + unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, + cconn->hba->snic->tx_max_size - + ISCSI_PDU_NONPAYLOAD_MAX); - max = min(cconn->hba->snic->tx_max_size, max); if (conn->max_xmit_dlength) - conn->max_xmit_dlength = min(conn->max_xmit_dlength, max); + conn->max_xmit_dlength = min_t(unsigned int, + conn->max_xmit_dlength, max); else conn->max_xmit_dlength = max; align_pdu_size(conn->max_xmit_dlength); - cxgb3i_api_debug("conn 0x%p, max xmit %u.\n", + cxgb3i_log_info("conn 0x%p, max xmit %u.\n", conn, conn->max_xmit_dlength); return 0; } @@ -426,7 +427,9 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn) { struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct cxgb3i_conn *cconn = tcp_conn->dd_data; - unsigned int max = cconn->hba->snic->rx_max_size; + unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, + cconn->hba->snic->rx_max_size - + ISCSI_PDU_NONPAYLOAD_MAX); align_pdu_size(max); if (conn->max_recv_dlength) { @@ -436,7 +439,8 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn) conn->max_recv_dlength, max); return -EINVAL; } - conn->max_recv_dlength = min(conn->max_recv_dlength, max); + conn->max_recv_dlength = min_t(unsigned int, + conn->max_recv_dlength, max); align_pdu_size(conn->max_recv_dlength); } else conn->max_recv_dlength = max; @@ -840,7 +844,7 @@ static struct scsi_host_template cxgb3i_host_template = { .proc_name = "cxgb3i", .queuecommand = iscsi_queuecommand, .change_queue_depth = iscsi_change_queue_depth, - .can_queue = CXGB3I_SCSI_QDEPTH_DFLT - 1, + .can_queue = 128 * (ISCSI_DEF_XMIT_CMDS_MAX - 1), .sg_tablesize = SG_ALL, .max_sectors = 0xFFFF, .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_offload.c b/trunk/drivers/scsi/cxgb3i/cxgb3i_offload.c index de3b3b614cca..a865f1fefe8b 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_offload.c @@ -23,19 +23,19 @@ #include "cxgb3i_ddp.h" #ifdef __DEBUG_C3CN_CONN__ -#define c3cn_conn_debug cxgb3i_log_debug +#define c3cn_conn_debug cxgb3i_log_info #else #define c3cn_conn_debug(fmt...) #endif #ifdef __DEBUG_C3CN_TX__ -#define c3cn_tx_debug cxgb3i_log_debug +#define c3cn_tx_debug cxgb3i_log_debug #else #define c3cn_tx_debug(fmt...) #endif #ifdef __DEBUG_C3CN_RX__ -#define c3cn_rx_debug cxgb3i_log_debug +#define c3cn_rx_debug cxgb3i_log_debug #else #define c3cn_rx_debug(fmt...) #endif @@ -47,9 +47,9 @@ static int cxgb3_rcv_win = 256 * 1024; module_param(cxgb3_rcv_win, int, 0644); MODULE_PARM_DESC(cxgb3_rcv_win, "TCP receive window in bytes (default=256KB)"); -static int cxgb3_snd_win = 128 * 1024; +static int cxgb3_snd_win = 64 * 1024; module_param(cxgb3_snd_win, int, 0644); -MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=128KB)"); +MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=64KB)"); static int cxgb3_rx_credit_thres = 10 * 1024; module_param(cxgb3_rx_credit_thres, int, 0644); @@ -301,8 +301,8 @@ static void act_open_req_arp_failure(struct t3cdev *dev, struct sk_buff *skb) static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb, int flags) { - skb_tcp_seq(skb) = c3cn->write_seq; - skb_flags(skb) = flags; + CXGB3_SKB_CB(skb)->seq = c3cn->write_seq; + CXGB3_SKB_CB(skb)->flags = flags; __skb_queue_tail(&c3cn->write_queue, skb); } @@ -457,9 +457,12 @@ static unsigned int wrlen __read_mostly; * The number of WRs needed for an skb depends on the number of fragments * in the skb and whether it has any payload in its main body. This maps the * length of the gather list represented by an skb into the # of necessary WRs. - * The extra two fragments are for iscsi bhs and payload padding. + * + * The max. length of an skb is controlled by the max pdu size which is ~16K. + * Also, assume the min. fragment length is the sector size (512), then add + * extra fragment counts for iscsi bhs and payload padding. */ -#define SKB_WR_LIST_SIZE (MAX_SKB_FRAGS + 2) +#define SKB_WR_LIST_SIZE (16384/512 + 3) static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly; static void s3_init_wr_tab(unsigned int wr_len) @@ -482,7 +485,7 @@ static void s3_init_wr_tab(unsigned int wr_len) static inline void reset_wr_list(struct s3_conn *c3cn) { - c3cn->wr_pending_head = c3cn->wr_pending_tail = NULL; + c3cn->wr_pending_head = NULL; } /* @@ -493,7 +496,7 @@ static inline void reset_wr_list(struct s3_conn *c3cn) static inline void enqueue_wr(struct s3_conn *c3cn, struct sk_buff *skb) { - skb_tx_wr_next(skb) = NULL; + skb_wr_data(skb) = NULL; /* * We want to take an extra reference since both us and the driver @@ -506,22 +509,10 @@ static inline void enqueue_wr(struct s3_conn *c3cn, if (!c3cn->wr_pending_head) c3cn->wr_pending_head = skb; else - skb_tx_wr_next(c3cn->wr_pending_tail) = skb; + skb_wr_data(skb) = skb; c3cn->wr_pending_tail = skb; } -static int count_pending_wrs(struct s3_conn *c3cn) -{ - int n = 0; - const struct sk_buff *skb = c3cn->wr_pending_head; - - while (skb) { - n += skb->csum; - skb = skb_tx_wr_next(skb); - } - return n; -} - static inline struct sk_buff *peek_wr(const struct s3_conn *c3cn) { return c3cn->wr_pending_head; @@ -538,8 +529,8 @@ static inline struct sk_buff *dequeue_wr(struct s3_conn *c3cn) if (likely(skb)) { /* Don't bother clearing the tail */ - c3cn->wr_pending_head = skb_tx_wr_next(skb); - skb_tx_wr_next(skb) = NULL; + c3cn->wr_pending_head = skb_wr_data(skb); + skb_wr_data(skb) = NULL; } return skb; } @@ -552,14 +543,13 @@ static void purge_wr_queue(struct s3_conn *c3cn) } static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb, - int len, int req_completion) + int len) { struct tx_data_wr *req; skb_reset_transport_header(skb); req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req)); - req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA) | - (req_completion ? F_WR_COMPL : 0)); + req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); req->wr_lo = htonl(V_WR_TID(c3cn->tid)); req->sndseq = htonl(c3cn->snd_nxt); /* len includes the length of any HW ULP additions */ @@ -602,7 +592,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion) if (unlikely(c3cn->state == C3CN_STATE_CONNECTING || c3cn->state == C3CN_STATE_CLOSE_WAIT_1 || - c3cn->state >= C3CN_STATE_ABORTING)) { + c3cn->state == C3CN_STATE_ABORTING)) { c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n", c3cn, c3cn->state); return 0; @@ -625,7 +615,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion) if (c3cn->wr_avail < wrs_needed) { c3cn_tx_debug("c3cn 0x%p, skb len %u/%u, frag %u, " "wr %d < %u.\n", - c3cn, skb->len, skb->data_len, frags, + c3cn, skb->len, skb->datalen, frags, wrs_needed, c3cn->wr_avail); break; } @@ -637,24 +627,20 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion) c3cn->wr_unacked += wrs_needed; enqueue_wr(c3cn, skb); - c3cn_tx_debug("c3cn 0x%p, enqueue, skb len %u/%u, frag %u, " - "wr %d, left %u, unack %u.\n", - c3cn, skb->len, skb->data_len, frags, - wrs_needed, c3cn->wr_avail, c3cn->wr_unacked); - + if (likely(CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_NEED_HDR)) { + len += ulp_extra_len(skb); + make_tx_data_wr(c3cn, skb, len); + c3cn->snd_nxt += len; + if ((req_completion + && c3cn->wr_unacked == wrs_needed) + || (CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_COMPL) + || c3cn->wr_unacked >= c3cn->wr_max / 2) { + struct work_request_hdr *wr = cplhdr(skb); - if (likely(skb_flags(skb) & C3CB_FLAG_NEED_HDR)) { - if ((req_completion && - c3cn->wr_unacked == wrs_needed) || - (skb_flags(skb) & C3CB_FLAG_COMPL) || - c3cn->wr_unacked >= c3cn->wr_max / 2) { - req_completion = 1; + wr->wr_hi |= htonl(F_WR_COMPL); c3cn->wr_unacked = 0; } - len += ulp_extra_len(skb); - make_tx_data_wr(c3cn, skb, len, req_completion); - c3cn->snd_nxt += len; - skb_flags(skb) &= ~C3CB_FLAG_NEED_HDR; + CXGB3_SKB_CB(skb)->flags &= ~C3CB_FLAG_NEED_HDR; } total_size += skb->truesize; @@ -749,11 +735,8 @@ static void process_act_establish(struct s3_conn *c3cn, struct sk_buff *skb) if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED))) /* upper layer has requested closing */ send_abort_req(c3cn); - else { - if (skb_queue_len(&c3cn->write_queue)) - c3cn_push_tx_frames(c3cn, 1); + else if (c3cn_push_tx_frames(c3cn, 1)) cxgb3i_conn_tx_open(c3cn); - } } static int do_act_establish(struct t3cdev *cdev, struct sk_buff *skb, @@ -1099,8 +1082,8 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb) return; } - skb_tcp_seq(skb) = ntohl(hdr_cpl->seq); - skb_flags(skb) = 0; + CXGB3_SKB_CB(skb)->seq = ntohl(hdr_cpl->seq); + CXGB3_SKB_CB(skb)->flags = 0; skb_reset_transport_header(skb); __skb_pull(skb, sizeof(struct cpl_iscsi_hdr)); @@ -1120,12 +1103,12 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb) goto abort_conn; skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY; - skb_rx_pdulen(skb) = ntohs(ddp_cpl.len); - skb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); + skb_ulp_pdulen(skb) = ntohs(ddp_cpl.len); + skb_ulp_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); status = ntohl(ddp_cpl.ddp_status); c3cn_rx_debug("rx skb 0x%p, len %u, pdulen %u, ddp status 0x%x.\n", - skb, skb->len, skb_rx_pdulen(skb), status); + skb, skb->len, skb_ulp_pdulen(skb), status); if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT)) skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR; @@ -1143,7 +1126,7 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb) } else if (status & (1 << RX_DDP_STATUS_DDP_SHIFT)) skb_ulp_mode(skb) |= ULP2_FLAG_DATA_DDPED; - c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_rx_pdulen(skb); + c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_ulp_pdulen(skb); __pskb_trim(skb, len); __skb_queue_tail(&c3cn->receive_queue, skb); cxgb3i_conn_pdu_ready(c3cn); @@ -1168,27 +1151,12 @@ static int do_iscsi_hdr(struct t3cdev *t3dev, struct sk_buff *skb, void *ctx) * Process an acknowledgment of WR completion. Advance snd_una and send the * next batch of work requests from the write queue. */ -static void check_wr_invariants(struct s3_conn *c3cn) -{ - int pending = count_pending_wrs(c3cn); - - if (unlikely(c3cn->wr_avail + pending != c3cn->wr_max)) - cxgb3i_log_error("TID %u: credit imbalance: avail %u, " - "pending %u, total should be %u\n", - c3cn->tid, c3cn->wr_avail, pending, - c3cn->wr_max); -} - static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) { struct cpl_wr_ack *hdr = cplhdr(skb); unsigned int credits = ntohs(hdr->credits); u32 snd_una = ntohl(hdr->snd_una); - c3cn_tx_debug("%u WR credits, avail %u, unack %u, TID %u, state %u.\n", - credits, c3cn->wr_avail, c3cn->wr_unacked, - c3cn->tid, c3cn->state); - c3cn->wr_avail += credits; if (c3cn->wr_unacked > c3cn->wr_max - c3cn->wr_avail) c3cn->wr_unacked = c3cn->wr_max - c3cn->wr_avail; @@ -1203,17 +1171,6 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) break; } if (unlikely(credits < p->csum)) { - struct tx_data_wr *w = cplhdr(p); - cxgb3i_log_error("TID %u got %u WR credits need %u, " - "len %u, main body %u, frags %u, " - "seq # %u, ACK una %u, ACK nxt %u, " - "WR_AVAIL %u, WRs pending %u\n", - c3cn->tid, credits, p->csum, p->len, - p->len - p->data_len, - skb_shinfo(p)->nr_frags, - ntohl(w->sndseq), snd_una, - ntohl(hdr->snd_nxt), c3cn->wr_avail, - count_pending_wrs(c3cn) - credits); p->csum -= credits; break; } else { @@ -1223,24 +1180,15 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) } } - check_wr_invariants(c3cn); - - if (unlikely(before(snd_una, c3cn->snd_una))) { - cxgb3i_log_error("TID %u, unexpected sequence # %u in WR_ACK " - "snd_una %u\n", - c3cn->tid, snd_una, c3cn->snd_una); + if (unlikely(before(snd_una, c3cn->snd_una))) goto out_free; - } if (c3cn->snd_una != snd_una) { c3cn->snd_una = snd_una; dst_confirm(c3cn->dst_cache); } - if (skb_queue_len(&c3cn->write_queue)) { - if (c3cn_push_tx_frames(c3cn, 0)) - cxgb3i_conn_tx_open(c3cn); - } else + if (skb_queue_len(&c3cn->write_queue) && c3cn_push_tx_frames(c3cn, 0)) cxgb3i_conn_tx_open(c3cn); out_free: __kfree_skb(skb); @@ -1504,7 +1452,7 @@ static void init_offload_conn(struct s3_conn *c3cn, struct dst_entry *dst) { BUG_ON(c3cn->cdev != cdev); - c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs - 1; + c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs; c3cn->wr_unacked = 0; c3cn->mss_idx = select_mss(c3cn, dst_mtu(dst)); @@ -1723,17 +1671,9 @@ int cxgb3i_c3cn_send_pdus(struct s3_conn *c3cn, struct sk_buff *skb) goto out_err; } + err = -EPIPE; if (c3cn->err) { c3cn_tx_debug("c3cn 0x%p, err %d.\n", c3cn, c3cn->err); - err = -EPIPE; - goto out_err; - } - - if (c3cn->write_seq - c3cn->snd_una >= cxgb3_snd_win) { - c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n", - c3cn, c3cn->write_seq, c3cn->snd_una, - cxgb3_snd_win); - err = -EAGAIN; goto out_err; } diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_offload.h b/trunk/drivers/scsi/cxgb3i/cxgb3i_offload.h index 6344b9eb2589..d23156907ffd 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_offload.h +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_offload.h @@ -178,33 +178,25 @@ void cxgb3i_c3cn_release(struct s3_conn *); * @flag: see C3CB_FLAG_* below * @ulp_mode: ULP mode/submode of sk_buff * @seq: tcp sequence number + * @ddigest: pdu data digest + * @pdulen: recovered pdu length + * @wr_data: scratch area for tx wr */ -struct cxgb3_skb_rx_cb { - __u32 ddigest; /* data digest */ - __u32 pdulen; /* recovered pdu length */ -}; - -struct cxgb3_skb_tx_cb { - struct sk_buff *wr_next; /* next wr */ -}; - struct cxgb3_skb_cb { __u8 flags; __u8 ulp_mode; __u32 seq; - union { - struct cxgb3_skb_rx_cb rx; - struct cxgb3_skb_tx_cb tx; - }; + __u32 ddigest; + __u32 pdulen; + struct sk_buff *wr_data; }; #define CXGB3_SKB_CB(skb) ((struct cxgb3_skb_cb *)&((skb)->cb[0])) -#define skb_flags(skb) (CXGB3_SKB_CB(skb)->flags) + #define skb_ulp_mode(skb) (CXGB3_SKB_CB(skb)->ulp_mode) -#define skb_tcp_seq(skb) (CXGB3_SKB_CB(skb)->seq) -#define skb_rx_ddigest(skb) (CXGB3_SKB_CB(skb)->rx.ddigest) -#define skb_rx_pdulen(skb) (CXGB3_SKB_CB(skb)->rx.pdulen) -#define skb_tx_wr_next(skb) (CXGB3_SKB_CB(skb)->tx.wr_next) +#define skb_ulp_ddigest(skb) (CXGB3_SKB_CB(skb)->ddigest) +#define skb_ulp_pdulen(skb) (CXGB3_SKB_CB(skb)->pdulen) +#define skb_wr_data(skb) (CXGB3_SKB_CB(skb)->wr_data) enum c3cb_flags { C3CB_FLAG_NEED_HDR = 1 << 0, /* packet needs a TX_DATA_WR header */ @@ -225,7 +217,6 @@ struct sge_opaque_hdr { /* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */ #define TX_HEADER_LEN \ (sizeof(struct tx_data_wr) + sizeof(struct sge_opaque_hdr)) -#define SKB_TX_HEADROOM SKB_MAX_HEAD(TX_HEADER_LEN) /* * get and set private ip for iscsi traffic diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/trunk/drivers/scsi/cxgb3i/cxgb3i_pdu.c index 17115c230d65..ce7ce8c6094c 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_pdu.c +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_pdu.c @@ -32,10 +32,6 @@ #define cxgb3i_tx_debug(fmt...) #endif -/* always allocate rooms for AHS */ -#define SKB_TX_PDU_HEADER_LEN \ - (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE) -static unsigned int skb_extra_headroom; static struct page *pad_page; /* @@ -150,13 +146,12 @@ static inline void tx_skb_setmode(struct sk_buff *skb, int hcrc, int dcrc) void cxgb3i_conn_cleanup_task(struct iscsi_task *task) { - struct cxgb3i_task_data *tdata = task->dd_data + - sizeof(struct iscsi_tcp_task); + struct iscsi_tcp_task *tcp_task = task->dd_data; /* never reached the xmit task callout */ - if (tdata->skb) - __kfree_skb(tdata->skb); - memset(tdata, 0, sizeof(struct cxgb3i_task_data)); + if (tcp_task->dd_data) + kfree_skb(tcp_task->dd_data); + tcp_task->dd_data = NULL; /* MNC - Do we need a check in case this is called but * cxgb3i_conn_alloc_pdu has never been called on the task */ @@ -164,102 +159,28 @@ void cxgb3i_conn_cleanup_task(struct iscsi_task *task) iscsi_tcp_cleanup_task(task); } -static int sgl_seek_offset(struct scatterlist *sgl, unsigned int sgcnt, - unsigned int offset, unsigned int *off, - struct scatterlist **sgp) -{ - int i; - struct scatterlist *sg; - - for_each_sg(sgl, sg, sgcnt, i) { - if (offset < sg->length) { - *off = offset; - *sgp = sg; - return 0; - } - offset -= sg->length; - } - return -EFAULT; -} - -static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset, - unsigned int dlen, skb_frag_t *frags, - int frag_max) -{ - unsigned int datalen = dlen; - unsigned int sglen = sg->length - sgoffset; - struct page *page = sg_page(sg); - int i; - - i = 0; - do { - unsigned int copy; - - if (!sglen) { - sg = sg_next(sg); - if (!sg) { - cxgb3i_log_error("%s, sg NULL, len %u/%u.\n", - __func__, datalen, dlen); - return -EINVAL; - } - sgoffset = 0; - sglen = sg->length; - page = sg_page(sg); - - } - copy = min(datalen, sglen); - if (i && page == frags[i - 1].page && - sgoffset + sg->offset == - frags[i - 1].page_offset + frags[i - 1].size) { - frags[i - 1].size += copy; - } else { - if (i >= frag_max) { - cxgb3i_log_error("%s, too many pages %u, " - "dlen %u.\n", __func__, - frag_max, dlen); - return -EINVAL; - } - - frags[i].page = page; - frags[i].page_offset = sg->offset + sgoffset; - frags[i].size = copy; - i++; - } - datalen -= copy; - sgoffset += copy; - sglen -= copy; - } while (datalen); - - return i; -} - +/* + * We do not support ahs yet + */ int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode) { - struct iscsi_conn *conn = task->conn; struct iscsi_tcp_task *tcp_task = task->dd_data; - struct cxgb3i_task_data *tdata = task->dd_data + sizeof(*tcp_task); - struct scsi_cmnd *sc = task->sc; - int headroom = SKB_TX_PDU_HEADER_LEN; + struct sk_buff *skb; - tcp_task->dd_data = tdata; task->hdr = NULL; - - /* write command, need to send data pdus */ - if (skb_extra_headroom && (opcode == ISCSI_OP_SCSI_DATA_OUT || - (opcode == ISCSI_OP_SCSI_CMD && - (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE)))) - headroom += min(skb_extra_headroom, conn->max_xmit_dlength); - - tdata->skb = alloc_skb(TX_HEADER_LEN + headroom, GFP_ATOMIC); - if (!tdata->skb) + /* always allocate rooms for AHS */ + skb = alloc_skb(sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE + + TX_HEADER_LEN, GFP_ATOMIC); + if (!skb) return -ENOMEM; - skb_reserve(tdata->skb, TX_HEADER_LEN); cxgb3i_tx_debug("task 0x%p, opcode 0x%x, skb 0x%p.\n", - task, opcode, tdata->skb); + task, opcode, skb); - task->hdr = (struct iscsi_hdr *)tdata->skb->data; - task->hdr_max = SKB_TX_PDU_HEADER_LEN; + tcp_task->dd_data = skb; + skb_reserve(skb, TX_HEADER_LEN); + task->hdr = (struct iscsi_hdr *)skb->data; + task->hdr_max = sizeof(struct iscsi_hdr); /* data_out uses scsi_cmd's itt */ if (opcode != ISCSI_OP_SCSI_DATA_OUT) @@ -271,13 +192,13 @@ int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode) int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset, unsigned int count) { - struct iscsi_conn *conn = task->conn; struct iscsi_tcp_task *tcp_task = task->dd_data; - struct cxgb3i_task_data *tdata = tcp_task->dd_data; - struct sk_buff *skb = tdata->skb; + struct sk_buff *skb = tcp_task->dd_data; + struct iscsi_conn *conn = task->conn; + struct page *pg; unsigned int datalen = count; int i, padlen = iscsi_padding(count); - struct page *pg; + skb_frag_t *frag; cxgb3i_tx_debug("task 0x%p,0x%p, offset %u, count %u, skb 0x%p.\n", task, task->sc, offset, count, skb); @@ -288,94 +209,90 @@ int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset, return 0; if (task->sc) { - struct scsi_data_buffer *sdb = scsi_out(task->sc); - struct scatterlist *sg = NULL; - int err; - - tdata->offset = offset; - tdata->count = count; - err = sgl_seek_offset(sdb->table.sgl, sdb->table.nents, - tdata->offset, &tdata->sgoffset, &sg); - if (err < 0) { - cxgb3i_log_warn("tpdu, sgl %u, bad offset %u/%u.\n", - sdb->table.nents, tdata->offset, - sdb->length); - return err; + struct scatterlist *sg; + struct scsi_data_buffer *sdb; + unsigned int sgoffset = offset; + struct page *sgpg; + unsigned int sglen; + + sdb = scsi_out(task->sc); + sg = sdb->table.sgl; + + for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { + cxgb3i_tx_debug("sg %d, page 0x%p, len %u offset %u\n", + i, sg_page(sg), sg->length, sg->offset); + + if (sgoffset < sg->length) + break; + sgoffset -= sg->length; } - err = sgl_read_to_frags(sg, tdata->sgoffset, tdata->count, - tdata->frags, MAX_PDU_FRAGS); - if (err < 0) { - cxgb3i_log_warn("tpdu, sgl %u, bad offset %u + %u.\n", - sdb->table.nents, tdata->offset, - tdata->count); - return err; - } - tdata->nr_frags = err; - - if (tdata->nr_frags > MAX_SKB_FRAGS || - (padlen && tdata->nr_frags == MAX_SKB_FRAGS)) { - char *dst = skb->data + task->hdr_len; - skb_frag_t *frag = tdata->frags; - - /* data fits in the skb's headroom */ - for (i = 0; i < tdata->nr_frags; i++, frag++) { - char *src = kmap_atomic(frag->page, - KM_SOFTIRQ0); - - memcpy(dst, src+frag->page_offset, frag->size); - dst += frag->size; - kunmap_atomic(src, KM_SOFTIRQ0); + sgpg = sg_page(sg); + sglen = sg->length - sgoffset; + + do { + int j = skb_shinfo(skb)->nr_frags; + unsigned int copy; + + if (!sglen) { + sg = sg_next(sg); + sgpg = sg_page(sg); + sgoffset = 0; + sglen = sg->length; + ++i; } - if (padlen) { - memset(dst, 0, padlen); - padlen = 0; + copy = min(sglen, datalen); + if (j && skb_can_coalesce(skb, j, sgpg, + sg->offset + sgoffset)) { + skb_shinfo(skb)->frags[j - 1].size += copy; + } else { + get_page(sgpg); + skb_fill_page_desc(skb, j, sgpg, + sg->offset + sgoffset, copy); } - skb_put(skb, count + padlen); - } else { - /* data fit into frag_list */ - for (i = 0; i < tdata->nr_frags; i++) - get_page(tdata->frags[i].page); - - memcpy(skb_shinfo(skb)->frags, tdata->frags, - sizeof(skb_frag_t) * tdata->nr_frags); - skb_shinfo(skb)->nr_frags = tdata->nr_frags; - skb->len += count; - skb->data_len += count; - skb->truesize += count; - } - + sgoffset += copy; + sglen -= copy; + datalen -= copy; + } while (datalen); } else { pg = virt_to_page(task->data); - get_page(pg); - skb_fill_page_desc(skb, 0, pg, offset_in_page(task->data), - count); - skb->len += count; - skb->data_len += count; - skb->truesize += count; + while (datalen) { + i = skb_shinfo(skb)->nr_frags; + frag = &skb_shinfo(skb)->frags[i]; + + get_page(pg); + frag->page = pg; + frag->page_offset = 0; + frag->size = min((unsigned int)PAGE_SIZE, datalen); + + skb_shinfo(skb)->nr_frags++; + datalen -= frag->size; + pg++; + } } if (padlen) { i = skb_shinfo(skb)->nr_frags; - get_page(pad_page); - skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, pad_page, 0, - padlen); - - skb->data_len += padlen; - skb->truesize += padlen; - skb->len += padlen; + frag = &skb_shinfo(skb)->frags[i]; + frag->page = pad_page; + frag->page_offset = 0; + frag->size = padlen; + skb_shinfo(skb)->nr_frags++; } + datalen = count + padlen; + skb->data_len += datalen; + skb->truesize += datalen; + skb->len += datalen; return 0; } int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) { + struct iscsi_tcp_task *tcp_task = task->dd_data; + struct sk_buff *skb = tcp_task->dd_data; struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data; struct cxgb3i_conn *cconn = tcp_conn->dd_data; - struct iscsi_tcp_task *tcp_task = task->dd_data; - struct cxgb3i_task_data *tdata = tcp_task->dd_data; - struct sk_buff *skb = tdata->skb; unsigned int datalen; int err; @@ -383,13 +300,12 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) return 0; datalen = skb->data_len; - tdata->skb = NULL; + tcp_task->dd_data = NULL; err = cxgb3i_c3cn_send_pdus(cconn->cep->c3cn, skb); - if (err > 0) { - int pdulen = err; - cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", task, skb, skb->len, skb->data_len, err); + if (err > 0) { + int pdulen = err; if (task->conn->hdrdgst_en) pdulen += ISCSI_DIGEST_SIZE; @@ -409,14 +325,12 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) return err; } /* reset skb to send when we are called again */ - tdata->skb = skb; + tcp_task->dd_data = skb; return -EAGAIN; } int cxgb3i_pdu_init(void) { - if (SKB_TX_HEADROOM > (512 * MAX_SKB_FRAGS)) - skb_extra_headroom = SKB_TX_HEADROOM; pad_page = alloc_page(GFP_KERNEL); if (!pad_page) return -ENOMEM; @@ -452,9 +366,7 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn) skb = skb_peek(&c3cn->receive_queue); while (!err && skb) { __skb_unlink(skb, &c3cn->receive_queue); - read += skb_rx_pdulen(skb); - cxgb3i_rx_debug("conn 0x%p, cn 0x%p, rx skb 0x%p, pdulen %u.\n", - conn, c3cn, skb, skb_rx_pdulen(skb)); + read += skb_ulp_pdulen(skb); err = cxgb3i_conn_read_pdu_skb(conn, skb); __kfree_skb(skb); skb = skb_peek(&c3cn->receive_queue); @@ -465,11 +377,6 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn) cxgb3i_c3cn_rx_credits(c3cn, read); } conn->rxdata_octets += read; - - if (err) { - cxgb3i_log_info("conn 0x%p rx failed err %d.\n", conn, err); - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - } } void cxgb3i_conn_tx_open(struct s3_conn *c3cn) diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_pdu.h b/trunk/drivers/scsi/cxgb3i/cxgb3i_pdu.h index 0770b23d90da..a3f685cc2362 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_pdu.h +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_pdu.h @@ -53,7 +53,7 @@ struct cpl_rx_data_ddp_norss { #define ULP2_FLAG_DCRC_ERROR 0x20 #define ULP2_FLAG_PAD_ERROR 0x40 -void cxgb3i_conn_closing(struct s3_conn *c3cn); +void cxgb3i_conn_closing(struct s3_conn *); void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn); void cxgb3i_conn_tx_open(struct s3_conn *c3cn); #endif diff --git a/trunk/drivers/scsi/hptiop.c b/trunk/drivers/scsi/hptiop.c index 34be88d7afa5..a48e4990fe12 100644 --- a/trunk/drivers/scsi/hptiop.c +++ b/trunk/drivers/scsi/hptiop.c @@ -1251,7 +1251,6 @@ static struct pci_device_id hptiop_id_table[] = { { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops }, - { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops }, diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvfc.c b/trunk/drivers/scsi/ibmvscsi/ibmvfc.c index ed1e728763a2..a1a511bdec8c 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvfc.c @@ -1573,6 +1573,9 @@ static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd, vfc_cmd->resp_len = sizeof(vfc_cmd->rsp); vfc_cmd->cancel_key = (unsigned long)cmnd->device->hostdata; vfc_cmd->tgt_scsi_id = rport->port_id; + if ((rport->supported_classes & FC_COS_CLASS3) && + (fc_host_supported_classes(vhost->host) & FC_COS_CLASS3)) + vfc_cmd->flags = IBMVFC_CLASS_3_ERR; vfc_cmd->iu.xfer_len = scsi_bufflen(cmnd); int_to_scsilun(cmnd->device->lun, &vfc_cmd->iu.lun); memcpy(vfc_cmd->iu.cdb, cmnd->cmnd, cmnd->cmd_len); @@ -3263,7 +3266,6 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, u64 scsi_id) return -ENOMEM; } - memset(tgt, 0, sizeof(*tgt)); tgt->scsi_id = scsi_id; tgt->new_scsi_id = scsi_id; tgt->vhost = vhost; @@ -3574,18 +3576,9 @@ static void ibmvfc_log_ae(struct ibmvfc_host *vhost, int events) static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) { struct ibmvfc_host *vhost = tgt->vhost; - struct fc_rport *rport = tgt->rport; + struct fc_rport *rport; unsigned long flags; - if (rport) { - tgt_dbg(tgt, "Setting rport roles\n"); - fc_remote_port_rolechg(rport, tgt->ids.roles); - spin_lock_irqsave(vhost->host->host_lock, flags); - ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); - spin_unlock_irqrestore(vhost->host->host_lock, flags); - return; - } - tgt_dbg(tgt, "Adding rport\n"); rport = fc_remote_port_add(vhost->host, 0, &tgt->ids); spin_lock_irqsave(vhost->host->host_lock, flags); diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvfc.h b/trunk/drivers/scsi/ibmvscsi/ibmvfc.h index b21e071b9862..87dafd0f8d44 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/trunk/drivers/scsi/ibmvscsi/ibmvfc.h @@ -32,7 +32,7 @@ #define IBMVFC_DRIVER_VERSION "1.0.4" #define IBMVFC_DRIVER_DATE "(November 14, 2008)" -#define IBMVFC_DEFAULT_TIMEOUT 60 +#define IBMVFC_DEFAULT_TIMEOUT 15 #define IBMVFC_INIT_TIMEOUT 120 #define IBMVFC_MAX_REQUESTS_DEFAULT 100 diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index c9aa7611e408..74d07d137dae 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -432,7 +432,6 @@ static int map_sg_data(struct scsi_cmnd *cmd, sdev_printk(KERN_ERR, cmd->device, "Can't allocate memory " "for indirect table\n"); - scsi_dma_unmap(cmd); return 0; } } diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c index 809d32d95c76..257c24115de9 100644 --- a/trunk/drivers/scsi/libiscsi.c +++ b/trunk/drivers/scsi/libiscsi.c @@ -1998,8 +1998,6 @@ int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev) if (!shost->can_queue) shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX; - if (!shost->transportt->eh_timed_out) - shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out; return scsi_add_host(shost, pdev); } EXPORT_SYMBOL_GPL(iscsi_host_add); @@ -2022,6 +2020,7 @@ struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size); if (!shost) return NULL; + shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out; if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) { if (qdepth != 0) diff --git a/trunk/drivers/scsi/lpfc/lpfc_els.c b/trunk/drivers/scsi/lpfc/lpfc_els.c index a7302480bc4a..a8f30bdaff69 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_els.c +++ b/trunk/drivers/scsi/lpfc/lpfc_els.c @@ -5258,7 +5258,6 @@ lpfc_send_els_event(struct lpfc_vport *vport, sizeof(struct lpfc_name)); break; default: - kfree(els_data); return; } memcpy(els_data->wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name)); diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index f4c57227ec18..33a3c13fd893 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -1265,6 +1265,13 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) msleep(1000); + if (ha->mqenable) { + if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS) + qla_printk(KERN_WARNING, ha, + "Queue delete failed.\n"); + vha->req_ques[0] = ha->req_q_map[0]->id; + } + qla24xx_disable_vp(vha); fc_remove_host(vha->host); @@ -1286,12 +1293,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) vha->host_no, vha->vp_idx, vha)); } - if (ha->mqenable) { - if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS) - qla_printk(KERN_WARNING, ha, - "Queue delete failed.\n"); - } - scsi_host_put(vha->host); qla_printk(KERN_INFO, ha, "vport %d deleted\n", id); return 0; diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index e0c5bb54b258..023ee77fb027 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -2135,7 +2135,6 @@ struct qla_msix_entry { /* Work events. */ enum qla_work_type { QLA_EVT_AEN, - QLA_EVT_IDC_ACK, }; @@ -2150,10 +2149,6 @@ struct qla_work_evt { enum fc_host_event_code code; u32 data; } aen; - struct { -#define QLA_IDC_ACK_REGS 7 - uint16_t mb[QLA_IDC_ACK_REGS]; - } idc_ack; } u; }; diff --git a/trunk/drivers/scsi/qla2xxx/qla_devtbl.h b/trunk/drivers/scsi/qla2xxx/qla_devtbl.h index d6ea69df7c5c..d78d35e681ab 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_devtbl.h +++ b/trunk/drivers/scsi/qla2xxx/qla_devtbl.h @@ -72,7 +72,7 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = { "QLA2462", "Sun PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x141 */ "QLE2460", "Sun PCI-Express to 2Gb FC, Single Channel", /* 0x142 */ "QLE2462", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x143 */ - "QEM2462", "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */ + "QEM2462" "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */ "QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */ "QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */ "QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */ diff --git a/trunk/drivers/scsi/qla2xxx/qla_fw.h b/trunk/drivers/scsi/qla2xxx/qla_fw.h index ffff42554087..7abb045a0410 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_fw.h +++ b/trunk/drivers/scsi/qla2xxx/qla_fw.h @@ -1402,8 +1402,6 @@ struct access_chip_rsp_84xx { #define MBA_IDC_NOTIFY 0x8101 #define MBA_IDC_TIME_EXT 0x8102 -#define MBC_IDC_ACK 0x101 - struct nvram_81xx { /* NVRAM header. */ uint8_t id[4]; diff --git a/trunk/drivers/scsi/qla2xxx/qla_gbl.h b/trunk/drivers/scsi/qla2xxx/qla_gbl.h index 6de283f8f111..a336b4bc81a7 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gbl.h +++ b/trunk/drivers/scsi/qla2xxx/qla_gbl.h @@ -72,7 +72,6 @@ extern int qla2x00_loop_reset(scsi_qla_host_t *); extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum fc_host_event_code, u32); -extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *); extern void qla2x00_abort_fcport_cmds(fc_port_t *); extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *, @@ -267,8 +266,6 @@ qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *); -extern int qla81xx_idc_ack(scsi_qla_host_t *, uint16_t *); - /* * Global Function Prototypes in qla_isr.c source file. */ @@ -379,8 +376,10 @@ extern int qla2x00_dfs_remove(scsi_qla_host_t *); /* Globa function prototypes for multi-q */ extern int qla25xx_request_irq(struct rsp_que *); -extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *); -extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *); +extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *, + uint8_t); +extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *, + uint8_t); extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t, uint16_t, uint8_t, uint8_t); extern int qla25xx_create_rsp_que(struct qla_hw_data *, uint16_t, uint8_t, diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index 986501759ad4..f6368a1d3021 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -1226,8 +1226,9 @@ qla24xx_config_rings(struct scsi_qla_host *vha) icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_18); - icb->firmware_options_2 &= __constant_cpu_to_le32(~BIT_22); + icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_22); icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23); + ha->rsp_q_map[0]->options = icb->firmware_options_2; WRT_REG_DWORD(®->isp25mq.req_q_in, 0); WRT_REG_DWORD(®->isp25mq.req_q_out, 0); @@ -3492,7 +3493,7 @@ qla25xx_init_queues(struct qla_hw_data *ha) rsp = ha->rsp_q_map[i]; if (rsp) { rsp->options &= ~BIT_0; - ret = qla25xx_init_rsp_que(base_vha, rsp); + ret = qla25xx_init_rsp_que(base_vha, rsp, rsp->options); if (ret != QLA_SUCCESS) DEBUG2_17(printk(KERN_WARNING "%s Rsp que:%d init failed\n", __func__, @@ -3506,7 +3507,7 @@ qla25xx_init_queues(struct qla_hw_data *ha) if (req) { /* Clear outstanding commands array. */ req->options &= ~BIT_0; - ret = qla25xx_init_req_que(base_vha, req); + ret = qla25xx_init_req_que(base_vha, req, req->options); if (ret != QLA_SUCCESS) DEBUG2_17(printk(KERN_WARNING "%s Req que:%d init failed\n", __func__, diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index f250e5b7897c..e28ad81baf1e 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -266,40 +266,6 @@ qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) } } -static void -qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr) -{ - static char *event[] = - { "Complete", "Request Notification", "Time Extension" }; - int rval; - struct device_reg_24xx __iomem *reg24 = &vha->hw->iobase->isp24; - uint16_t __iomem *wptr; - uint16_t cnt, timeout, mb[QLA_IDC_ACK_REGS]; - - /* Seed data -- mailbox1 -> mailbox7. */ - wptr = (uint16_t __iomem *)®24->mailbox1; - for (cnt = 0; cnt < QLA_IDC_ACK_REGS; cnt++, wptr++) - mb[cnt] = RD_REG_WORD(wptr); - - DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- " - "%04x %04x %04x %04x %04x %04x %04x.\n", vha->host_no, - event[aen & 0xff], - mb[0], mb[1], mb[2], mb[3], mb[4], mb[5], mb[6])); - - /* Acknowledgement needed? [Notify && non-zero timeout]. */ - timeout = (descr >> 8) & 0xf; - if (aen != MBA_IDC_NOTIFY || !timeout) - return; - - DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- " - "ACK timeout=%d.\n", vha->host_no, event[aen & 0xff], timeout)); - - rval = qla2x00_post_idc_ack_work(vha, mb); - if (rval != QLA_SUCCESS) - qla_printk(KERN_WARNING, vha->hw, - "IDC failed to post ACK.\n"); -} - /** * qla2x00_async_event() - Process aynchronous events. * @ha: SCSI driver HA context @@ -748,9 +714,21 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) "%04x %04x %04x\n", vha->host_no, mb[1], mb[2], mb[3])); break; case MBA_IDC_COMPLETE: + DEBUG2(printk("scsi(%ld): Inter-Driver Commucation " + "Complete -- %04x %04x %04x\n", vha->host_no, mb[1], mb[2], + mb[3])); + break; case MBA_IDC_NOTIFY: + DEBUG2(printk("scsi(%ld): Inter-Driver Commucation " + "Request Notification -- %04x %04x %04x\n", vha->host_no, + mb[1], mb[2], mb[3])); + /**** Mailbox registers 4 - 7 valid!!! */ + break; case MBA_IDC_TIME_EXT: - qla81xx_idc_event(vha, mb[0], mb[1]); + DEBUG2(printk("scsi(%ld): Inter-Driver Commucation " + "Time Extension -- %04x %04x %04x\n", vha->host_no, mb[1], + mb[2], mb[3])); + /**** Mailbox registers 4 - 7 valid!!! */ break; } @@ -1729,6 +1707,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) struct qla_hw_data *ha; struct rsp_que *rsp; struct device_reg_24xx __iomem *reg; + uint16_t msix_disabled_hccr = 0; rsp = (struct rsp_que *) dev_id; if (!rsp) { @@ -1741,8 +1720,17 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) spin_lock_irq(&ha->hardware_lock); + msix_disabled_hccr = rsp->options; + if (!rsp->id) + msix_disabled_hccr &= __constant_cpu_to_le32(BIT_22); + else + msix_disabled_hccr &= __constant_cpu_to_le32(BIT_6); + qla24xx_process_response_queue(rsp); + if (!msix_disabled_hccr) + WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); + spin_unlock_irq(&ha->hardware_lock); return IRQ_HANDLED; diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index 4c7504cb3990..f94ffbb98e95 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -3090,7 +3090,8 @@ qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status) } int -qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) +qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req, + uint8_t options) { int rval; unsigned long flags; @@ -3100,7 +3101,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) struct qla_hw_data *ha = vha->hw; mcp->mb[0] = MBC_INITIALIZE_MULTIQ; - mcp->mb[1] = req->options; + mcp->mb[1] = options; mcp->mb[2] = MSW(LSD(req->dma)); mcp->mb[3] = LSW(LSD(req->dma)); mcp->mb[6] = MSW(MSD(req->dma)); @@ -3127,7 +3128,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) mcp->tov = 60; spin_lock_irqsave(&ha->hardware_lock, flags); - if (!(req->options & BIT_0)) { + if (!(options & BIT_0)) { WRT_REG_DWORD(®->req_q_in, 0); WRT_REG_DWORD(®->req_q_out, 0); } @@ -3141,7 +3142,8 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) } int -qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) +qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp, + uint8_t options) { int rval; unsigned long flags; @@ -3151,7 +3153,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) struct qla_hw_data *ha = vha->hw; mcp->mb[0] = MBC_INITIALIZE_MULTIQ; - mcp->mb[1] = rsp->options; + mcp->mb[1] = options; mcp->mb[2] = MSW(LSD(rsp->dma)); mcp->mb[3] = LSW(LSD(rsp->dma)); mcp->mb[6] = MSW(MSD(rsp->dma)); @@ -3176,7 +3178,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) mcp->tov = 60; spin_lock_irqsave(&ha->hardware_lock, flags); - if (!(rsp->options & BIT_0)) { + if (!(options & BIT_0)) { WRT_REG_DWORD(®->rsp_q_out, 0); WRT_REG_DWORD(®->rsp_q_in, 0); } @@ -3191,29 +3193,3 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) return rval; } -int -qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb) -{ - int rval; - mbx_cmd_t mc; - mbx_cmd_t *mcp = &mc; - - DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); - - mcp->mb[0] = MBC_IDC_ACK; - memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t)); - mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; - mcp->in_mb = MBX_0; - mcp->tov = MBX_TOV_SECONDS; - mcp->flags = 0; - rval = qla2x00_mailbox_command(vha, mcp); - - if (rval != QLA_SUCCESS) { - DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, - vha->host_no, rval, mcp->mb[0])); - } else { - DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no)); - } - - return rval; -} diff --git a/trunk/drivers/scsi/qla2xxx/qla_mid.c b/trunk/drivers/scsi/qla2xxx/qla_mid.c index 3f23932210c4..f53179c46423 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mid.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mid.c @@ -396,7 +396,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL); - memset(vha->req_ques, 0, sizeof(vha->req_ques)); + memset(vha->req_ques, 0, sizeof(vha->req_ques) * QLA_MAX_HOST_QUES); vha->req_ques[0] = ha->req_q_map[0]->id; host->can_queue = ha->req_q_map[0]->length + 128; host->this_id = 255; @@ -471,7 +471,7 @@ qla25xx_delete_req_que(struct scsi_qla_host *vha, struct req_que *req) if (req) { req->options |= BIT_0; - ret = qla25xx_init_req_que(vha, req); + ret = qla25xx_init_req_que(vha, req, req->options); } if (ret == QLA_SUCCESS) qla25xx_free_req_que(vha, req); @@ -486,7 +486,7 @@ qla25xx_delete_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) if (rsp) { rsp->options |= BIT_0; - ret = qla25xx_init_rsp_que(vha, rsp); + ret = qla25xx_init_rsp_que(vha, rsp, rsp->options); } if (ret == QLA_SUCCESS) qla25xx_free_rsp_que(vha, rsp); @@ -502,7 +502,7 @@ int qla25xx_update_req_que(struct scsi_qla_host *vha, uint8_t que, uint8_t qos) req->options |= BIT_3; req->qos = qos; - ret = qla25xx_init_req_que(vha, req); + ret = qla25xx_init_req_que(vha, req, req->options); if (ret != QLA_SUCCESS) DEBUG2_17(printk(KERN_WARNING "%s failed\n", __func__)); /* restore options bit */ @@ -632,7 +632,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, req->max_q_depth = ha->req_q_map[0]->max_q_depth; mutex_unlock(&ha->vport_lock); - ret = qla25xx_init_req_que(base_vha, req); + ret = qla25xx_init_req_que(base_vha, req, options); if (ret != QLA_SUCCESS) { qla_printk(KERN_WARNING, ha, "%s failed\n", __func__); mutex_lock(&ha->vport_lock); @@ -710,7 +710,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, if (ret) goto que_failed; - ret = qla25xx_init_rsp_que(base_vha, rsp); + ret = qla25xx_init_rsp_que(base_vha, rsp, options); if (ret != QLA_SUCCESS) { qla_printk(KERN_WARNING, ha, "%s failed\n", __func__); mutex_lock(&ha->vport_lock); diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 2f5f72531e23..c11f872d3e10 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -2522,19 +2522,6 @@ qla2x00_post_aen_work(struct scsi_qla_host *vha, enum fc_host_event_code code, return qla2x00_post_work(vha, e, 1); } -int -qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb) -{ - struct qla_work_evt *e; - - e = qla2x00_alloc_work(vha, QLA_EVT_IDC_ACK, 1); - if (!e) - return QLA_FUNCTION_FAILED; - - memcpy(e->u.idc_ack.mb, mb, QLA_IDC_ACK_REGS * sizeof(uint16_t)); - return qla2x00_post_work(vha, e, 1); -} - static void qla2x00_do_work(struct scsi_qla_host *vha) { @@ -2552,9 +2539,6 @@ qla2x00_do_work(struct scsi_qla_host *vha) fc_host_post_event(vha->host, fc_get_event_number(), e->u.aen.code, e->u.aen.data); break; - case QLA_EVT_IDC_ACK: - qla81xx_idc_ack(vha, e->u.idc_ack.mb); - break; } if (e->flags & QLA_EVT_FLAG_FREE) kfree(e); diff --git a/trunk/drivers/scsi/qla2xxx/qla_sup.c b/trunk/drivers/scsi/qla2xxx/qla_sup.c index 284827926eff..9c3b694c049d 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_sup.c +++ b/trunk/drivers/scsi/qla2xxx/qla_sup.c @@ -684,7 +684,7 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) "end=0x%x size=0x%x.\n", le32_to_cpu(region->code), start, le32_to_cpu(region->end) >> 2, le32_to_cpu(region->size))); - switch (le32_to_cpu(region->code) & 0xff) { + switch (le32_to_cpu(region->code)) { case FLT_REG_FW: ha->flt_region_fw = start; break; diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index 79f7053da99b..cfa4c11a4797 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.00-k3" +#define QLA2XXX_VERSION "8.03.00-k2" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index b82ffd90632e..940dc32ff0dc 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -1040,11 +1040,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) action = ACTION_FAIL; break; case ABORTED_COMMAND: - action = ACTION_FAIL; if (sshdr.asc == 0x10) { /* DIF */ description = "Target Data Integrity Failure"; + action = ACTION_FAIL; error = -EILSEQ; - } + } else + action = ACTION_RETRY; break; case NOT_READY: /* If the device is in the process of becoming diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index 8f4de20c9deb..66505bb79410 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -317,7 +317,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, return sdev; out_device_destroy: - scsi_device_set_state(sdev, SDEV_DEL); transport_destroy_device(&sdev->sdev_gendev); put_device(&sdev->sdev_gendev); out: diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 55310dbc10a6..d57566b8be0a 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -107,7 +107,6 @@ static void scsi_disk_release(struct device *cdev); static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); static void sd_print_result(struct scsi_disk *, int); -static DEFINE_SPINLOCK(sd_index_lock); static DEFINE_IDA(sd_index_ida); /* This semaphore is used to mediate the 0->1 reference get in the @@ -1915,9 +1914,7 @@ static int sd_probe(struct device *dev) if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) goto out_put; - spin_lock(&sd_index_lock); error = ida_get_new(&sd_index_ida, &index); - spin_unlock(&sd_index_lock); } while (error == -EAGAIN); if (error) @@ -1939,9 +1936,7 @@ static int sd_probe(struct device *dev) return 0; out_free_index: - spin_lock(&sd_index_lock); ida_remove(&sd_index_ida, index); - spin_unlock(&sd_index_lock); out_put: put_disk(gd); out_free: @@ -1991,9 +1986,7 @@ static void scsi_disk_release(struct device *dev) struct scsi_disk *sdkp = to_scsi_disk(dev); struct gendisk *disk = sdkp->disk; - spin_lock(&sd_index_lock); ida_remove(&sd_index_ida, sdkp->index); - spin_unlock(&sd_index_lock); disk->private_data = NULL; put_disk(disk); diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 516925d8b570..8f0bd3f7a59f 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -1078,7 +1078,7 @@ sg_ioctl(struct inode *inode, struct file *filp, case BLKTRACESETUP: return blk_trace_setup(sdp->device->request_queue, sdp->disk->disk_name, - MKDEV(SCSI_GENERIC_MAJOR, sdp->index), + sdp->device->sdev_gendev.devt, (char *)arg); case BLKTRACESTART: return blk_trace_startstop(sdp->device->request_queue, 1); diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index b4b39811b445..0d934bfbdd9b 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -2083,20 +2083,6 @@ static int serial8250_startup(struct uart_port *port) serial8250_set_mctrl(&up->port, up->port.mctrl); - /* Serial over Lan (SoL) hack: - Intel 8257x Gigabit ethernet chips have a - 16550 emulation, to be used for Serial Over Lan. - Those chips take a longer time than a normal - serial device to signalize that a transmission - data was queued. Due to that, the above test generally - fails. One solution would be to delay the reading of - iir. However, this is not reliable, since the timeout - is variable. So, let's just don't test if we receive - TX irq. This way, we'll never enable UART_BUG_TXEN. - */ - if (up->port.flags & UPF_NO_TXEN_TEST) - goto dont_test_tx_en; - /* * Do a quick test to see if we receive an * interrupt when we enable the TX irq. @@ -2116,7 +2102,6 @@ static int serial8250_startup(struct uart_port *port) up->bugs &= ~UART_BUG_TXEN; } -dont_test_tx_en: spin_unlock_irqrestore(&up->port.lock, flags); /* diff --git a/trunk/drivers/serial/8250_pci.c b/trunk/drivers/serial/8250_pci.c index 533f82025adf..536d8e510f66 100644 --- a/trunk/drivers/serial/8250_pci.c +++ b/trunk/drivers/serial/8250_pci.c @@ -798,21 +798,6 @@ pci_default_setup(struct serial_private *priv, return setup_port(priv, port, bar, offset, board->reg_shift); } -static int skip_tx_en_setup(struct serial_private *priv, - const struct pciserial_board *board, - struct uart_port *port, int idx) -{ - port->flags |= UPF_NO_TXEN_TEST; - printk(KERN_DEBUG "serial8250: skipping TxEn test for device " - "[%04x:%04x] subsystem [%04x:%04x]\n", - priv->dev->vendor, - priv->dev->device, - priv->dev->subsystem_vendor, - priv->dev->subsystem_device); - - return pci_default_setup(priv, board, port, idx); -} - /* This should be in linux/pci_ids.h */ #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B @@ -879,27 +864,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .init = pci_inteli960ni_init, .setup = pci_default_setup, }, - { - .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_DEVICE_ID_INTEL_8257X_SOL, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = skip_tx_en_setup, - }, - { - .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_DEVICE_ID_INTEL_82573L_SOL, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = skip_tx_en_setup, - }, - { - .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_DEVICE_ID_INTEL_82573E_SOL, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = skip_tx_en_setup, - }, /* * ITE */ diff --git a/trunk/drivers/serial/atmel_serial.c b/trunk/drivers/serial/atmel_serial.c index 8f58f7ff0dd7..89362d733d62 100644 --- a/trunk/drivers/serial/atmel_serial.c +++ b/trunk/drivers/serial/atmel_serial.c @@ -877,10 +877,6 @@ static int atmel_startup(struct uart_port *port) } } - /* Save current CSR for comparison in atmel_tasklet_func() */ - atmel_port->irq_status_prev = UART_GET_CSR(port); - atmel_port->irq_status = atmel_port->irq_status_prev; - /* * Finally, enable the serial port */ diff --git a/trunk/drivers/serial/jsm/jsm_driver.c b/trunk/drivers/serial/jsm/jsm_driver.c index ac79cbe4c2cf..92187e28608a 100644 --- a/trunk/drivers/serial/jsm/jsm_driver.c +++ b/trunk/drivers/serial/jsm/jsm_driver.c @@ -84,8 +84,6 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) brd->pci_dev = pdev; if (pdev->device == PCIE_DEVICE_ID_NEO_4_IBM) brd->maxports = 4; - else if (pdev->device == PCI_DEVICE_ID_DIGI_NEO_8) - brd->maxports = 8; else brd->maxports = 2; @@ -214,7 +212,6 @@ static struct pci_device_id jsm_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4_IBM), 0, 0, 4 }, - { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_NEO_8), 0, 0, 5 }, { 0, } }; MODULE_DEVICE_TABLE(pci, jsm_pci_tbl); diff --git a/trunk/drivers/serial/sh-sci.h b/trunk/drivers/serial/sh-sci.h index 022e89ffec1d..3599828b9766 100644 --- a/trunk/drivers/serial/sh-sci.h +++ b/trunk/drivers/serial/sh-sci.h @@ -133,7 +133,7 @@ # define SCSPTR3 0xffed0024 /* 16 bit SCIF */ # define SCSPTR4 0xffee0024 /* 16 bit SCIF */ # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ -# define SCIF_ORER 0x0001 /* Overrun error bit */ +# define SCIF_OPER 0x0001 /* Overrun error bit */ # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ defined(CONFIG_CPU_SUBTYPE_SH7203) || \ diff --git a/trunk/drivers/spi/spi_gpio.c b/trunk/drivers/spi/spi_gpio.c index f5ed9721aabb..49698cabc30d 100644 --- a/trunk/drivers/spi/spi_gpio.c +++ b/trunk/drivers/spi/spi_gpio.c @@ -114,7 +114,7 @@ static inline void setmosi(const struct spi_device *spi, int is_on) static inline int getmiso(const struct spi_device *spi) { - return !!gpio_get_value(SPI_MISO_GPIO); + return gpio_get_value(SPI_MISO_GPIO); } #undef pdata diff --git a/trunk/drivers/staging/android/Kconfig b/trunk/drivers/staging/android/Kconfig index 604bd1e0d546..6b996db0dd6a 100644 --- a/trunk/drivers/staging/android/Kconfig +++ b/trunk/drivers/staging/android/Kconfig @@ -27,7 +27,6 @@ menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION bool "Android RAM Console Enable error correction" default n depends on ANDROID_RAM_CONSOLE - depends on !ANDROID_RAM_CONSOLE_EARLY_INIT select REED_SOLOMON select REED_SOLOMON_ENC8 select REED_SOLOMON_DEC8 diff --git a/trunk/drivers/staging/android/ram_console.c b/trunk/drivers/staging/android/ram_console.c index 643ac5ce381d..bf006857a87a 100644 --- a/trunk/drivers/staging/android/ram_console.c +++ b/trunk/drivers/staging/android/ram_console.c @@ -224,23 +224,9 @@ static int __init ram_console_init(struct ram_console_buffer *buffer, ram_console_buffer_size = buffer_size - sizeof(struct ram_console_buffer); - if (ram_console_buffer_size > buffer_size) { - pr_err("ram_console: buffer %p, invalid size %d, datasize %d\n", - buffer, buffer_size, ram_console_buffer_size); - return 0; - } - #ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) + 1) * ECC_SIZE; - - if (ram_console_buffer_size > buffer_size) { - pr_err("ram_console: buffer %p, invalid size %d, " - "non-ecc datasize %d\n", - buffer, buffer_size, ram_console_buffer_size); - return 0; - } - ram_console_par_buffer = buffer->data + ram_console_buffer_size; diff --git a/trunk/drivers/staging/android/timed_gpio.c b/trunk/drivers/staging/android/timed_gpio.c index 33daff0481d2..903270cbbe02 100644 --- a/trunk/drivers/staging/android/timed_gpio.c +++ b/trunk/drivers/staging/android/timed_gpio.c @@ -50,7 +50,7 @@ static ssize_t gpio_enable_show(struct device *dev, struct device_attribute *att if (hrtimer_active(&gpio_data->timer)) { ktime_t r = hrtimer_get_remaining(&gpio_data->timer); struct timeval t = ktime_to_timeval(r); - remaining = t.tv_sec * 1000 + t.tv_usec / 1000; + remaining = t.tv_sec * 1000 + t.tv_usec; } else remaining = 0; diff --git a/trunk/drivers/staging/at76_usb/Kconfig b/trunk/drivers/staging/at76_usb/Kconfig index 8606f9621624..4c0e55e15448 100644 --- a/trunk/drivers/staging/at76_usb/Kconfig +++ b/trunk/drivers/staging/at76_usb/Kconfig @@ -1,6 +1,6 @@ config USB_ATMEL tristate "Atmel at76c503/at76c505/at76c505a USB cards" - depends on WLAN_80211 && USB + depends on MAC80211 && WLAN_80211 && USB default N select FW_LOADER ---help--- diff --git a/trunk/drivers/staging/at76_usb/at76_usb.c b/trunk/drivers/staging/at76_usb/at76_usb.c index c8e4d31c7df2..185533e54769 100644 --- a/trunk/drivers/staging/at76_usb/at76_usb.c +++ b/trunk/drivers/staging/at76_usb/at76_usb.c @@ -6,6 +6,7 @@ * Copyright (c) 2004 Nick Jones * Copyright (c) 2004 Balint Seeber * Copyright (c) 2007 Guido Guenther + * Copyright (c) 2007 Kalle Valo * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -16,6 +17,13 @@ * Atmel AT76C503A/505/505A. * * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed + * + * TODO for the mac80211 port: + * o adhoc support + * o RTS/CTS support + * o Power Save Mode support + * o support for short/long preambles + * o export variables through debugfs/sysfs */ #include @@ -36,7 +44,7 @@ #include #include #include -#include +#include #include "at76_usb.h" @@ -76,31 +84,43 @@ #define DBG_WE_EVENTS 0x08000000 /* dump wireless events */ #define DBG_FW 0x10000000 /* firmware download */ #define DBG_DFU 0x20000000 /* device firmware upgrade */ +#define DBG_CMD 0x40000000 +#define DBG_MAC80211 0x80000000 #define DBG_DEFAULTS 0 /* Use our own dbg macro */ #define at76_dbg(bits, format, arg...) \ - do { \ - if (at76_debug & (bits)) \ +do { \ + if (at76_debug & (bits)) \ + printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \ +} while (0) + +#define at76_dbg_dump(bits, buf, len, format, arg...) \ +do { \ + if (at76_debug & (bits)) { \ printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \ - } while (0) + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); \ + } \ +} while (0) static int at76_debug = DBG_DEFAULTS; +#define FIRMWARE_IS_WPA(ver) ((ver.major == 1) && (ver.minor == 103)) + /* Protect against concurrent firmware loading and parsing */ static struct mutex fw_mutex; static struct fwentry firmwares[] = { - [0] = {""}, - [BOARD_503_ISL3861] = {"atmel_at76c503-i3861.bin"}, - [BOARD_503_ISL3863] = {"atmel_at76c503-i3863.bin"}, - [BOARD_503] = {"atmel_at76c503-rfmd.bin"}, - [BOARD_503_ACC] = {"atmel_at76c503-rfmd-acc.bin"}, - [BOARD_505] = {"atmel_at76c505-rfmd.bin"}, - [BOARD_505_2958] = {"atmel_at76c505-rfmd2958.bin"}, - [BOARD_505A] = {"atmel_at76c505a-rfmd2958.bin"}, - [BOARD_505AMX] = {"atmel_at76c505amx-rfmd.bin"}, + [0] = { "" }, + [BOARD_503_ISL3861] = { "atmel_at76c503-i3861.bin" }, + [BOARD_503_ISL3863] = { "atmel_at76c503-i3863.bin" }, + [BOARD_503] = { "atmel_at76c503-rfmd.bin" }, + [BOARD_503_ACC] = { "atmel_at76c503-rfmd-acc.bin" }, + [BOARD_505] = { "atmel_at76c505-rfmd.bin" }, + [BOARD_505_2958] = { "atmel_at76c505-rfmd2958.bin" }, + [BOARD_505A] = { "atmel_at76c505a-rfmd2958.bin" }, + [BOARD_505AMX] = { "atmel_at76c505amx-rfmd.bin" }, }; #define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops) @@ -110,135 +130,133 @@ static struct usb_device_id dev_table[] = { * at76c503-i3861 */ /* Generic AT76C503/3861 device */ - {USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* Linksys WUSB11 v2.1/v2.6 */ - {USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* Netgear MA101 rev. A */ - {USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* Tekram U300C / Allnet ALL0193 */ - {USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* HP HN210W J7801A */ - {USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* Sitecom/Z-Com/Zyxel M4Y-750 */ - {USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* Dynalink/Askey WLL013 (intersil) */ - {USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */ - {USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* BenQ AWL300 */ - {USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* Addtron AWU-120, Compex WLU11 */ - {USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* Intel AP310 AnyPoint II USB */ - {USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* Dynalink L11U */ - {USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* Arescom WL-210, FCC id 07J-GL2411USB */ - {USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* I-O DATA WN-B11/USB */ - {USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* BT Voyager 1010 */ - {USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861)}, + { USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861) }, /* * at76c503-i3863 */ /* Generic AT76C503/3863 device */ - {USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863)}, + { USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863) }, /* Samsung SWL-2100U */ - {USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863)}, + { USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863) }, /* * at76c503-rfmd */ /* Generic AT76C503/RFMD device */ - {USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503) }, /* Dynalink/Askey WLL013 (rfmd) */ - {USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503) }, /* Linksys WUSB11 v2.6 */ - {USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503) }, /* Network Everywhere NWU11B */ - {USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503) }, /* Netgear MA101 rev. B */ - {USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503) }, /* D-Link DWL-120 rev. E */ - {USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503) }, /* Actiontec 802UAT1, HWU01150-01UK */ - {USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503) }, /* AirVast W-Buddie WN210 */ - {USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503) }, /* Dick Smith Electronics XH1153 802.11b USB adapter */ - {USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503) }, /* CNet CNUSB611 */ - {USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503) }, /* FiberLine FL-WL200U */ - {USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503) }, /* BenQ AWL400 USB stick */ - {USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503) }, /* 3Com 3CRSHEW696 */ - {USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503) }, /* Siemens Santis ADSL WLAN USB adapter WLL 013 */ - {USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503) }, /* Belkin F5D6050, version 2 */ - {USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503) }, /* iBlitzz, BWU613 (not *B or *SB) */ - {USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503) }, /* Gigabyte GN-WLBM101 */ - {USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503) }, /* Planex GW-US11S */ - {USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503) }, /* Internal WLAN adapter in h5[4,5]xx series iPAQs */ - {USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503) }, /* Corega Wireless LAN USB-11 mini */ - {USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503) }, /* Corega Wireless LAN USB-11 mini2 */ - {USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503) }, /* Uniden PCW100 */ - {USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503)}, + { USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503) }, /* * at76c503-rfmd-acc */ /* SMC2664W */ - {USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC)}, + { USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC) }, /* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */ - {USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC)}, + { USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC) }, /* * at76c505-rfmd */ /* Generic AT76C505/RFMD */ - {USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)}, + { USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505) }, /* * at76c505-rfmd2958 */ /* Generic AT76C505/RFMD, OvisLink WL-1130USB */ - {USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)}, + { USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) }, /* Fiberline FL-WL240U */ - {USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958)}, + { USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958) }, /* CNet CNUSB-611G */ - {USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958)}, + { USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958) }, /* Linksys WUSB11 v2.8 */ - {USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958)}, + { USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958) }, /* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */ - {USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958)}, + { USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958) }, /* Corega WLAN USB Stick 11 */ - {USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)}, + { USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) }, /* Microstar MSI Box MS6978 */ - {USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958)}, + { USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958) }, /* * at76c505a-rfmd2958 */ /* Generic AT76C505A device */ - {USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A)}, + { USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A) }, /* Generic AT76C505AS device */ - {USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)}, + { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) }, /* Siemens Gigaset USB WLAN Adapter 11 */ - {USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)}, - /* OQO Model 01+ Internal Wi-Fi */ - {USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A)}, + { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) }, /* * at76c505amx-rfmd */ /* Generic AT76C505AMX device */ - {USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)}, - {} + { USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX) }, + { } }; MODULE_DEVICE_TABLE(usb, dev_table); @@ -246,26 +264,8 @@ MODULE_DEVICE_TABLE(usb, dev_table); /* Supported rates of this hardware, bit 7 marks basic rates */ static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 }; -/* Frequency of each channel in MHz */ -static const long channel_frequency[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, - 2447, 2452, 2457, 2462, 2467, 2472, 2484 -}; - -#define NUM_CHANNELS ARRAY_SIZE(channel_frequency) - static const char *const preambles[] = { "long", "short", "auto" }; -static const char *const mac_states[] = { - [MAC_INIT] = "INIT", - [MAC_SCANNING] = "SCANNING", - [MAC_AUTH] = "AUTH", - [MAC_ASSOC] = "ASSOC", - [MAC_JOINING] = "JOINING", - [MAC_CONNECTED] = "CONNECTED", - [MAC_OWN_IBSS] = "OWN_IBSS" -}; - /* Firmware download */ /* DFU states */ #define STATE_IDLE 0x00 @@ -300,17 +300,30 @@ struct dfu_status { static inline int at76_is_intersil(enum board_type board) { - return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863); + if (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863) + return 1; + return 0; } static inline int at76_is_503rfmd(enum board_type board) { - return (board == BOARD_503 || board == BOARD_503_ACC); + if (board == BOARD_503 || board == BOARD_503_ACC) + return 1; + return 0; +} + +static inline int at76_is_505(enum board_type board) +{ + if (board == BOARD_505 || board == BOARD_505_2958) + return 1; + return 0; } static inline int at76_is_505a(enum board_type board) { - return (board == BOARD_505A || board == BOARD_505AMX); + if (board == BOARD_505A || board == BOARD_505AMX) + return 1; + return 0; } /* Load a block of the first (internal) part of the firmware */ @@ -491,41 +504,6 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, return ret; } -/* Report that the scan results are ready */ -static inline void at76_iwevent_scan_complete(struct net_device *netdev) -{ - union iwreq_data wrqu; - wrqu.data.length = 0; - wrqu.data.flags = 0; - wireless_send_event(netdev, SIOCGIWSCAN, &wrqu, NULL); - at76_dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", netdev->name); -} - -static inline void at76_iwevent_bss_connect(struct net_device *netdev, - u8 *bssid) -{ - union iwreq_data wrqu; - wrqu.data.length = 0; - wrqu.data.flags = 0; - memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL); - at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name, - __func__); -} - -static inline void at76_iwevent_bss_disconnect(struct net_device *netdev) -{ - union iwreq_data wrqu; - wrqu.data.length = 0; - wrqu.data.flags = 0; - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL); - at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name, - __func__); -} - #define HEX2STR_BUFFERS 4 #define HEX2STR_MAX_LEN 64 #define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10) @@ -597,37 +575,6 @@ static void at76_ledtrig_tx_activity(void) mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4); } -/* Check if the given ssid is hidden */ -static inline int at76_is_hidden_ssid(u8 *ssid, int length) -{ - static const u8 zeros[32]; - - if (length == 0) - return 1; - - if (length == 1 && ssid[0] == ' ') - return 1; - - return (memcmp(ssid, zeros, length) == 0); -} - -static inline void at76_free_bss_list(struct at76_priv *priv) -{ - struct list_head *next, *ptr; - unsigned long flags; - - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - - priv->curr_bss = NULL; - - list_for_each_safe(ptr, next, &priv->bss_list) { - list_del(ptr); - kfree(list_entry(ptr, struct bss_info, list)); - } - - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); -} - static int at76_remap(struct usb_device *udev) { int ret; @@ -651,7 +598,7 @@ static int at76_get_op_mode(struct usb_device *udev) return -ENOMEM; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33, USB_TYPE_VENDOR | USB_DIR_IN | - USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1, + USB_RECIP_INTERFACE, 0x01, 0, &op_mode, 1, USB_CTRL_GET_TIMEOUT); saved = *op_mode; kfree(op_mode); @@ -729,7 +676,7 @@ static int at76_get_hw_config(struct at76_priv *priv) kfree(hwcfg); if (ret < 0) printk(KERN_ERR "%s: cannot get HW Config (error %d)\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -738,15 +685,15 @@ static struct reg_domain const *at76_get_reg_domain(u16 code) { int i; static struct reg_domain const fd_tab[] = { - {0x10, "FCC (USA)", 0x7ff}, /* ch 1-11 */ - {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */ - {0x30, "ETSI (most of Europe)", 0x1fff}, /* ch 1-13 */ - {0x31, "Spain", 0x600}, /* ch 10-11 */ - {0x32, "France", 0x1e00}, /* ch 10-13 */ - {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */ - {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */ - {0x50, "Israel", 0x3fc}, /* ch 3-9 */ - {0x00, "", 0xffffffff} /* ch 1-32 */ + { 0x10, "FCC (USA)", 0x7ff }, /* ch 1-11 */ + { 0x20, "IC (Canada)", 0x7ff }, /* ch 1-11 */ + { 0x30, "ETSI (most of Europe)", 0x1fff }, /* ch 1-13 */ + { 0x31, "Spain", 0x600 }, /* ch 10-11 */ + { 0x32, "France", 0x1e00 }, /* ch 10-13 */ + { 0x40, "MKK (Japan)", 0x2000 }, /* ch 14 */ + { 0x41, "MKK1 (Japan)", 0x3fff }, /* ch 1-14 */ + { 0x50, "Israel", 0x3fc }, /* ch 3-9 */ + { 0x00, "", 0xffffffff } /* ch 1-32 */ }; /* Last entry is fallback for unknown domain code */ @@ -784,7 +731,7 @@ static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd) ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE, cmd, 0, stat_buf, - 40, USB_CTRL_GET_TIMEOUT); + sizeof(stat_buf), USB_CTRL_GET_TIMEOUT); if (ret >= 0) ret = stat_buf[5]; kfree(stat_buf); @@ -792,6 +739,24 @@ static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd) return ret; } +#define MAKE_CMD_CASE(c) case (c): return #c + +static const char *at76_get_cmd_string(u8 cmd_status) +{ + switch (cmd_status) { + MAKE_CMD_CASE(CMD_SET_MIB); + MAKE_CMD_CASE(CMD_GET_MIB); + MAKE_CMD_CASE(CMD_SCAN); + MAKE_CMD_CASE(CMD_JOIN); + MAKE_CMD_CASE(CMD_START_IBSS); + MAKE_CMD_CASE(CMD_RADIO_ON); + MAKE_CMD_CASE(CMD_RADIO_OFF); + MAKE_CMD_CASE(CMD_STARTUP); + } + + return "UNKNOWN"; +} + static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf, int buf_size) { @@ -807,6 +772,10 @@ static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf, cmd_buf->size = cpu_to_le16(buf_size); memcpy(cmd_buf->data, buf, buf_size); + at76_dbg_dump(DBG_CMD, cmd_buf, sizeof(struct at76_command) + buf_size, + "issuing command %s (0x%02x)", + at76_get_cmd_string(cmd), cmd); + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, 0, 0, cmd_buf, @@ -844,13 +813,13 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd) status = at76_get_cmd_status(priv->udev, cmd); if (status < 0) { printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n", - priv->netdev->name, status); + wiphy_name(priv->hw->wiphy), status); break; } at76_dbg(DBG_WAIT_COMPLETE, "%s: Waiting on cmd %d, status = %d (%s)", - priv->netdev->name, cmd, status, + wiphy_name(priv->hw->wiphy), cmd, status, at76_get_cmd_status_string(status)); if (status != CMD_STATUS_IN_PROGRESS @@ -861,7 +830,7 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd) if (time_after(jiffies, timeout)) { printk(KERN_ERR "%s: completion timeout for command %d\n", - priv->netdev->name, cmd); + wiphy_name(priv->hw->wiphy), cmd); status = -ETIMEDOUT; break; } @@ -884,7 +853,7 @@ static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf) if (ret != CMD_STATUS_COMPLETE) { printk(KERN_INFO "%s: set_mib: at76_wait_completion failed " - "with %d\n", priv->netdev->name, ret); + "with %d\n", wiphy_name(priv->hw->wiphy), ret); ret = -EIO; } @@ -905,7 +874,7 @@ static int at76_set_radio(struct at76_priv *priv, int enable) ret = at76_set_card_command(priv->udev, cmd, NULL, 0); if (ret < 0) printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n", - priv->netdev->name, cmd, ret); + wiphy_name(priv->hw->wiphy), cmd, ret); else ret = 1; @@ -926,44 +895,7 @@ static int at76_set_pm_mode(struct at76_priv *priv) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n", - priv->netdev->name, ret); - - return ret; -} - -/* Set the association id for power save mode */ -static int at76_set_associd(struct at76_priv *priv, u16 id) -{ - int ret = 0; - - priv->mib_buf.type = MIB_MAC_MGMT; - priv->mib_buf.size = 2; - priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id); - priv->mib_buf.data.word = cpu_to_le16(id); - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (associd) failed: %d\n", - priv->netdev->name, ret); - - return ret; -} - -/* Set the listen interval for power save mode */ -static int at76_set_listen_interval(struct at76_priv *priv, u16 interval) -{ - int ret = 0; - - priv->mib_buf.type = MIB_MAC; - priv->mib_buf.size = 2; - priv->mib_buf.index = offsetof(struct mib_mac, listen_interval); - priv->mib_buf.data.word = cpu_to_le16(interval); - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR - "%s: set_mib (listen_interval) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -980,7 +912,7 @@ static int at76_set_preamble(struct at76_priv *priv, u8 type) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -997,7 +929,7 @@ static int at76_set_frag(struct at76_priv *priv, u16 size) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -1014,7 +946,7 @@ static int at76_set_rts(struct at76_priv *priv, u16 size) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) printk(KERN_ERR "%s: set_mib (rts) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -1031,24 +963,41 @@ static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); return ret; } -static int at76_add_mac_address(struct at76_priv *priv, void *addr) +static int at76_set_tkip_bssid(struct at76_priv *priv, const void *addr) { int ret = 0; - priv->mib_buf.type = MIB_MAC_ADDR; + priv->mib_buf.type = MIB_MAC_ENCRYPTION; priv->mib_buf.size = ETH_ALEN; - priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr); + priv->mib_buf.index = offsetof(struct mib_mac_encryption, tkip_bssid); memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN); ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n", - priv->netdev->name, ret); + printk(KERN_ERR "%s: set_mib (MAC_ENCRYPTION, tkip_bssid) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); + + return ret; +} + +static int at76_reset_rsc(struct at76_priv *priv) +{ + int ret = 0; + + priv->mib_buf.type = MIB_MAC_ENCRYPTION; + priv->mib_buf.size = 4 * 8; + priv->mib_buf.index = offsetof(struct mib_mac_encryption, key_rsc); + memset(priv->mib_buf.data.data, 0 , priv->mib_buf.size); + + ret = at76_set_mib(priv, &priv->mib_buf); + if (ret < 0) + printk(KERN_ERR "%s: set_mib (MAC_ENCRYPTION, key_rsc) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -1067,16 +1016,16 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv) sizeof(struct mib_mac_addr)); if (ret < 0) { printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); goto exit; } at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x", - priv->netdev->name, + wiphy_name(priv->hw->wiphy), mac2str(m->mac_addr), m->res[0], m->res[1]); for (i = 0; i < ARRAY_SIZE(m->group_addr); i++) at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, " - "status %d", priv->netdev->name, i, + "status %d", wiphy_name(priv->hw->wiphy), i, mac2str(m->group_addr[i]), m->group_addr_status[i]); exit: kfree(m); @@ -1096,13 +1045,13 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv) sizeof(struct mib_mac_wep)); if (ret < 0) { printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); goto exit; } at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u " "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u " - "encr_level %u key %d", priv->netdev->name, + "encr_level %u key %d", wiphy_name(priv->hw->wiphy), m->privacy_invoked, m->wep_default_key_id, m->wep_key_mapping_len, m->exclude_unencrypted, le32_to_cpu(m->wep_icv_error_count), @@ -1114,12 +1063,55 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv) for (i = 0; i < WEP_KEYS; i++) at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s", - priv->netdev->name, i, + wiphy_name(priv->hw->wiphy), i, hex2str(m->wep_default_keyvalue[i], key_len)); exit: kfree(m); } +static void at76_dump_mib_mac_encryption(struct at76_priv *priv) +{ + int i; + int ret; + /*int key_len;*/ + struct mib_mac_encryption *m; + + m = kmalloc(sizeof(struct mib_mac_encryption), GFP_KERNEL); + if (!m) + return; + + ret = at76_get_mib(priv->udev, MIB_MAC_ENCRYPTION, m, + sizeof(struct mib_mac_encryption)); + if (ret < 0) { + dev_err(&priv->udev->dev, + "%s: at76_get_mib (MAC_ENCRYPTION) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); + goto exit; + } + + at76_dbg(DBG_MIB, + "%s: MIB MAC_ENCRYPTION: tkip_bssid %s priv_invoked %u " + "ciph_key_id %u grp_key_id %u excl_unencr %u " + "ckip_key_perm %u wep_icv_err %u wep_excluded %u", + wiphy_name(priv->hw->wiphy), mac2str(m->tkip_bssid), + m->privacy_invoked, m->cipher_default_key_id, + m->cipher_default_group_key_id, m->exclude_unencrypted, + m->ckip_key_permutation, + le32_to_cpu(m->wep_icv_error_count), + le32_to_cpu(m->wep_excluded_count)); + + /*key_len = (m->encryption_level == 1) ? + WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;*/ + + for (i = 0; i < CIPHER_KEYS; i++) + at76_dbg(DBG_MIB, "%s: MIB MAC_ENCRYPTION: key %d: %s", + wiphy_name(priv->hw->wiphy), i, + hex2str(m->cipher_default_keyvalue[i], + CIPHER_KEY_LEN)); +exit: + kfree(m); +} + static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) { int ret; @@ -1133,7 +1125,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) sizeof(struct mib_mac_mgmt)); if (ret < 0) { printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); goto exit; } @@ -1144,7 +1136,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) "pm_mode %d ibss_change %d res %d " "multi_domain_capability_implemented %d " "international_roaming %d country_string %.3s", - priv->netdev->name, le16_to_cpu(m->beacon_period), + wiphy_name(priv->hw->wiphy), le16_to_cpu(m->beacon_period), le16_to_cpu(m->CFP_max_duration), le16_to_cpu(m->medium_occupancy_limit), le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window), @@ -1169,7 +1161,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac)); if (ret < 0) { printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); goto exit; } @@ -1179,7 +1171,8 @@ static void at76_dump_mib_mac(struct at76_priv *priv) "scan_type %d scan_channel %d probe_delay %u " "min_channel_time %d max_channel_time %d listen_int %d " "desired_ssid %s desired_bssid %s desired_bsstype %d", - priv->netdev->name, le32_to_cpu(m->max_tx_msdu_lifetime), + wiphy_name(priv->hw->wiphy), + le32_to_cpu(m->max_tx_msdu_lifetime), le32_to_cpu(m->max_rx_lifetime), le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold), le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax), @@ -1205,7 +1198,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy)); if (ret < 0) { printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); goto exit; } @@ -1214,7 +1207,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv) "mpdu_max_length %d cca_mode_supported %d operation_rate_set " "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d " "phy_type %d current_reg_domain %d", - priv->netdev->name, le32_to_cpu(m->ed_threshold), + wiphy_name(priv->hw->wiphy), le32_to_cpu(m->ed_threshold), le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time), le16_to_cpu(m->preamble_length), le16_to_cpu(m->plcp_header_length), @@ -1238,13 +1231,14 @@ static void at76_dump_mib_local(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); if (ret < 0) { printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); goto exit; } at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d " "txautorate_fallback %d ssid_size %d promiscuous_mode %d " - "preamble_type %d", priv->netdev->name, m->beacon_enable, + "preamble_type %d", wiphy_name(priv->hw->wiphy), + m->beacon_enable, m->txautorate_fallback, m->ssid_size, m->promiscuous_mode, m->preamble_type); exit: @@ -1263,118 +1257,21 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv) sizeof(struct mib_mdomain)); if (ret < 0) { printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); goto exit; } at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s", - priv->netdev->name, + wiphy_name(priv->hw->wiphy), hex2str(m->channel_list, sizeof(m->channel_list))); at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s", - priv->netdev->name, + wiphy_name(priv->hw->wiphy), hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel))); exit: kfree(m); } -static int at76_get_current_bssid(struct at76_priv *priv) -{ - int ret = 0; - struct mib_mac_mgmt *mac_mgmt = - kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL); - - if (!mac_mgmt) { - ret = -ENOMEM; - goto exit; - } - - ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, mac_mgmt, - sizeof(struct mib_mac_mgmt)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib failed: %d\n", - priv->netdev->name, ret); - goto error; - } - memcpy(priv->bssid, mac_mgmt->current_bssid, ETH_ALEN); - printk(KERN_INFO "%s: using BSSID %s\n", priv->netdev->name, - mac2str(priv->bssid)); -error: - kfree(mac_mgmt); -exit: - return ret; -} - -static int at76_get_current_channel(struct at76_priv *priv) -{ - int ret = 0; - struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL); - - if (!phy) { - ret = -ENOMEM; - goto exit; - } - ret = at76_get_mib(priv->udev, MIB_PHY, phy, sizeof(struct mib_phy)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib(MIB_PHY) failed: %d\n", - priv->netdev->name, ret); - goto error; - } - priv->channel = phy->channel_id; -error: - kfree(phy); -exit: - return ret; -} - -/** - * at76_start_scan - start a scan - * - * @use_essid - use the configured ESSID in non passive mode - */ -static int at76_start_scan(struct at76_priv *priv, int use_essid) -{ - struct at76_req_scan scan; - - memset(&scan, 0, sizeof(struct at76_req_scan)); - memset(scan.bssid, 0xff, ETH_ALEN); - - if (use_essid) { - memcpy(scan.essid, priv->essid, IW_ESSID_MAX_SIZE); - scan.essid_size = priv->essid_size; - } else - scan.essid_size = 0; - - /* jal: why should we start at a certain channel? we do scan the whole - range allowed by reg domain. */ - scan.channel = priv->channel; - - /* atmelwlandriver differs between scan type 0 and 1 (active/passive) - For ad-hoc mode, it uses type 0 only. */ - scan.scan_type = priv->scan_mode; - - /* INFO: For probe_delay, not multiplying by 1024 as this will be - slightly less than min_channel_time - (per spec: probe delay < min. channel time) */ - scan.min_channel_time = cpu_to_le16(priv->scan_min_time); - scan.max_channel_time = cpu_to_le16(priv->scan_max_time); - scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000); - scan.international_scan = 0; - - /* other values are set to 0 for type 0 */ - - at76_dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, " - "channel = %d, probe_delay = %d, scan_min_time = %d, " - "scan_max_time = %d)", - priv->netdev->name, use_essid, - scan.international_scan, scan.channel, - le16_to_cpu(scan.probe_delay), - le16_to_cpu(scan.min_channel_time), - le16_to_cpu(scan.max_channel_time)); - - return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan)); -} - /* Enable monitor mode */ static int at76_start_monitor(struct at76_priv *priv) { @@ -1395,86 +1292,6 @@ static int at76_start_monitor(struct at76_priv *priv) return ret; } -static int at76_start_ibss(struct at76_priv *priv) -{ - struct at76_req_ibss bss; - int ret; - - WARN_ON(priv->mac_state != MAC_OWN_IBSS); - if (priv->mac_state != MAC_OWN_IBSS) - return -EBUSY; - - memset(&bss, 0, sizeof(struct at76_req_ibss)); - memset(bss.bssid, 0xff, ETH_ALEN); - memcpy(bss.essid, priv->essid, IW_ESSID_MAX_SIZE); - bss.essid_size = priv->essid_size; - bss.bss_type = ADHOC_MODE; - bss.channel = priv->channel; - - ret = at76_set_card_command(priv->udev, CMD_START_IBSS, &bss, - sizeof(struct at76_req_ibss)); - if (ret < 0) { - printk(KERN_ERR "%s: start_ibss failed: %d\n", - priv->netdev->name, ret); - return ret; - } - - ret = at76_wait_completion(priv, CMD_START_IBSS); - if (ret != CMD_STATUS_COMPLETE) { - printk(KERN_ERR "%s: start_ibss failed to complete, %d\n", - priv->netdev->name, ret); - return ret; - } - - ret = at76_get_current_bssid(priv); - if (ret < 0) - return ret; - - ret = at76_get_current_channel(priv); - if (ret < 0) - return ret; - - /* not sure what this is good for ??? */ - priv->mib_buf.type = MIB_MAC_MGMT; - priv->mib_buf.size = 1; - priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change); - priv->mib_buf.data.byte = 0; - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) { - printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n", - priv->netdev->name, ret); - return ret; - } - - netif_carrier_on(priv->netdev); - netif_start_queue(priv->netdev); - return 0; -} - -/* Request card to join BSS in managed or ad-hoc mode */ -static int at76_join_bss(struct at76_priv *priv, struct bss_info *ptr) -{ - struct at76_req_join join; - - BUG_ON(!ptr); - - memset(&join, 0, sizeof(struct at76_req_join)); - memcpy(join.bssid, ptr->bssid, ETH_ALEN); - memcpy(join.essid, ptr->ssid, ptr->ssid_len); - join.essid_size = ptr->ssid_len; - join.bss_type = (priv->iw_mode == IW_MODE_ADHOC ? 1 : 2); - join.channel = ptr->channel; - join.timeout = cpu_to_le16(2000); - - at76_dbg(DBG_PROGRESS, - "%s join addr %s ssid %s type %d ch %d timeout %d", - priv->netdev->name, mac2str(join.bssid), join.essid, - join.bss_type, join.channel, le16_to_cpu(join.timeout)); - return at76_set_card_command(priv->udev, CMD_JOIN, &join, - sizeof(struct at76_req_join)); -} - /* Calculate padding from txbuf->wlength (which excludes the USB TX header), likely to compensate a flaw in the AT76C503A USB part ... */ static inline int at76_calc_padding(int wlen) @@ -1493,14 +1310,6 @@ static inline int at76_calc_padding(int wlen) return 0; } -/* We are doing a lot of things here in an interrupt. Need - a bh handler (Watching TV with a TV card is probably - a good test: if you see flickers, we are doing too much. - Currently I do see flickers... even with our tasklet :-( ) - Maybe because the bttv driver and usb-uhci use the same interrupt -*/ -/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't - * solve everything.. (alex) */ static void at76_rx_callback(struct urb *urb) { struct at76_priv *priv = urb->context; @@ -1510,1911 +1319,67 @@ static void at76_rx_callback(struct urb *urb) return; } -static void at76_tx_callback(struct urb *urb) +static int at76_submit_rx_urb(struct at76_priv *priv) { - struct at76_priv *priv = urb->context; - struct net_device_stats *stats = &priv->stats; - unsigned long flags; - struct at76_tx_buffer *mgmt_buf; int ret; + int size; + struct sk_buff *skb = priv->rx_skb; - switch (urb->status) { - case 0: - stats->tx_packets++; - break; - case -ENOENT: - case -ECONNRESET: - /* urb has been unlinked */ - return; - default: - at76_dbg(DBG_URB, "%s - nonzero tx status received: %d", - __func__, urb->status); - stats->tx_errors++; - break; + if (!priv->rx_urb) { + printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n", + wiphy_name(priv->hw->wiphy), __func__); + return -EFAULT; } - spin_lock_irqsave(&priv->mgmt_spinlock, flags); - mgmt_buf = priv->next_mgmt_bulk; - priv->next_mgmt_bulk = NULL; - spin_unlock_irqrestore(&priv->mgmt_spinlock, flags); + if (!skb) { + skb = dev_alloc_skb(sizeof(struct at76_rx_buffer)); + if (!skb) { + printk(KERN_ERR "%s: cannot allocate rx skbuff\n", + wiphy_name(priv->hw->wiphy)); + ret = -ENOMEM; + goto exit; + } + priv->rx_skb = skb; + } else { + skb_push(skb, skb_headroom(skb)); + skb_trim(skb, 0); + } - if (!mgmt_buf) { - netif_wake_queue(priv->netdev); - return; + size = skb_tailroom(skb); + usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe, + skb_put(skb, size), size, at76_rx_callback, priv); + ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC); + if (ret < 0) { + if (ret == -ENODEV) + at76_dbg(DBG_DEVSTART, + "usb_submit_urb returned -ENODEV"); + else + printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); } - /* we don't copy the padding bytes, but add them - to the length */ - memcpy(priv->bulk_out_buffer, mgmt_buf, - le16_to_cpu(mgmt_buf->wlength) + AT76_TX_HDRLEN); - usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, - priv->bulk_out_buffer, - le16_to_cpu(mgmt_buf->wlength) + mgmt_buf->padding + - AT76_TX_HDRLEN, at76_tx_callback, priv); - ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); - if (ret) - printk(KERN_ERR "%s: error in tx submit urb: %d\n", - priv->netdev->name, ret); +exit: + if (ret < 0 && ret != -ENODEV) + printk(KERN_ERR "%s: cannot submit rx urb - please unload the " + "driver and/or power cycle the device\n", + wiphy_name(priv->hw->wiphy)); - kfree(mgmt_buf); + return ret; } -/* Send a management frame on bulk-out. txbuf->wlength must be set */ -static int at76_tx_mgmt(struct at76_priv *priv, struct at76_tx_buffer *txbuf) +/* Download external firmware */ +static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) { - unsigned long flags; int ret; - int urb_status; - void *oldbuf = NULL; + int op_mode; + int blockno = 0; + int bsize; + u8 *block; + u8 *buf = fwe->extfw; + int size = fwe->extfw_size; - netif_carrier_off(priv->netdev); /* stop netdev watchdog */ - netif_stop_queue(priv->netdev); /* stop tx data packets */ - - spin_lock_irqsave(&priv->mgmt_spinlock, flags); - - urb_status = priv->tx_urb->status; - if (urb_status == -EINPROGRESS) { - /* cannot transmit now, put in the queue */ - oldbuf = priv->next_mgmt_bulk; - priv->next_mgmt_bulk = txbuf; - } - spin_unlock_irqrestore(&priv->mgmt_spinlock, flags); - - if (oldbuf) { - /* a data/mgmt tx is already pending in the URB - - if this is no error in some situations we must - implement a queue or silently modify the old msg */ - printk(KERN_ERR "%s: removed pending mgmt buffer %s\n", - priv->netdev->name, hex2str(oldbuf, 64)); - kfree(oldbuf); - return 0; - } - - txbuf->tx_rate = TX_RATE_1MBIT; - txbuf->padding = at76_calc_padding(le16_to_cpu(txbuf->wlength)); - memset(txbuf->reserved, 0, sizeof(txbuf->reserved)); - - if (priv->next_mgmt_bulk) - printk(KERN_ERR "%s: URB status %d, but mgmt is pending\n", - priv->netdev->name, urb_status); - - at76_dbg(DBG_TX_MGMT, - "%s: tx mgmt: wlen %d tx_rate %d pad %d %s", - priv->netdev->name, le16_to_cpu(txbuf->wlength), - txbuf->tx_rate, txbuf->padding, - hex2str(txbuf->packet, le16_to_cpu(txbuf->wlength))); - - /* txbuf was not consumed above -> send mgmt msg immediately */ - memcpy(priv->bulk_out_buffer, txbuf, - le16_to_cpu(txbuf->wlength) + AT76_TX_HDRLEN); - usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, - priv->bulk_out_buffer, - le16_to_cpu(txbuf->wlength) + txbuf->padding + - AT76_TX_HDRLEN, at76_tx_callback, priv); - ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); - if (ret) - printk(KERN_ERR "%s: error in tx submit urb: %d\n", - priv->netdev->name, ret); - - kfree(txbuf); - - return ret; -} - -/* Go to the next information element */ -static inline void next_ie(struct ieee80211_info_element **ie) -{ - *ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]); -} - -/* Challenge is the challenge string (in TLV format) - we got with seq_nr 2 for shared secret authentication only and - send in seq_nr 3 WEP encrypted to prove we have the correct WEP key; - otherwise it is NULL */ -static int at76_auth_req(struct at76_priv *priv, struct bss_info *bss, - int seq_nr, struct ieee80211_info_element *challenge) -{ - struct at76_tx_buffer *tx_buffer; - struct ieee80211_hdr_3addr *mgmt; - struct ieee80211_auth *req; - int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE : - AUTH_FRAME_SIZE + 1 + 1 + challenge->len); - - BUG_ON(!bss); - BUG_ON(seq_nr == 3 && !challenge); - tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC); - if (!tx_buffer) - return -ENOMEM; - - req = (struct ieee80211_auth *)tx_buffer->packet; - mgmt = &req->header; - - /* make wireless header */ - /* first auth msg is not encrypted, only the second (seq_nr == 3) */ - mgmt->frame_ctl = - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH | - (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0)); - - mgmt->duration_id = cpu_to_le16(0x8000); - memcpy(mgmt->addr1, bss->bssid, ETH_ALEN); - memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN); - memcpy(mgmt->addr3, bss->bssid, ETH_ALEN); - mgmt->seq_ctl = cpu_to_le16(0); - - req->algorithm = cpu_to_le16(priv->auth_mode); - req->transaction = cpu_to_le16(seq_nr); - req->status = cpu_to_le16(0); - - if (seq_nr == 3) - memcpy(req->info_element, challenge, 1 + 1 + challenge->len); - - /* init. at76_priv tx header */ - tx_buffer->wlength = cpu_to_le16(buf_len - AT76_TX_HDRLEN); - at76_dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d", - priv->netdev->name, mac2str(mgmt->addr3), - le16_to_cpu(req->algorithm), le16_to_cpu(req->transaction)); - if (seq_nr == 3) - at76_dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...", - priv->netdev->name, hex2str(req->info_element, 18)); - - /* either send immediately (if no data tx is pending - or put it in pending list */ - return at76_tx_mgmt(priv, tx_buffer); -} - -static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss) -{ - struct at76_tx_buffer *tx_buffer; - struct ieee80211_hdr_3addr *mgmt; - struct ieee80211_assoc_request *req; - struct ieee80211_info_element *ie; - char *essid; - int essid_len; - u16 capa; - - BUG_ON(!bss); - - tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC); - if (!tx_buffer) - return -ENOMEM; - - req = (struct ieee80211_assoc_request *)tx_buffer->packet; - mgmt = &req->header; - ie = req->info_element; - - /* make wireless header */ - mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_ASSOC_REQ); - - mgmt->duration_id = cpu_to_le16(0x8000); - memcpy(mgmt->addr1, bss->bssid, ETH_ALEN); - memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN); - memcpy(mgmt->addr3, bss->bssid, ETH_ALEN); - mgmt->seq_ctl = cpu_to_le16(0); - - /* we must set the Privacy bit in the capabilities to assure an - Agere-based AP with optional WEP transmits encrypted frames - to us. AP only set the Privacy bit in their capabilities - if WEP is mandatory in the BSS! */ - capa = bss->capa; - if (priv->wep_enabled) - capa |= WLAN_CAPABILITY_PRIVACY; - if (priv->preamble_type != PREAMBLE_TYPE_LONG) - capa |= WLAN_CAPABILITY_SHORT_PREAMBLE; - req->capability = cpu_to_le16(capa); - - req->listen_interval = cpu_to_le16(2 * bss->beacon_interval); - - /* write TLV data elements */ - - ie->id = MFIE_TYPE_SSID; - ie->len = bss->ssid_len; - memcpy(ie->data, bss->ssid, bss->ssid_len); - next_ie(&ie); - - ie->id = MFIE_TYPE_RATES; - ie->len = sizeof(hw_rates); - memcpy(ie->data, hw_rates, sizeof(hw_rates)); - next_ie(&ie); /* ie points behind the supp_rates field */ - - /* init. at76_priv tx header */ - tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt); - - ie = req->info_element; - essid = ie->data; - essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len); - - next_ie(&ie); /* points to IE of rates now */ - at76_dbg(DBG_TX_MGMT, - "%s: AssocReq bssid %s capa 0x%04x ssid %.*s rates %s", - priv->netdev->name, mac2str(mgmt->addr3), - le16_to_cpu(req->capability), essid_len, essid, - hex2str(ie->data, ie->len)); - - /* either send immediately (if no data tx is pending - or put it in pending list */ - return at76_tx_mgmt(priv, tx_buffer); -} - -/* We got to check the bss_list for old entries */ -static void at76_bss_list_timeout(unsigned long par) -{ - struct at76_priv *priv = (struct at76_priv *)par; - unsigned long flags; - struct list_head *lptr, *nptr; - struct bss_info *ptr; - - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - - list_for_each_safe(lptr, nptr, &priv->bss_list) { - - ptr = list_entry(lptr, struct bss_info, list); - - if (ptr != priv->curr_bss - && time_after(jiffies, ptr->last_rx + BSS_LIST_TIMEOUT)) { - at76_dbg(DBG_BSS_TABLE_RM, - "%s: bss_list: removing old BSS %s ch %d", - priv->netdev->name, mac2str(ptr->bssid), - ptr->channel); - list_del(&ptr->list); - kfree(ptr); - } - } - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); - /* restart the timer */ - mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT); -} - -static inline void at76_set_mac_state(struct at76_priv *priv, - enum mac_state mac_state) -{ - at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name, - mac_states[mac_state]); - priv->mac_state = mac_state; -} - -static void at76_dump_bss_table(struct at76_priv *priv) -{ - struct bss_info *ptr; - unsigned long flags; - struct list_head *lptr; - - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - - at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name, - priv->curr_bss); - - list_for_each(lptr, &priv->bss_list) { - ptr = list_entry(lptr, struct bss_info, list); - at76_dbg(DBG_BSS_TABLE, "0x%p: bssid %s channel %d ssid %.*s " - "(%s) capa 0x%04x rates %s rssi %d link %d noise %d", - ptr, mac2str(ptr->bssid), ptr->channel, ptr->ssid_len, - ptr->ssid, hex2str(ptr->ssid, ptr->ssid_len), - ptr->capa, hex2str(ptr->rates, ptr->rates_len), - ptr->rssi, ptr->link_qual, ptr->noise_level); - } - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); -} - -/* Called upon successful association to mark interface as connected */ -static void at76_work_assoc_done(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - work_assoc_done); - - mutex_lock(&priv->mtx); - - WARN_ON(priv->mac_state != MAC_ASSOC); - WARN_ON(!priv->curr_bss); - if (priv->mac_state != MAC_ASSOC || !priv->curr_bss) - goto exit; - - if (priv->iw_mode == IW_MODE_INFRA) { - if (priv->pm_mode != AT76_PM_OFF) { - /* calculate the listen interval in units of - beacon intervals of the curr_bss */ - u32 pm_period_beacon = (priv->pm_period >> 10) / - priv->curr_bss->beacon_interval; - - pm_period_beacon = max(pm_period_beacon, 2u); - pm_period_beacon = min(pm_period_beacon, 0xffffu); - - at76_dbg(DBG_PM, - "%s: pm_mode %d assoc id 0x%x listen int %d", - priv->netdev->name, priv->pm_mode, - priv->assoc_id, pm_period_beacon); - - at76_set_associd(priv, priv->assoc_id); - at76_set_listen_interval(priv, (u16)pm_period_beacon); - } - schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT); - } - at76_set_pm_mode(priv); - - netif_carrier_on(priv->netdev); - netif_wake_queue(priv->netdev); - at76_set_mac_state(priv, MAC_CONNECTED); - at76_iwevent_bss_connect(priv->netdev, priv->curr_bss->bssid); - at76_dbg(DBG_PROGRESS, "%s: connected to BSSID %s", - priv->netdev->name, mac2str(priv->curr_bss->bssid)); - -exit: - mutex_unlock(&priv->mtx); -} - -/* We only store the new mac address in netdev struct, - it gets set when the netdev is opened. */ -static int at76_set_mac_address(struct net_device *netdev, void *addr) -{ - struct sockaddr *mac = addr; - memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN); - return 1; -} - -static struct net_device_stats *at76_get_stats(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - return &priv->stats; -} - -static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d", - priv->wstats.qual.qual, priv->wstats.qual.level, - priv->wstats.qual.noise, priv->wstats.qual.updated); - - return &priv->wstats; -} - -static void at76_set_multicast(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - int promisc; - - promisc = ((netdev->flags & IFF_PROMISC) != 0); - if (promisc != priv->promisc) { - /* This gets called in interrupt, must reschedule */ - priv->promisc = promisc; - schedule_work(&priv->work_set_promisc); - } -} - -/* Stop all network activity, flush all pending tasks */ -static void at76_quiesce(struct at76_priv *priv) -{ - unsigned long flags; - - netif_stop_queue(priv->netdev); - netif_carrier_off(priv->netdev); - - at76_set_mac_state(priv, MAC_INIT); - - cancel_delayed_work(&priv->dwork_get_scan); - cancel_delayed_work(&priv->dwork_beacon); - cancel_delayed_work(&priv->dwork_auth); - cancel_delayed_work(&priv->dwork_assoc); - cancel_delayed_work(&priv->dwork_restart); - - spin_lock_irqsave(&priv->mgmt_spinlock, flags); - kfree(priv->next_mgmt_bulk); - priv->next_mgmt_bulk = NULL; - spin_unlock_irqrestore(&priv->mgmt_spinlock, flags); -} - -/******************************************************************************* - * at76_priv implementations of iw_handler functions: - */ -static int at76_iw_handler_commit(struct net_device *netdev, - struct iw_request_info *info, - void *null, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name, - __func__); - - if (priv->mac_state != MAC_INIT) - at76_quiesce(priv); - - /* Wait half second before the restart to process subsequent - * requests from the same iwconfig in a single restart */ - schedule_delayed_work(&priv->dwork_restart, HZ / 2); - - return 0; -} - -static int at76_iw_handler_get_name(struct net_device *netdev, - struct iw_request_info *info, - char *name, char *extra) -{ - strcpy(name, "IEEE 802.11b"); - at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name); - return 0; -} - -static int at76_iw_handler_set_freq(struct net_device *netdev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int chan = -1; - int ret = -EIWCOMMIT; - at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d", - netdev->name, freq->m, freq->e); - - if ((freq->e == 0) && (freq->m <= 1000)) - /* Setting by channel number */ - chan = freq->m; - else { - /* Setting by frequency - search the table */ - int mult = 1; - int i; - - for (i = 0; i < (6 - freq->e); i++) - mult *= 10; - - for (i = 0; i < NUM_CHANNELS; i++) { - if (freq->m == (channel_frequency[i] * mult)) - chan = i + 1; - } - } - - if (chan < 1 || !priv->domain) - /* non-positive channels are invalid - * we need a domain info to set the channel - * either that or an invalid frequency was - * provided by the user */ - ret = -EINVAL; - else if (!(priv->domain->channel_map & (1 << (chan - 1)))) { - printk(KERN_INFO "%s: channel %d not allowed for domain %s\n", - priv->netdev->name, chan, priv->domain->name); - ret = -EINVAL; - } - - if (ret == -EIWCOMMIT) { - priv->channel = chan; - at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name, - chan); - } - - return ret; -} - -static int at76_iw_handler_get_freq(struct net_device *netdev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - freq->m = priv->channel; - freq->e = 0; - - if (priv->channel) - at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d", - netdev->name, channel_frequency[priv->channel - 1], 6); - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name, - priv->channel); - - return 0; -} - -static int at76_iw_handler_set_mode(struct net_device *netdev, - struct iw_request_info *info, - __u32 *mode, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode); - - if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) && - (*mode != IW_MODE_MONITOR)) - return -EINVAL; - - priv->iw_mode = *mode; - if (priv->iw_mode != IW_MODE_INFRA) - priv->pm_mode = AT76_PM_OFF; - - return -EIWCOMMIT; -} - -static int at76_iw_handler_get_mode(struct net_device *netdev, - struct iw_request_info *info, - __u32 *mode, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - *mode = priv->iw_mode; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode); - - return 0; -} - -static int at76_iw_handler_get_range(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - /* inspired by atmel.c */ - struct at76_priv *priv = netdev_priv(netdev); - struct iw_range *range = (struct iw_range *)extra; - int i; - - data->length = sizeof(struct iw_range); - memset(range, 0, sizeof(struct iw_range)); - - /* TODO: range->throughput = xxxxxx; */ - - range->min_nwid = 0x0000; - range->max_nwid = 0x0000; - - /* this driver doesn't maintain sensitivity information */ - range->sensitivity = 0; - - range->max_qual.qual = 100; - range->max_qual.level = 100; - range->max_qual.noise = 0; - range->max_qual.updated = IW_QUAL_NOISE_INVALID; - - range->avg_qual.qual = 50; - range->avg_qual.level = 50; - range->avg_qual.noise = 0; - range->avg_qual.updated = IW_QUAL_NOISE_INVALID; - - range->bitrate[0] = 1000000; - range->bitrate[1] = 2000000; - range->bitrate[2] = 5500000; - range->bitrate[3] = 11000000; - range->num_bitrates = 4; - - range->min_rts = 0; - range->max_rts = MAX_RTS_THRESHOLD; - - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_ON; - range->pm_capa = IW_POWER_PERIOD | IW_POWER_ALL_R; - - range->encoding_size[0] = WEP_SMALL_KEY_LEN; - range->encoding_size[1] = WEP_LARGE_KEY_LEN; - range->num_encoding_sizes = 2; - range->max_encoding_tokens = WEP_KEYS; - - /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power - - take this for all (ignore antenna gains) */ - range->txpower[0] = 15; - range->num_txpower = 1; - range->txpower_capa = IW_TXPOW_DBM; - - range->we_version_source = WIRELESS_EXT; - range->we_version_compiled = WIRELESS_EXT; - - /* same as the values used in atmel.c */ - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->r_time_flags = 0; - range->min_retry = 1; - range->max_retry = 255; - - range->num_channels = NUM_CHANNELS; - range->num_frequency = 0; - - for (i = 0; i < NUM_CHANNELS; i++) { - /* test if channel map bit is raised */ - if (priv->domain->channel_map & (0x1 << i)) { - range->num_frequency += 1; - - range->freq[i].i = i + 1; - range->freq[i].m = channel_frequency[i] * 100000; - range->freq[i].e = 1; /* freq * 10^1 */ - } - } - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name); - - return 0; -} - -static int at76_iw_handler_set_spy(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = 0; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d", - netdev->name, data->length); - - spin_lock_bh(&priv->spy_spinlock); - ret = iw_handler_set_spy(priv->netdev, info, (union iwreq_data *)data, - extra); - spin_unlock_bh(&priv->spy_spinlock); - - return ret; -} - -static int at76_iw_handler_get_spy(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - - struct at76_priv *priv = netdev_priv(netdev); - int ret = 0; - - spin_lock_bh(&priv->spy_spinlock); - ret = iw_handler_get_spy(priv->netdev, info, - (union iwreq_data *)data, extra); - spin_unlock_bh(&priv->spy_spinlock); - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d", - netdev->name, data->length); - - return ret; -} - -static int at76_iw_handler_set_thrspy(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)", - netdev->name, data->length); - - spin_lock_bh(&priv->spy_spinlock); - ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data, - extra); - spin_unlock_bh(&priv->spy_spinlock); - - return ret; -} - -static int at76_iw_handler_get_thrspy(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret; - - spin_lock_bh(&priv->spy_spinlock); - ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data, - extra); - spin_unlock_bh(&priv->spy_spinlock); - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)", - netdev->name, data->length); - - return ret; -} - -static int at76_iw_handler_set_wap(struct net_device *netdev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name, - mac2str(ap_addr->sa_data)); - - /* if the incoming address == ff:ff:ff:ff:ff:ff, the user has - chosen any or auto AP preference */ - if (is_broadcast_ether_addr(ap_addr->sa_data) - || is_zero_ether_addr(ap_addr->sa_data)) - priv->wanted_bssid_valid = 0; - else { - /* user wants to set a preferred AP address */ - priv->wanted_bssid_valid = 1; - memcpy(priv->wanted_bssid, ap_addr->sa_data, ETH_ALEN); - } - - return -EIWCOMMIT; -} - -static int at76_iw_handler_get_wap(struct net_device *netdev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - ap_addr->sa_family = ARPHRD_ETHER; - memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN); - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name, - mac2str(ap_addr->sa_data)); - - return 0; -} - -static int at76_iw_handler_set_scan(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = 0; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name); - - if (mutex_lock_interruptible(&priv->mtx)) - return -EINTR; - - if (!netif_running(netdev)) { - ret = -ENETDOWN; - goto exit; - } - - /* jal: we don't allow "iwlist ethX scan" while we are - in monitor mode */ - if (priv->iw_mode == IW_MODE_MONITOR) { - ret = -EBUSY; - goto exit; - } - - /* Discard old scan results */ - if ((jiffies - priv->last_scan) > (20 * HZ)) - priv->scan_state = SCAN_IDLE; - priv->last_scan = jiffies; - - /* Initiate a scan command */ - if (priv->scan_state == SCAN_IN_PROGRESS) { - ret = -EBUSY; - goto exit; - } - - priv->scan_state = SCAN_IN_PROGRESS; - - at76_quiesce(priv); - - /* Try to do passive or active scan if WE asks as. */ - if (wrqu->data.length - && wrqu->data.length == sizeof(struct iw_scan_req)) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; - - if (req->scan_type == IW_SCAN_TYPE_PASSIVE) - priv->scan_mode = SCAN_TYPE_PASSIVE; - else if (req->scan_type == IW_SCAN_TYPE_ACTIVE) - priv->scan_mode = SCAN_TYPE_ACTIVE; - - /* Sanity check values? */ - if (req->min_channel_time > 0) - priv->scan_min_time = req->min_channel_time; - - if (req->max_channel_time > 0) - priv->scan_max_time = req->max_channel_time; - } - - /* change to scanning state */ - at76_set_mac_state(priv, MAC_SCANNING); - schedule_work(&priv->work_start_scan); - -exit: - mutex_unlock(&priv->mtx); - return ret; -} - -static int at76_iw_handler_get_scan(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - unsigned long flags; - struct list_head *lptr, *nptr; - struct bss_info *curr_bss; - struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL); - char *curr_val, *curr_pos = extra; - int i; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name); - - if (!iwe) - return -ENOMEM; - - if (priv->scan_state != SCAN_COMPLETED) { - /* scan not yet finished */ - kfree(iwe); - return -EAGAIN; - } - - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - - list_for_each_safe(lptr, nptr, &priv->bss_list) { - curr_bss = list_entry(lptr, struct bss_info, list); - - iwe->cmd = SIOCGIWAP; - iwe->u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6); - curr_pos = iwe_stream_add_event(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - IW_EV_ADDR_LEN); - - iwe->u.data.length = curr_bss->ssid_len; - iwe->cmd = SIOCGIWESSID; - iwe->u.data.flags = 1; - - curr_pos = iwe_stream_add_point(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - curr_bss->ssid); - - iwe->cmd = SIOCGIWMODE; - iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ? - IW_MODE_ADHOC : - (curr_bss->capa & WLAN_CAPABILITY_ESS) ? - IW_MODE_MASTER : IW_MODE_AUTO; - /* IW_MODE_AUTO = 0 which I thought is - * the most logical value to return in this case */ - curr_pos = iwe_stream_add_event(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - IW_EV_UINT_LEN); - - iwe->cmd = SIOCGIWFREQ; - iwe->u.freq.m = curr_bss->channel; - iwe->u.freq.e = 0; - curr_pos = iwe_stream_add_event(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - IW_EV_FREQ_LEN); - - iwe->cmd = SIOCGIWENCODE; - if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY) - iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe->u.data.flags = IW_ENCODE_DISABLED; - - iwe->u.data.length = 0; - curr_pos = iwe_stream_add_point(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - NULL); - - /* Add quality statistics */ - iwe->cmd = IWEVQUAL; - iwe->u.qual.noise = 0; - iwe->u.qual.updated = - IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED; - iwe->u.qual.level = (curr_bss->rssi * 100 / 42); - if (iwe->u.qual.level > 100) - iwe->u.qual.level = 100; - if (at76_is_intersil(priv->board_type)) - iwe->u.qual.qual = curr_bss->link_qual; - else { - iwe->u.qual.qual = 0; - iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID; - } - /* Add new value to event */ - curr_pos = iwe_stream_add_event(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - IW_EV_QUAL_LEN); - - /* Rate: stuffing multiple values in a single event requires - * a bit more of magic - Jean II */ - curr_val = curr_pos + IW_EV_LCP_LEN; - - iwe->cmd = SIOCGIWRATE; - /* Those two flags are ignored... */ - iwe->u.bitrate.fixed = 0; - iwe->u.bitrate.disabled = 0; - /* Max 8 values */ - for (i = 0; i < curr_bss->rates_len; i++) { - /* Bit rate given in 500 kb/s units (+ 0x80) */ - iwe->u.bitrate.value = - ((curr_bss->rates[i] & 0x7f) * 500000); - /* Add new value to event */ - curr_val = iwe_stream_add_value(info, curr_pos, - curr_val, - extra + - IW_SCAN_MAX_DATA, iwe, - IW_EV_PARAM_LEN); - } - - /* Check if we added any event */ - if ((curr_val - curr_pos) > IW_EV_LCP_LEN) - curr_pos = curr_val; - - /* more information may be sent back using IWECUSTOM */ - - } - - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); - - data->length = (curr_pos - extra); - data->flags = 0; - - kfree(iwe); - return 0; -} - -static int at76_iw_handler_set_essid(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra); - - if (data->flags) { - memcpy(priv->essid, extra, data->length); - priv->essid_size = data->length; - } else - priv->essid_size = 0; /* Use any SSID */ - - return -EIWCOMMIT; -} - -static int at76_iw_handler_get_essid(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - if (priv->essid_size) { - /* not the ANY ssid in priv->essid */ - data->flags = 1; - data->length = priv->essid_size; - memcpy(extra, priv->essid, data->length); - } else { - /* the ANY ssid was specified */ - if (priv->mac_state == MAC_CONNECTED && priv->curr_bss) { - /* report the SSID we have found */ - data->flags = 1; - data->length = priv->curr_bss->ssid_len; - memcpy(extra, priv->curr_bss->ssid, data->length); - } else { - /* report ANY back */ - data->flags = 0; - data->length = 0; - } - } - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name, - data->length, extra); - - return 0; -} - -static int at76_iw_handler_set_rate(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *bitrate, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name, - bitrate->value); - - switch (bitrate->value) { - case -1: - priv->txrate = TX_RATE_AUTO; - break; /* auto rate */ - case 1000000: - priv->txrate = TX_RATE_1MBIT; - break; - case 2000000: - priv->txrate = TX_RATE_2MBIT; - break; - case 5500000: - priv->txrate = TX_RATE_5_5MBIT; - break; - case 11000000: - priv->txrate = TX_RATE_11MBIT; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int at76_iw_handler_get_rate(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *bitrate, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = 0; - - switch (priv->txrate) { - /* return max rate if RATE_AUTO */ - case TX_RATE_AUTO: - bitrate->value = 11000000; - break; - case TX_RATE_1MBIT: - bitrate->value = 1000000; - break; - case TX_RATE_2MBIT: - bitrate->value = 2000000; - break; - case TX_RATE_5_5MBIT: - bitrate->value = 5500000; - break; - case TX_RATE_11MBIT: - bitrate->value = 11000000; - break; - default: - ret = -EINVAL; - } - - bitrate->fixed = (priv->txrate != TX_RATE_AUTO); - bitrate->disabled = 0; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name, - bitrate->value); - - return ret; -} - -static int at76_iw_handler_set_rts(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = -EIWCOMMIT; - int rthr = rts->value; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s", - netdev->name, rts->value, (rts->disabled) ? "true" : "false"); - - if (rts->disabled) - rthr = MAX_RTS_THRESHOLD; - - if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD)) - ret = -EINVAL; - else - priv->rts_threshold = rthr; - - return ret; -} - -static int at76_iw_handler_get_rts(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - rts->value = priv->rts_threshold; - rts->disabled = (rts->value >= MAX_RTS_THRESHOLD); - rts->fixed = 1; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s", - netdev->name, rts->value, (rts->disabled) ? "true" : "false"); - - return 0; -} - -static int at76_iw_handler_set_frag(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *frag, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = -EIWCOMMIT; - int fthr = frag->value; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s", - netdev->name, frag->value, - (frag->disabled) ? "true" : "false"); - - if (frag->disabled) - fthr = MAX_FRAG_THRESHOLD; - - if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD)) - ret = -EINVAL; - else - priv->frag_threshold = fthr & ~0x1; /* get an even value */ - - return ret; -} - -static int at76_iw_handler_get_frag(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *frag, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - frag->value = priv->frag_threshold; - frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD); - frag->fixed = 1; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s", - netdev->name, frag->value, - (frag->disabled) ? "true" : "false"); - - return 0; -} - -static int at76_iw_handler_get_txpow(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *power, char *extra) -{ - power->value = 15; - power->fixed = 1; /* No power control */ - power->disabled = 0; - power->flags = IW_TXPOW_DBM; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name, - power->value); - - return 0; -} - -/* jal: short retry is handled by the firmware (at least 0.90.x), - while long retry is not (?) */ -static int at76_iw_handler_set_retry(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *retry, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d", - netdev->name, retry->disabled, retry->flags, retry->value); - - if (!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) { - if ((retry->flags & IW_RETRY_MIN) || - !(retry->flags & IW_RETRY_MAX)) - priv->short_retry_limit = retry->value; - else - ret = -EINVAL; - } else - ret = -EINVAL; - - return ret; -} - -/* Adapted (ripped) from atmel.c */ -static int at76_iw_handler_get_retry(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *retry, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name); - - retry->disabled = 0; /* Can't be disabled */ - retry->flags = IW_RETRY_LIMIT; - retry->value = priv->short_retry_limit; - - return 0; -} - -static int at76_iw_handler_set_encode(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *encoding, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int index = (encoding->flags & IW_ENCODE_INDEX) - 1; - int len = encoding->length; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x " - "pointer %p len %d", netdev->name, encoding->flags, - encoding->pointer, encoding->length); - at76_dbg(DBG_IOCTL, - "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d " - "auth_mode %s", netdev->name, - (priv->wep_enabled) ? "true" : "false", priv->wep_key_id, - (priv->auth_mode == - WLAN_AUTH_SHARED_KEY) ? "restricted" : "open"); - - /* take the old default key if index is invalid */ - if ((index < 0) || (index >= WEP_KEYS)) - index = priv->wep_key_id; - - if (len > 0) { - if (len > WEP_LARGE_KEY_LEN) - len = WEP_LARGE_KEY_LEN; - - memset(priv->wep_keys[index], 0, WEP_KEY_LEN); - memcpy(priv->wep_keys[index], extra, len); - priv->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ? - WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN; - priv->wep_enabled = 1; - } - - priv->wep_key_id = index; - priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0); - - if (encoding->flags & IW_ENCODE_RESTRICTED) - priv->auth_mode = WLAN_AUTH_SHARED_KEY; - if (encoding->flags & IW_ENCODE_OPEN) - priv->auth_mode = WLAN_AUTH_OPEN; - - at76_dbg(DBG_IOCTL, - "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d " - "key_len %d auth_mode %s", netdev->name, - (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1, - priv->wep_keys_len[priv->wep_key_id], - (priv->auth_mode == - WLAN_AUTH_SHARED_KEY) ? "restricted" : "open"); - - return -EIWCOMMIT; -} - -static int at76_iw_handler_get_encode(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *encoding, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int index = (encoding->flags & IW_ENCODE_INDEX) - 1; - - if ((index < 0) || (index >= WEP_KEYS)) - index = priv->wep_key_id; - - encoding->flags = - (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ? - IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN; - - if (!priv->wep_enabled) - encoding->flags |= IW_ENCODE_DISABLED; - - if (encoding->pointer) { - encoding->length = priv->wep_keys_len[index]; - - memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]); - - encoding->flags |= (index + 1); - } - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x " - "pointer %p len %d", netdev->name, encoding->flags, - encoding->pointer, encoding->length); - at76_dbg(DBG_IOCTL, - "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d " - "key_len %d auth_mode %s", netdev->name, - (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1, - priv->wep_keys_len[priv->wep_key_id], - (priv->auth_mode == - WLAN_AUTH_SHARED_KEY) ? "restricted" : "open"); - - return 0; -} - -static int at76_iw_handler_set_power(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *prq, char *extra) -{ - int err = -EIWCOMMIT; - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, - "%s: SIOCSIWPOWER - disabled %s flags 0x%x value 0x%x", - netdev->name, (prq->disabled) ? "true" : "false", prq->flags, - prq->value); - - if (prq->disabled) - priv->pm_mode = AT76_PM_OFF; - else { - switch (prq->flags & IW_POWER_MODE) { - case IW_POWER_ALL_R: - case IW_POWER_ON: - break; - default: - err = -EINVAL; - goto exit; - } - if (prq->flags & IW_POWER_PERIOD) - priv->pm_period = prq->value; - - if (prq->flags & IW_POWER_TIMEOUT) { - err = -EINVAL; - goto exit; - } - priv->pm_mode = AT76_PM_ON; - } -exit: - return err; -} - -static int at76_iw_handler_get_power(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *power, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - power->disabled = (priv->pm_mode == AT76_PM_OFF); - if (!power->disabled) { - power->flags = IW_POWER_PERIOD | IW_POWER_ALL_R; - power->value = priv->pm_period; - } - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - %s flags 0x%x value 0x%x", - netdev->name, power->disabled ? "disabled" : "enabled", - power->flags, power->value); - - return 0; -} - -/******************************************************************************* - * Private IOCTLS - */ -static int at76_iw_set_short_preamble(struct net_device *netdev, - struct iw_request_info *info, char *name, - char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int val = *((int *)name); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d", - netdev->name, val); - - if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO) - ret = -EINVAL; - else - priv->preamble_type = val; - - return ret; -} - -static int at76_iw_get_short_preamble(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)", - preambles[priv->preamble_type], priv->preamble_type); - return 0; -} - -static int at76_iw_set_debug(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - char *ptr; - u32 val; - - if (data->length > 0) { - val = simple_strtol(extra, &ptr, 0); - - if (ptr == extra) - val = DBG_DEFAULTS; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG input %d: %s -> 0x%x", - netdev->name, data->length, extra, val); - } else - val = DBG_DEFAULTS; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x", - netdev->name, at76_debug, val); - - /* jal: some more output to pin down lockups */ - at76_dbg(DBG_IOCTL, "%s: netif running %d queue_stopped %d " - "carrier_ok %d", netdev->name, netif_running(netdev), - netif_queue_stopped(netdev), netif_carrier_ok(netdev)); - - at76_debug = val; - - return 0; -} - -static int at76_iw_get_debug(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug); - return 0; -} - -static int at76_iw_set_powersave_mode(struct net_device *netdev, - struct iw_request_info *info, char *name, - char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int val = *((int *)name); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_POWERSAVE_MODE, %d (%s)", - netdev->name, val, - val == AT76_PM_OFF ? "active" : val == AT76_PM_ON ? "save" : - val == AT76_PM_SMART ? "smart save" : ""); - if (val < AT76_PM_OFF || val > AT76_PM_SMART) - ret = -EINVAL; - else - priv->pm_mode = val; - - return ret; -} - -static int at76_iw_get_powersave_mode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int *param = (int *)extra; - - param[0] = priv->pm_mode; - return 0; -} - -static int at76_iw_set_scan_times(struct net_device *netdev, - struct iw_request_info *info, char *name, - char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int mint = *((int *)name); - int maxt = *((int *)name + 1); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_TIMES - min %d max %d", - netdev->name, mint, maxt); - if (mint <= 0 || maxt <= 0 || mint > maxt) - ret = -EINVAL; - else { - priv->scan_min_time = mint; - priv->scan_max_time = maxt; - } - - return ret; -} - -static int at76_iw_get_scan_times(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int *param = (int *)extra; - - param[0] = priv->scan_min_time; - param[1] = priv->scan_max_time; - return 0; -} - -static int at76_iw_set_scan_mode(struct net_device *netdev, - struct iw_request_info *info, char *name, - char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int val = *((int *)name); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_MODE - mode %s", - netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" : - (val = SCAN_TYPE_PASSIVE) ? "passive" : ""); - - if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE) - ret = -EINVAL; - else - priv->scan_mode = val; - - return ret; -} - -static int at76_iw_get_scan_mode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int *param = (int *)extra; - - param[0] = priv->scan_mode; - return 0; -} - -#define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f - -/* Standard wireless handlers */ -static const iw_handler at76_handlers[] = { - AT76_SET_HANDLER(SIOCSIWCOMMIT, at76_iw_handler_commit), - AT76_SET_HANDLER(SIOCGIWNAME, at76_iw_handler_get_name), - AT76_SET_HANDLER(SIOCSIWFREQ, at76_iw_handler_set_freq), - AT76_SET_HANDLER(SIOCGIWFREQ, at76_iw_handler_get_freq), - AT76_SET_HANDLER(SIOCSIWMODE, at76_iw_handler_set_mode), - AT76_SET_HANDLER(SIOCGIWMODE, at76_iw_handler_get_mode), - AT76_SET_HANDLER(SIOCGIWRANGE, at76_iw_handler_get_range), - AT76_SET_HANDLER(SIOCSIWSPY, at76_iw_handler_set_spy), - AT76_SET_HANDLER(SIOCGIWSPY, at76_iw_handler_get_spy), - AT76_SET_HANDLER(SIOCSIWTHRSPY, at76_iw_handler_set_thrspy), - AT76_SET_HANDLER(SIOCGIWTHRSPY, at76_iw_handler_get_thrspy), - AT76_SET_HANDLER(SIOCSIWAP, at76_iw_handler_set_wap), - AT76_SET_HANDLER(SIOCGIWAP, at76_iw_handler_get_wap), - AT76_SET_HANDLER(SIOCSIWSCAN, at76_iw_handler_set_scan), - AT76_SET_HANDLER(SIOCGIWSCAN, at76_iw_handler_get_scan), - AT76_SET_HANDLER(SIOCSIWESSID, at76_iw_handler_set_essid), - AT76_SET_HANDLER(SIOCGIWESSID, at76_iw_handler_get_essid), - AT76_SET_HANDLER(SIOCSIWRATE, at76_iw_handler_set_rate), - AT76_SET_HANDLER(SIOCGIWRATE, at76_iw_handler_get_rate), - AT76_SET_HANDLER(SIOCSIWRTS, at76_iw_handler_set_rts), - AT76_SET_HANDLER(SIOCGIWRTS, at76_iw_handler_get_rts), - AT76_SET_HANDLER(SIOCSIWFRAG, at76_iw_handler_set_frag), - AT76_SET_HANDLER(SIOCGIWFRAG, at76_iw_handler_get_frag), - AT76_SET_HANDLER(SIOCGIWTXPOW, at76_iw_handler_get_txpow), - AT76_SET_HANDLER(SIOCSIWRETRY, at76_iw_handler_set_retry), - AT76_SET_HANDLER(SIOCGIWRETRY, at76_iw_handler_get_retry), - AT76_SET_HANDLER(SIOCSIWENCODE, at76_iw_handler_set_encode), - AT76_SET_HANDLER(SIOCGIWENCODE, at76_iw_handler_get_encode), - AT76_SET_HANDLER(SIOCSIWPOWER, at76_iw_handler_set_power), - AT76_SET_HANDLER(SIOCGIWPOWER, at76_iw_handler_get_power) -}; - -#define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f - -/* Private wireless handlers */ -static const iw_handler at76_priv_handlers[] = { - AT76_SET_PRIV(AT76_SET_SHORT_PREAMBLE, at76_iw_set_short_preamble), - AT76_SET_PRIV(AT76_GET_SHORT_PREAMBLE, at76_iw_get_short_preamble), - AT76_SET_PRIV(AT76_SET_DEBUG, at76_iw_set_debug), - AT76_SET_PRIV(AT76_GET_DEBUG, at76_iw_get_debug), - AT76_SET_PRIV(AT76_SET_POWERSAVE_MODE, at76_iw_set_powersave_mode), - AT76_SET_PRIV(AT76_GET_POWERSAVE_MODE, at76_iw_get_powersave_mode), - AT76_SET_PRIV(AT76_SET_SCAN_TIMES, at76_iw_set_scan_times), - AT76_SET_PRIV(AT76_GET_SCAN_TIMES, at76_iw_get_scan_times), - AT76_SET_PRIV(AT76_SET_SCAN_MODE, at76_iw_set_scan_mode), - AT76_SET_PRIV(AT76_GET_SCAN_MODE, at76_iw_get_scan_mode), -}; - -/* Names and arguments of private wireless handlers */ -static const struct iw_priv_args at76_priv_args[] = { - /* 0 - long, 1 - short */ - {AT76_SET_SHORT_PREAMBLE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"}, - - {AT76_GET_SHORT_PREAMBLE, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"}, - - /* we must pass the new debug mask as a string, because iwpriv cannot - * parse hex numbers starting with 0x :-( */ - {AT76_SET_DEBUG, - IW_PRIV_TYPE_CHAR | 10, 0, "set_debug"}, - - {AT76_GET_DEBUG, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"}, - - /* 1 - active, 2 - power save, 3 - smart power save */ - {AT76_SET_POWERSAVE_MODE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_powersave"}, - - {AT76_GET_POWERSAVE_MODE, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"}, - - /* min_channel_time, max_channel_time */ - {AT76_SET_SCAN_TIMES, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_scan_times"}, - - {AT76_GET_SCAN_TIMES, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"}, - - /* 0 - active, 1 - passive scan */ - {AT76_SET_SCAN_MODE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_scan_mode"}, - - {AT76_GET_SCAN_MODE, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"}, -}; - -static const struct iw_handler_def at76_handler_def = { - .num_standard = ARRAY_SIZE(at76_handlers), - .num_private = ARRAY_SIZE(at76_priv_handlers), - .num_private_args = ARRAY_SIZE(at76_priv_args), - .standard = at76_handlers, - .private = at76_priv_handlers, - .private_args = at76_priv_args, - .get_wireless_stats = at76_get_wireless_stats, -}; - -static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 }; - -/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with - * a SNAP OID of 0 (0x00, 0x00, 0x00) */ -static const u8 rfc1042sig[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; - -static int at76_tx(struct sk_buff *skb, struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - struct net_device_stats *stats = &priv->stats; - int ret = 0; - int wlen; - int submit_len; - struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; - struct ieee80211_hdr_3addr *i802_11_hdr = - (struct ieee80211_hdr_3addr *)tx_buffer->packet; - u8 *payload = i802_11_hdr->payload; - struct ethhdr *eh = (struct ethhdr *)skb->data; - - if (netif_queue_stopped(netdev)) { - printk(KERN_ERR "%s: %s called while netdev is stopped\n", - netdev->name, __func__); - /* skip this packet */ - dev_kfree_skb(skb); - return 0; - } - - if (priv->tx_urb->status == -EINPROGRESS) { - printk(KERN_ERR "%s: %s called while tx urb is pending\n", - netdev->name, __func__); - /* skip this packet */ - dev_kfree_skb(skb); - return 0; - } - - if (skb->len < ETH_HLEN) { - printk(KERN_ERR "%s: %s: skb too short (%d)\n", - netdev->name, __func__, skb->len); - dev_kfree_skb(skb); - return 0; - } - - at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */ - - /* we can get rid of memcpy if we set netdev->hard_header_len to - reserve enough space, but we would need to keep the skb around */ - - if (ntohs(eh->h_proto) <= ETH_DATA_LEN) { - /* this is a 802.3 packet */ - if (skb->len >= ETH_HLEN + sizeof(rfc1042sig) - && skb->data[ETH_HLEN] == rfc1042sig[0] - && skb->data[ETH_HLEN + 1] == rfc1042sig[1]) { - /* higher layer delivered SNAP header - keep it */ - memcpy(payload, skb->data + ETH_HLEN, - skb->len - ETH_HLEN); - wlen = IEEE80211_3ADDR_LEN + skb->len - ETH_HLEN; - } else { - printk(KERN_ERR "%s: dropping non-SNAP 802.2 packet " - "(DSAP 0x%02x SSAP 0x%02x cntrl 0x%02x)\n", - priv->netdev->name, skb->data[ETH_HLEN], - skb->data[ETH_HLEN + 1], - skb->data[ETH_HLEN + 2]); - dev_kfree_skb(skb); - return 0; - } - } else { - /* add RFC 1042 header in front */ - memcpy(payload, rfc1042sig, sizeof(rfc1042sig)); - memcpy(payload + sizeof(rfc1042sig), &eh->h_proto, - skb->len - offsetof(struct ethhdr, h_proto)); - wlen = IEEE80211_3ADDR_LEN + sizeof(rfc1042sig) + skb->len - - offsetof(struct ethhdr, h_proto); - } - - /* make wireless header */ - i802_11_hdr->frame_ctl = - cpu_to_le16(IEEE80211_FTYPE_DATA | - (priv->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) | - (priv->iw_mode == - IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0)); - - if (priv->iw_mode == IW_MODE_ADHOC) { - memcpy(i802_11_hdr->addr1, eh->h_dest, ETH_ALEN); - memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN); - memcpy(i802_11_hdr->addr3, priv->bssid, ETH_ALEN); - } else if (priv->iw_mode == IW_MODE_INFRA) { - memcpy(i802_11_hdr->addr1, priv->bssid, ETH_ALEN); - memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN); - memcpy(i802_11_hdr->addr3, eh->h_dest, ETH_ALEN); - } - - i802_11_hdr->duration_id = cpu_to_le16(0); - i802_11_hdr->seq_ctl = cpu_to_le16(0); - - /* setup 'Atmel' header */ - tx_buffer->wlength = cpu_to_le16(wlen); - tx_buffer->tx_rate = priv->txrate; - /* for broadcast destination addresses, the firmware 0.100.x - seems to choose the highest rate set with CMD_STARTUP in - basic_rate_set replacing this value */ - - memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved)); - - tx_buffer->padding = at76_calc_padding(wlen); - submit_len = wlen + AT76_TX_HDRLEN + tx_buffer->padding; - - at76_dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", priv->netdev->name, - hex2str(skb->data, 32)); - at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr %s", - priv->netdev->name, - le16_to_cpu(tx_buffer->wlength), - tx_buffer->padding, tx_buffer->tx_rate, - hex2str(i802_11_hdr, sizeof(*i802_11_hdr))); - at76_dbg(DBG_TX_DATA_CONTENT, "%s payload %s", priv->netdev->name, - hex2str(payload, 48)); - - /* send stuff */ - netif_stop_queue(netdev); - netdev->trans_start = jiffies; - - usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer, - submit_len, at76_tx_callback, priv); - ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); - if (ret) { - stats->tx_errors++; - printk(KERN_ERR "%s: error in tx submit urb: %d\n", - netdev->name, ret); - if (ret == -EINVAL) - printk(KERN_ERR - "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n", - priv->netdev->name, priv->tx_urb, - priv->tx_urb->hcpriv, priv->tx_urb->complete); - } else { - stats->tx_bytes += skb->len; - dev_kfree_skb(skb); - } - - return ret; -} - -static void at76_tx_timeout(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - - if (!priv) - return; - dev_warn(&netdev->dev, "tx timeout."); - - usb_unlink_urb(priv->tx_urb); - priv->stats.tx_errors++; -} - -static int at76_submit_rx_urb(struct at76_priv *priv) -{ - int ret; - int size; - struct sk_buff *skb = priv->rx_skb; - - if (!priv->rx_urb) { - printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n", - priv->netdev->name, __func__); - return -EFAULT; - } - - if (!skb) { - skb = dev_alloc_skb(sizeof(struct at76_rx_buffer)); - if (!skb) { - printk(KERN_ERR "%s: cannot allocate rx skbuff\n", - priv->netdev->name); - ret = -ENOMEM; - goto exit; - } - priv->rx_skb = skb; - } else { - skb_push(skb, skb_headroom(skb)); - skb_trim(skb, 0); - } - - size = skb_tailroom(skb); - usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe, - skb_put(skb, size), size, at76_rx_callback, priv); - ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC); - if (ret < 0) { - if (ret == -ENODEV) - at76_dbg(DBG_DEVSTART, - "usb_submit_urb returned -ENODEV"); - else - printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n", - priv->netdev->name, ret); - } - -exit: - if (ret < 0 && ret != -ENODEV) - printk(KERN_ERR "%s: cannot submit rx urb - please unload the " - "driver and/or power cycle the device\n", - priv->netdev->name); - - return ret; -} - -static int at76_open(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = 0; - - at76_dbg(DBG_PROC_ENTRY, "%s(): entry", __func__); - - if (mutex_lock_interruptible(&priv->mtx)) - return -EINTR; - - /* if netdev->dev_addr != priv->mac_addr we must - set the mac address in the device ! */ - if (compare_ether_addr(netdev->dev_addr, priv->mac_addr)) { - if (at76_add_mac_address(priv, netdev->dev_addr) >= 0) - at76_dbg(DBG_PROGRESS, "%s: set new MAC addr %s", - netdev->name, mac2str(netdev->dev_addr)); - } - - priv->scan_state = SCAN_IDLE; - priv->last_scan = jiffies; - - ret = at76_submit_rx_urb(priv); - if (ret < 0) { - printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n", - netdev->name, ret); - goto error; - } - - schedule_delayed_work(&priv->dwork_restart, 0); - - at76_dbg(DBG_PROC_ENTRY, "%s(): end", __func__); -error: - mutex_unlock(&priv->mtx); - return ret < 0 ? ret : 0; -} - -static int at76_stop(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_DEVSTART, "%s: ENTER", __func__); - - if (mutex_lock_interruptible(&priv->mtx)) - return -EINTR; - - at76_quiesce(priv); - - if (!priv->device_unplugged) { - /* We are called by "ifconfig ethX down", not because the - * device is not available anymore. */ - at76_set_radio(priv, 0); - - /* We unlink rx_urb because at76_open() re-submits it. - * If unplugged, at76_delete_device() takes care of it. */ - usb_kill_urb(priv->rx_urb); - } - - /* free the bss_list */ - at76_free_bss_list(priv); - - mutex_unlock(&priv->mtx); - at76_dbg(DBG_DEVSTART, "%s: EXIT", __func__); - - return 0; -} - -static void at76_ethtool_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *info) -{ - struct at76_priv *priv = netdev_priv(netdev); - - strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); - strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); - - usb_make_path(priv->udev, info->bus_info, sizeof(info->bus_info)); - - snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d-%d", - priv->fw_version.major, priv->fw_version.minor, - priv->fw_version.patch, priv->fw_version.build); -} - -static u32 at76_ethtool_get_link(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - return priv->mac_state == MAC_CONNECTED; -} - -static struct ethtool_ops at76_ethtool_ops = { - .get_drvinfo = at76_ethtool_get_drvinfo, - .get_link = at76_ethtool_get_link, -}; - -/* Download external firmware */ -static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) -{ - int ret; - int op_mode; - int blockno = 0; - int bsize; - u8 *block; - u8 *buf = fwe->extfw; - int size = fwe->extfw_size; - - if (!buf || !size) - return -ENOENT; + if (!buf || !size) + return -ENOENT; op_mode = at76_get_op_mode(udev); at76_dbg(DBG_DEVSTART, "opmode %d", op_mode); @@ -3458,444 +1423,44 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) exit: kfree(block); if (ret < 0) - dev_printk(KERN_ERR, &udev->dev, - "downloading external firmware failed: %d\n", ret); - return ret; -} - -/* Download internal firmware */ -static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) -{ - int ret; - int need_remap = !at76_is_505a(fwe->board_type); - - ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size, - need_remap ? 0 : 2 * HZ); - - if (ret < 0) { - dev_printk(KERN_ERR, &udev->dev, - "downloading internal fw failed with %d\n", ret); - goto exit; - } - - at76_dbg(DBG_DEVSTART, "sending REMAP"); - - /* no REMAP for 505A (see SF driver) */ - if (need_remap) { - ret = at76_remap(udev); - if (ret < 0) { - dev_printk(KERN_ERR, &udev->dev, - "sending REMAP failed with %d\n", ret); - goto exit; - } - } - - at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds"); - schedule_timeout_interruptible(2 * HZ + 1); - usb_reset_device(udev); - -exit: - return ret; -} - -static int at76_match_essid(struct at76_priv *priv, struct bss_info *ptr) -{ - /* common criteria for both modi */ - - int ret = (priv->essid_size == 0 /* ANY ssid */ || - (priv->essid_size == ptr->ssid_len && - !memcmp(priv->essid, ptr->ssid, ptr->ssid_len))); - if (!ret) - at76_dbg(DBG_BSS_MATCH, - "%s bss table entry %p: essid didn't match", - priv->netdev->name, ptr); - return ret; -} - -static inline int at76_match_mode(struct at76_priv *priv, struct bss_info *ptr) -{ - int ret; - - if (priv->iw_mode == IW_MODE_ADHOC) - ret = ptr->capa & WLAN_CAPABILITY_IBSS; - else - ret = ptr->capa & WLAN_CAPABILITY_ESS; - if (!ret) - at76_dbg(DBG_BSS_MATCH, - "%s bss table entry %p: mode didn't match", - priv->netdev->name, ptr); - return ret; -} - -static int at76_match_rates(struct at76_priv *priv, struct bss_info *ptr) -{ - int i; - - for (i = 0; i < ptr->rates_len; i++) { - u8 rate = ptr->rates[i]; - - if (!(rate & 0x80)) - continue; - - /* this is a basic rate we have to support - (see IEEE802.11, ch. 7.3.2.2) */ - if (rate != (0x80 | hw_rates[0]) - && rate != (0x80 | hw_rates[1]) - && rate != (0x80 | hw_rates[2]) - && rate != (0x80 | hw_rates[3])) { - at76_dbg(DBG_BSS_MATCH, - "%s: bss table entry %p: basic rate %02x not " - "supported", priv->netdev->name, ptr, rate); - return 0; - } - } - - /* if we use short preamble, the bss must support it */ - if (priv->preamble_type == PREAMBLE_TYPE_SHORT && - !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) { - at76_dbg(DBG_BSS_MATCH, - "%s: %p does not support short preamble", - priv->netdev->name, ptr); - return 0; - } else - return 1; -} - -static inline int at76_match_wep(struct at76_priv *priv, struct bss_info *ptr) -{ - if (!priv->wep_enabled && ptr->capa & WLAN_CAPABILITY_PRIVACY) { - /* we have disabled WEP, but the BSS signals privacy */ - at76_dbg(DBG_BSS_MATCH, - "%s: bss table entry %p: requires encryption", - priv->netdev->name, ptr); - return 0; - } - /* otherwise if the BSS does not signal privacy it may well - accept encrypted packets from us ... */ - return 1; -} - -static inline int at76_match_bssid(struct at76_priv *priv, struct bss_info *ptr) -{ - if (!priv->wanted_bssid_valid || - !compare_ether_addr(ptr->bssid, priv->wanted_bssid)) - return 1; - - at76_dbg(DBG_BSS_MATCH, - "%s: requested bssid - %s does not match", - priv->netdev->name, mac2str(priv->wanted_bssid)); - at76_dbg(DBG_BSS_MATCH, - " AP bssid - %s of bss table entry %p", - mac2str(ptr->bssid), ptr); - return 0; -} - -/** - * at76_match_bss - try to find a matching bss in priv->bss - * - * last - last bss tried - * - * last == NULL signals a new round starting with priv->bss_list.next - * this function must be called inside an acquired priv->bss_list_spinlock - * otherwise the timeout on bss may remove the newly chosen entry - */ -static struct bss_info *at76_match_bss(struct at76_priv *priv, - struct bss_info *last) -{ - struct bss_info *ptr = NULL; - struct list_head *curr; - - curr = last ? last->list.next : priv->bss_list.next; - while (curr != &priv->bss_list) { - ptr = list_entry(curr, struct bss_info, list); - if (at76_match_essid(priv, ptr) && at76_match_mode(priv, ptr) - && at76_match_wep(priv, ptr) && at76_match_rates(priv, ptr) - && at76_match_bssid(priv, ptr)) - break; - curr = curr->next; - } - - if (curr == &priv->bss_list) - ptr = NULL; - /* otherwise ptr points to the struct bss_info we have chosen */ - - at76_dbg(DBG_BSS_TABLE, "%s %s: returned %p", priv->netdev->name, - __func__, ptr); - return ptr; -} - -/* Start joining a matching BSS, or create own IBSS */ -static void at76_work_join(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - work_join); - int ret; - unsigned long flags; - - mutex_lock(&priv->mtx); - - WARN_ON(priv->mac_state != MAC_JOINING); - if (priv->mac_state != MAC_JOINING) - goto exit; - - /* secure the access to priv->curr_bss ! */ - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - priv->curr_bss = at76_match_bss(priv, priv->curr_bss); - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); - - if (!priv->curr_bss) { - /* here we haven't found a matching (i)bss ... */ - if (priv->iw_mode == IW_MODE_ADHOC) { - at76_set_mac_state(priv, MAC_OWN_IBSS); - at76_start_ibss(priv); - goto exit; - } - /* haven't found a matching BSS in infra mode - try again */ - at76_set_mac_state(priv, MAC_SCANNING); - schedule_work(&priv->work_start_scan); - goto exit; - } - - ret = at76_join_bss(priv, priv->curr_bss); - if (ret < 0) { - printk(KERN_ERR "%s: join_bss failed with %d\n", - priv->netdev->name, ret); - goto exit; - } - - ret = at76_wait_completion(priv, CMD_JOIN); - if (ret != CMD_STATUS_COMPLETE) { - if (ret != CMD_STATUS_TIME_OUT) - printk(KERN_ERR "%s: join_bss completed with %d\n", - priv->netdev->name, ret); - else - printk(KERN_INFO "%s: join_bss ssid %s timed out\n", - priv->netdev->name, - mac2str(priv->curr_bss->bssid)); - - /* retry next BSS immediately */ - schedule_work(&priv->work_join); - goto exit; - } - - /* here we have joined the (I)BSS */ - if (priv->iw_mode == IW_MODE_ADHOC) { - struct bss_info *bptr = priv->curr_bss; - at76_set_mac_state(priv, MAC_CONNECTED); - /* get ESSID, BSSID and channel for priv->curr_bss */ - priv->essid_size = bptr->ssid_len; - memcpy(priv->essid, bptr->ssid, bptr->ssid_len); - memcpy(priv->bssid, bptr->bssid, ETH_ALEN); - priv->channel = bptr->channel; - at76_iwevent_bss_connect(priv->netdev, bptr->bssid); - netif_carrier_on(priv->netdev); - netif_start_queue(priv->netdev); - /* just to be sure */ - cancel_delayed_work(&priv->dwork_get_scan); - cancel_delayed_work(&priv->dwork_auth); - cancel_delayed_work(&priv->dwork_assoc); - } else { - /* send auth req */ - priv->retries = AUTH_RETRIES; - at76_set_mac_state(priv, MAC_AUTH); - at76_auth_req(priv, priv->curr_bss, 1, NULL); - at76_dbg(DBG_MGMT_TIMER, - "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__); - schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT); - } - -exit: - mutex_unlock(&priv->mtx); -} - -/* Reap scan results */ -static void at76_dwork_get_scan(struct work_struct *work) -{ - int status; - int ret; - struct at76_priv *priv = container_of(work, struct at76_priv, - dwork_get_scan.work); - - mutex_lock(&priv->mtx); - WARN_ON(priv->mac_state != MAC_SCANNING); - if (priv->mac_state != MAC_SCANNING) - goto exit; - - status = at76_get_cmd_status(priv->udev, CMD_SCAN); - if (status < 0) { - printk(KERN_ERR "%s: %s: at76_get_cmd_status failed with %d\n", - priv->netdev->name, __func__, status); - status = CMD_STATUS_IN_PROGRESS; - /* INFO: Hope it was a one off error - if not, scanning - further down the line and stop this cycle */ - } - at76_dbg(DBG_PROGRESS, - "%s %s: got cmd_status %d (state %s, need_any %d)", - priv->netdev->name, __func__, status, - mac_states[priv->mac_state], priv->scan_need_any); - - if (status != CMD_STATUS_COMPLETE) { - if ((status != CMD_STATUS_IN_PROGRESS) && - (status != CMD_STATUS_IDLE)) - printk(KERN_ERR "%s: %s: Bad scan status: %s\n", - priv->netdev->name, __func__, - at76_get_cmd_status_string(status)); - - /* the first cmd status after scan start is always a IDLE -> - start the timer to poll again until COMPLETED */ - at76_dbg(DBG_MGMT_TIMER, - "%s:%d: starting mgmt_timer for %d ticks", - __func__, __LINE__, SCAN_POLL_INTERVAL); - schedule_delayed_work(&priv->dwork_get_scan, - SCAN_POLL_INTERVAL); - goto exit; - } - - if (at76_debug & DBG_BSS_TABLE) - at76_dump_bss_table(priv); - - if (priv->scan_need_any) { - ret = at76_start_scan(priv, 0); - if (ret < 0) - printk(KERN_ERR - "%s: %s: start_scan (ANY) failed with %d\n", - priv->netdev->name, __func__, ret); - at76_dbg(DBG_MGMT_TIMER, - "%s:%d: starting mgmt_timer for %d ticks", __func__, - __LINE__, SCAN_POLL_INTERVAL); - schedule_delayed_work(&priv->dwork_get_scan, - SCAN_POLL_INTERVAL); - priv->scan_need_any = 0; - } else { - priv->scan_state = SCAN_COMPLETED; - /* report the end of scan to user space */ - at76_iwevent_scan_complete(priv->netdev); - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - } - -exit: - mutex_unlock(&priv->mtx); -} - -/* Handle loss of beacons from the AP */ -static void at76_dwork_beacon(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - dwork_beacon.work); - - mutex_lock(&priv->mtx); - if (priv->mac_state != MAC_CONNECTED || priv->iw_mode != IW_MODE_INFRA) - goto exit; - - /* We haven't received any beacons from out AP for BEACON_TIMEOUT */ - printk(KERN_INFO "%s: lost beacon bssid %s\n", - priv->netdev->name, mac2str(priv->curr_bss->bssid)); - - netif_carrier_off(priv->netdev); - netif_stop_queue(priv->netdev); - at76_iwevent_bss_disconnect(priv->netdev); - at76_set_mac_state(priv, MAC_SCANNING); - schedule_work(&priv->work_start_scan); - -exit: - mutex_unlock(&priv->mtx); -} - -/* Handle authentication response timeout */ -static void at76_dwork_auth(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - dwork_auth.work); - - mutex_lock(&priv->mtx); - WARN_ON(priv->mac_state != MAC_AUTH); - if (priv->mac_state != MAC_AUTH) - goto exit; - - at76_dbg(DBG_PROGRESS, "%s: authentication response timeout", - priv->netdev->name); - - if (priv->retries-- >= 0) { - at76_auth_req(priv, priv->curr_bss, 1, NULL); - at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", - __func__, __LINE__); - schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT); - } else { - /* try to get next matching BSS */ - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - } - -exit: - mutex_unlock(&priv->mtx); -} - -/* Handle association response timeout */ -static void at76_dwork_assoc(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - dwork_assoc.work); - - mutex_lock(&priv->mtx); - WARN_ON(priv->mac_state != MAC_ASSOC); - if (priv->mac_state != MAC_ASSOC) - goto exit; - - at76_dbg(DBG_PROGRESS, "%s: association response timeout", - priv->netdev->name); - - if (priv->retries-- >= 0) { - at76_assoc_req(priv, priv->curr_bss); - at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", - __func__, __LINE__); - schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT); - } else { - /* try to get next matching BSS */ - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - } - -exit: - mutex_unlock(&priv->mtx); + dev_printk(KERN_ERR, &udev->dev, + "downloading external firmware failed: %d\n", ret); + return ret; } -/* Read new bssid in ad-hoc mode */ -static void at76_work_new_bss(struct work_struct *work) +/* Download internal firmware */ +static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) { - struct at76_priv *priv = container_of(work, struct at76_priv, - work_new_bss); int ret; - struct mib_mac_mgmt mac_mgmt; + int need_remap = !at76_is_505a(fwe->board_type); - mutex_lock(&priv->mtx); + ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size, + need_remap ? 0 : 2 * HZ); - ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, &mac_mgmt, - sizeof(struct mib_mac_mgmt)); if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib failed: %d\n", - priv->netdev->name, ret); + dev_printk(KERN_ERR, &udev->dev, + "downloading internal fw failed with %d\n", ret); goto exit; } - at76_dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt.ibss_change); - memcpy(priv->bssid, mac_mgmt.current_bssid, ETH_ALEN); - at76_dbg(DBG_PROGRESS, "using BSSID %s", mac2str(priv->bssid)); - - at76_iwevent_bss_connect(priv->netdev, priv->bssid); + at76_dbg(DBG_DEVSTART, "sending REMAP"); - priv->mib_buf.type = MIB_MAC_MGMT; - priv->mib_buf.size = 1; - priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change); - priv->mib_buf.data.byte = 0; + /* no REMAP for 505A (see SF driver) */ + if (need_remap) { + ret = at76_remap(udev); + if (ret < 0) { + dev_printk(KERN_ERR, &udev->dev, + "sending REMAP failed with %d\n", ret); + goto exit; + } + } - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n", - priv->netdev->name, ret); + at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds"); + schedule_timeout_interruptible(2 * HZ + 1); + usb_reset_device(udev); exit: - mutex_unlock(&priv->mtx); + return ret; } static int at76_startup_device(struct at76_priv *priv) @@ -3905,14 +1470,14 @@ static int at76_startup_device(struct at76_priv *priv) at76_dbg(DBG_PARAMS, "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d " - "keylen %d", priv->netdev->name, priv->essid_size, priv->essid, - hex2str(priv->essid, IW_ESSID_MAX_SIZE), + "keylen %d", wiphy_name(priv->hw->wiphy), priv->essid_size, + priv->essid, hex2str(priv->essid, IW_ESSID_MAX_SIZE), priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra", priv->channel, priv->wep_enabled ? "enabled" : "disabled", priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]); at76_dbg(DBG_PARAMS, "%s param: preamble %s rts %d retry %d frag %d " - "txrate %s auth_mode %d", priv->netdev->name, + "txrate %s auth_mode %d", wiphy_name(priv->hw->wiphy), preambles[priv->preamble_type], priv->rts_threshold, priv->short_retry_limit, priv->frag_threshold, priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate == @@ -3923,7 +1488,7 @@ static int at76_startup_device(struct at76_priv *priv) at76_dbg(DBG_PARAMS, "%s param: pm_mode %d pm_period %d auth_mode %s " "scan_times %d %d scan_mode %s", - priv->netdev->name, priv->pm_mode, priv->pm_period, + wiphy_name(priv->hw->wiphy), priv->pm_mode, priv->pm_period, priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret", priv->scan_min_time, priv->scan_max_time, priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive"); @@ -3957,7 +1522,8 @@ static int at76_startup_device(struct at76_priv *priv) ccfg->ssid_len = priv->essid_size; ccfg->wep_default_key_id = priv->wep_key_id; - memcpy(ccfg->wep_default_key_value, priv->wep_keys, 4 * WEP_KEY_LEN); + memcpy(ccfg->wep_default_key_value, priv->wep_keys, + sizeof(priv->wep_keys)); ccfg->short_preamble = priv->preamble_type; ccfg->beacon_period = cpu_to_le16(priv->beacon_period); @@ -3966,7 +1532,7 @@ static int at76_startup_device(struct at76_priv *priv) sizeof(struct at76_card_config)); if (ret < 0) { printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -4012,69 +1578,6 @@ static int at76_startup_device(struct at76_priv *priv) return 0; } -/* Restart the interface */ -static void at76_dwork_restart(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - dwork_restart.work); - - mutex_lock(&priv->mtx); - - netif_carrier_off(priv->netdev); /* stop netdev watchdog */ - netif_stop_queue(priv->netdev); /* stop tx data packets */ - - at76_startup_device(priv); - - if (priv->iw_mode != IW_MODE_MONITOR) { - priv->netdev->type = ARPHRD_ETHER; - at76_set_mac_state(priv, MAC_SCANNING); - schedule_work(&priv->work_start_scan); - } else { - priv->netdev->type = ARPHRD_IEEE80211_RADIOTAP; - at76_start_monitor(priv); - } - - mutex_unlock(&priv->mtx); -} - -/* Initiate scanning */ -static void at76_work_start_scan(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - work_start_scan); - int ret; - - mutex_lock(&priv->mtx); - - WARN_ON(priv->mac_state != MAC_SCANNING); - if (priv->mac_state != MAC_SCANNING) - goto exit; - - /* only clear the bss list when a scan is actively initiated, - * otherwise simply rely on at76_bss_list_timeout */ - if (priv->scan_state == SCAN_IN_PROGRESS) { - at76_free_bss_list(priv); - priv->scan_need_any = 1; - } else - priv->scan_need_any = 0; - - ret = at76_start_scan(priv, 1); - - if (ret < 0) - printk(KERN_ERR "%s: %s: start_scan failed with %d\n", - priv->netdev->name, __func__, ret); - else { - at76_dbg(DBG_MGMT_TIMER, - "%s:%d: starting mgmt_timer for %d ticks", - __func__, __LINE__, SCAN_POLL_INTERVAL); - schedule_delayed_work(&priv->dwork_get_scan, - SCAN_POLL_INTERVAL); - } - -exit: - mutex_unlock(&priv->mtx); -} - /* Enable or disable promiscuous mode */ static void at76_work_set_promisc(struct work_struct *work) { @@ -4092,7 +1595,7 @@ static void at76_work_set_promisc(struct work_struct *work) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n", - priv->netdev->name, ret); + wiphy_name(priv->hw->wiphy), ret); mutex_unlock(&priv->mtx); } @@ -4108,1088 +1611,759 @@ static void at76_work_submit_rx(struct work_struct *work) mutex_unlock(&priv->mtx); } -/* We got an association response */ -static void at76_rx_mgmt_assoc(struct at76_priv *priv, - struct at76_rx_buffer *buf) +static void at76_rx_tasklet(unsigned long param) { - struct ieee80211_assoc_response *resp = - (struct ieee80211_assoc_response *)buf->packet; - u16 assoc_id = le16_to_cpu(resp->aid); - u16 status = le16_to_cpu(resp->status); - - at76_dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa 0x%04x status " - "0x%04x assoc_id 0x%04x rates %s", priv->netdev->name, - mac2str(resp->header.addr3), le16_to_cpu(resp->capability), - status, assoc_id, hex2str(resp->info_element->data, - resp->info_element->len)); - - if (priv->mac_state != MAC_ASSOC) { - printk(KERN_INFO "%s: AssocResp in state %s ignored\n", - priv->netdev->name, mac_states[priv->mac_state]); - return; - } - - BUG_ON(!priv->curr_bss); - - cancel_delayed_work(&priv->dwork_assoc); - if (status == WLAN_STATUS_SUCCESS) { - struct bss_info *ptr = priv->curr_bss; - priv->assoc_id = assoc_id & 0x3fff; - /* update iwconfig params */ - memcpy(priv->bssid, ptr->bssid, ETH_ALEN); - memcpy(priv->essid, ptr->ssid, ptr->ssid_len); - priv->essid_size = ptr->ssid_len; - priv->channel = ptr->channel; - schedule_work(&priv->work_assoc_done); - } else { - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - } -} + struct urb *urb = (struct urb *)param; + struct at76_priv *priv = urb->context; + struct at76_rx_buffer *buf; + struct ieee80211_rx_status rx_status = { 0 }; -/* Process disassociation request from the AP */ -static void at76_rx_mgmt_disassoc(struct at76_priv *priv, - struct at76_rx_buffer *buf) -{ - struct ieee80211_disassoc *resp = - (struct ieee80211_disassoc *)buf->packet; - struct ieee80211_hdr_3addr *mgmt = &resp->header; - - at76_dbg(DBG_RX_MGMT, - "%s: rx DisAssoc bssid %s reason 0x%04x destination %s", - priv->netdev->name, mac2str(mgmt->addr3), - le16_to_cpu(resp->reason), mac2str(mgmt->addr1)); - - /* We are not connected, ignore */ - if (priv->mac_state == MAC_SCANNING || priv->mac_state == MAC_INIT - || !priv->curr_bss) + if (priv->device_unplugged) { + at76_dbg(DBG_DEVSTART, "device unplugged"); + if (urb) + at76_dbg(DBG_DEVSTART, "urb status %d", urb->status); return; + } - /* Not our BSSID, ignore */ - if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)) + if (!priv->rx_skb || !priv->rx_skb->data) return; - /* Not for our STA and not broadcast, ignore */ - if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1) - && !is_broadcast_ether_addr(mgmt->addr1)) - return; + buf = (struct at76_rx_buffer *)priv->rx_skb->data; - if (priv->mac_state != MAC_ASSOC && priv->mac_state != MAC_CONNECTED - && priv->mac_state != MAC_JOINING) { - printk(KERN_INFO "%s: DisAssoc in state %s ignored\n", - priv->netdev->name, mac_states[priv->mac_state]); + if (urb->status != 0) { + if (urb->status != -ENOENT && urb->status != -ECONNRESET) + at76_dbg(DBG_URB, + "%s %s: - nonzero Rx bulk status received: %d", + __func__, wiphy_name(priv->hw->wiphy), + urb->status); return; } - if (priv->mac_state == MAC_CONNECTED) { - netif_carrier_off(priv->netdev); - netif_stop_queue(priv->netdev); - at76_iwevent_bss_disconnect(priv->netdev); - } - cancel_delayed_work(&priv->dwork_get_scan); - cancel_delayed_work(&priv->dwork_beacon); - cancel_delayed_work(&priv->dwork_auth); - cancel_delayed_work(&priv->dwork_assoc); - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); + at76_dbg(DBG_RX_ATMEL_HDR, + "%s: rx frame: rate %d rssi %d noise %d link %d", + wiphy_name(priv->hw->wiphy), buf->rx_rate, buf->rssi, + buf->noise_level, buf->link_quality); + + skb_trim(priv->rx_skb, le16_to_cpu(buf->wlength) + AT76_RX_HDRLEN); + at76_dbg_dump(DBG_RX_DATA, &priv->rx_skb->data[AT76_RX_HDRLEN], + priv->rx_skb->len, "RX: len=%d", + (int)(priv->rx_skb->len - AT76_RX_HDRLEN)); + + rx_status.signal = buf->rssi; + /* FIXME: is rate_idx still present in structure? */ + rx_status.rate_idx = buf->rx_rate; + rx_status.flag |= RX_FLAG_DECRYPTED; + rx_status.flag |= RX_FLAG_IV_STRIPPED; + + skb_pull(priv->rx_skb, AT76_RX_HDRLEN); + at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d", + priv->rx_skb->len, priv->rx_skb->data_len); + ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status); + + /* Use a new skb for the next receive */ + priv->rx_skb = NULL; + + at76_submit_rx_urb(priv); } -static void at76_rx_mgmt_auth(struct at76_priv *priv, - struct at76_rx_buffer *buf) +/* Load firmware into kernel memory and parse it */ +static struct fwentry *at76_load_firmware(struct usb_device *udev, + enum board_type board_type) { - struct ieee80211_auth *resp = (struct ieee80211_auth *)buf->packet; - struct ieee80211_hdr_3addr *mgmt = &resp->header; - int seq_nr = le16_to_cpu(resp->transaction); - int alg = le16_to_cpu(resp->algorithm); - int status = le16_to_cpu(resp->status); - - at76_dbg(DBG_RX_MGMT, - "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d " - "destination %s", priv->netdev->name, mac2str(mgmt->addr3), - alg, seq_nr, status, mac2str(mgmt->addr1)); - - if (alg == WLAN_AUTH_SHARED_KEY && seq_nr == 2) - at76_dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...", - priv->netdev->name, hex2str(resp->info_element, 18)); - - if (priv->mac_state != MAC_AUTH) { - printk(KERN_INFO "%s: ignored AuthFrame in state %s\n", - priv->netdev->name, mac_states[priv->mac_state]); - return; - } - if (priv->auth_mode != alg) { - printk(KERN_INFO "%s: ignored AuthFrame for alg %d\n", - priv->netdev->name, alg); - return; + int ret; + char *str; + struct at76_fw_header *fwh; + struct fwentry *fwe = &firmwares[board_type]; + + mutex_lock(&fw_mutex); + + if (fwe->loaded) { + at76_dbg(DBG_FW, "re-using previously loaded fw"); + goto exit; } - BUG_ON(!priv->curr_bss); + at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); + ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); + if (ret < 0) { + dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n", + fwe->fwname); + dev_printk(KERN_ERR, &udev->dev, + "you may need to download the firmware from " + "http://developer.berlios.de/projects/at76c503a/\n"); + goto exit; + } - /* Not our BSSID or not for our STA, ignore */ - if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid) - || compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)) - return; + at76_dbg(DBG_FW, "got it."); + fwh = (struct at76_fw_header *)(fwe->fw->data); - cancel_delayed_work(&priv->dwork_auth); - if (status != WLAN_STATUS_SUCCESS) { - /* try to join next bss */ - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - return; + if (fwe->fw->size <= sizeof(*fwh)) { + dev_printk(KERN_ERR, &udev->dev, + "firmware is too short (0x%zx)\n", fwe->fw->size); + goto exit; } - if (priv->auth_mode == WLAN_AUTH_OPEN || seq_nr == 4) { - priv->retries = ASSOC_RETRIES; - at76_set_mac_state(priv, MAC_ASSOC); - at76_assoc_req(priv, priv->curr_bss); - at76_dbg(DBG_MGMT_TIMER, - "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__); - schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT); - return; + /* CRC currently not checked */ + fwe->board_type = le32_to_cpu(fwh->board_type); + if (fwe->board_type != board_type) { + dev_printk(KERN_ERR, &udev->dev, + "board type mismatch, requested %u, got %u\n", + board_type, fwe->board_type); + goto exit; } - WARN_ON(seq_nr != 2); - at76_auth_req(priv, priv->curr_bss, seq_nr + 1, resp->info_element); - at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __func__, - __LINE__); - schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT); -} + fwe->fw_version.major = fwh->major; + fwe->fw_version.minor = fwh->minor; + fwe->fw_version.patch = fwh->patch; + fwe->fw_version.build = fwh->build; -static void at76_rx_mgmt_deauth(struct at76_priv *priv, - struct at76_rx_buffer *buf) -{ - struct ieee80211_disassoc *resp = - (struct ieee80211_disassoc *)buf->packet; - struct ieee80211_hdr_3addr *mgmt = &resp->header; - - at76_dbg(DBG_RX_MGMT | DBG_PROGRESS, - "%s: rx DeAuth bssid %s reason 0x%04x destination %s", - priv->netdev->name, mac2str(mgmt->addr3), - le16_to_cpu(resp->reason), mac2str(mgmt->addr1)); - - if (priv->mac_state != MAC_AUTH && priv->mac_state != MAC_ASSOC - && priv->mac_state != MAC_CONNECTED) { - printk(KERN_INFO "%s: DeAuth in state %s ignored\n", - priv->netdev->name, mac_states[priv->mac_state]); - return; - } + str = (char *)fwh + le32_to_cpu(fwh->str_offset); + fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset); + fwe->intfw_size = le32_to_cpu(fwh->int_fw_len); + fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset); + fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len); - BUG_ON(!priv->curr_bss); + fwe->loaded = 1; - /* Not our BSSID, ignore */ - if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)) - return; + dev_printk(KERN_DEBUG, &udev->dev, + "using firmware %s (version %d.%d.%d-%d)\n", + fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build); - /* Not for our STA and not broadcast, ignore */ - if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1) - && !is_broadcast_ether_addr(mgmt->addr1)) - return; + at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type, + le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len), + le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len)); + at76_dbg(DBG_DEVSTART, "firmware id %s", str); - if (priv->mac_state == MAC_CONNECTED) - at76_iwevent_bss_disconnect(priv->netdev); +exit: + mutex_unlock(&fw_mutex); - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - cancel_delayed_work(&priv->dwork_get_scan); - cancel_delayed_work(&priv->dwork_beacon); - cancel_delayed_work(&priv->dwork_auth); - cancel_delayed_work(&priv->dwork_assoc); + if (fwe->loaded) + return fwe; + else + return NULL; } -static void at76_rx_mgmt_beacon(struct at76_priv *priv, - struct at76_rx_buffer *buf) +static void at76_mac80211_tx_callback(struct urb *urb) { - int varpar_len; - /* beacon content */ - struct ieee80211_beacon *bdata = (struct ieee80211_beacon *)buf->packet; - struct ieee80211_hdr_3addr *mgmt = &bdata->header; - - struct list_head *lptr; - struct bss_info *match; /* entry matching addr3 with its bssid */ - int new_entry = 0; - int len; - struct ieee80211_info_element *ie; - int have_ssid = 0; - int have_rates = 0; - int have_channel = 0; - int keep_going = 1; - unsigned long flags; - - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - if (priv->mac_state == MAC_CONNECTED) { - /* in state MAC_CONNECTED we use the mgmt_timer to control - the beacon of the BSS */ - BUG_ON(!priv->curr_bss); - - if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) { - /* We got our AP's beacon, defer the timeout handler. - Kill pending work first, as schedule_delayed_work() - won't do it. */ - cancel_delayed_work(&priv->dwork_beacon); - schedule_delayed_work(&priv->dwork_beacon, - BEACON_TIMEOUT); - priv->curr_bss->rssi = buf->rssi; - priv->beacons_received++; - goto exit; - } - } + struct at76_priv *priv = urb->context; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb); - /* look if we have this BSS already in the list */ - match = NULL; + at76_dbg(DBG_MAC80211, "%s()", __func__); - if (!list_empty(&priv->bss_list)) { - list_for_each(lptr, &priv->bss_list) { - struct bss_info *bss_ptr = - list_entry(lptr, struct bss_info, list); - if (!compare_ether_addr(bss_ptr->bssid, mgmt->addr3)) { - match = bss_ptr; - break; - } - } + switch (urb->status) { + case 0: + /* success */ + /* FIXME: + * is the frame really ACKed when tx_callback is called ? */ + info->flags |= IEEE80211_TX_STAT_ACK; + break; + case -ENOENT: + case -ECONNRESET: + /* fail, urb has been unlinked */ + /* FIXME: add error message */ + break; + default: + at76_dbg(DBG_URB, "%s - nonzero tx status received: %d", + __func__, urb->status); + break; } - if (!match) { - /* BSS not in the list - append it */ - match = kzalloc(sizeof(struct bss_info), GFP_ATOMIC); - if (!match) { - at76_dbg(DBG_BSS_TABLE, - "%s: cannot kmalloc new bss info (%zd byte)", - priv->netdev->name, sizeof(struct bss_info)); - goto exit; - } - new_entry = 1; - list_add_tail(&match->list, &priv->bss_list); - } + memset(&info->status, 0, sizeof(info->status)); - match->capa = le16_to_cpu(bdata->capability); - match->beacon_interval = le16_to_cpu(bdata->beacon_interval); - match->rssi = buf->rssi; - match->link_qual = buf->link_quality; - match->noise_level = buf->noise_level; - memcpy(match->bssid, mgmt->addr3, ETH_ALEN); - at76_dbg(DBG_RX_BEACON, "%s: bssid %s", priv->netdev->name, - mac2str(match->bssid)); - - ie = bdata->info_element; - - /* length of var length beacon parameters */ - varpar_len = min_t(int, le16_to_cpu(buf->wlength) - - sizeof(struct ieee80211_beacon), - BEACON_MAX_DATA_LENGTH); - - /* This routine steps through the bdata->data array to get - * some useful information about the access point. - * Currently, this implementation supports receipt of: SSID, - * supported transfer rates and channel, in any order, with some - * tolerance for intermittent unknown codes (although this - * functionality may not be necessary as the useful information will - * usually arrive in consecutively, but there have been some - * reports of some of the useful information fields arriving in a - * different order). - * It does not support any more IE types although MFIE_TYPE_TIM may - * be supported (on my AP at least). - * The bdata->data array is about 1500 bytes long but only ~36 of those - * bytes are useful, hence the have_ssid etc optimizations. */ - - while (keep_going && - ((&ie->data[ie->len] - (u8 *)bdata->info_element) <= - varpar_len)) { - - switch (ie->id) { - - case MFIE_TYPE_SSID: - if (have_ssid) - break; + ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb); - len = min_t(int, IW_ESSID_MAX_SIZE, ie->len); + priv->tx_skb = NULL; - /* we copy only if this is a new entry, - or the incoming SSID is not a hidden SSID. This - will protect us from overwriting a real SSID read - in a ProbeResponse with a hidden one from a - following beacon. */ - if (!new_entry && at76_is_hidden_ssid(ie->data, len)) { - have_ssid = 1; - break; - } + ieee80211_wake_queues(priv->hw); +} - match->ssid_len = len; - memcpy(match->ssid, ie->data, len); - at76_dbg(DBG_RX_BEACON, "%s: SSID - %.*s", - priv->netdev->name, len, match->ssid); - have_ssid = 1; - break; +static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct at76_priv *priv = hw->priv; + struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + int padding, submit_len, ret; - case MFIE_TYPE_RATES: - if (have_rates) - break; + at76_dbg(DBG_MAC80211, "%s()", __func__); - match->rates_len = - min_t(int, sizeof(match->rates), ie->len); - memcpy(match->rates, ie->data, match->rates_len); - have_rates = 1; - at76_dbg(DBG_RX_BEACON, "%s: SUPPORTED RATES %s", - priv->netdev->name, - hex2str(ie->data, ie->len)); - break; + if (priv->tx_urb->status == -EINPROGRESS) { + printk(KERN_ERR "%s: %s called while tx urb is pending\n", + wiphy_name(priv->hw->wiphy), __func__); + return NETDEV_TX_BUSY; + } - case MFIE_TYPE_DS_SET: - if (have_channel) - break; + ieee80211_stop_queues(hw); - match->channel = ie->data[0]; - have_channel = 1; - at76_dbg(DBG_RX_BEACON, "%s: CHANNEL - %d", - priv->netdev->name, match->channel); - break; + at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */ - case MFIE_TYPE_CF_SET: - case MFIE_TYPE_TIM: - case MFIE_TYPE_IBSS_SET: - default: - at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s", - priv->netdev->name, ie->id, ie->len, - hex2str(ie->data, ie->len)); - break; - } + WARN_ON(priv->tx_skb != NULL); - /* advance to the next informational element */ - next_ie(&ie); + priv->tx_skb = skb; + padding = at76_calc_padding(skb->len); + submit_len = AT76_TX_HDRLEN + skb->len + padding; - /* Optimization: after all, the bdata->data array is - * varpar_len bytes long, whereas we get all of the useful - * information after only ~36 bytes, this saves us a lot of - * time (and trouble as the remaining portion of the array - * could be full of junk) - * Comment this out if you want to see what other information - * comes from the AP - although little of it may be useful */ - } + /* setup 'Atmel' header */ + memset(tx_buffer, 0, sizeof(*tx_buffer)); + tx_buffer->padding = padding; + tx_buffer->wlength = cpu_to_le16(skb->len); + tx_buffer->tx_rate = ieee80211_get_tx_rate(hw, info)->hw_value; + if (FIRMWARE_IS_WPA(priv->fw_version) && info->control.hw_key) { + tx_buffer->key_id = (info->control.hw_key->keyidx); + tx_buffer->cipher_type = + priv->keys[info->control.hw_key->keyidx].cipher; + tx_buffer->cipher_length = + priv->keys[info->control.hw_key->keyidx].keylen; + tx_buffer->reserved = 0; + } else { + tx_buffer->key_id = 0; + tx_buffer->cipher_type = 0; + tx_buffer->cipher_length = 0; + tx_buffer->reserved = 0; + }; + /* memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved)); */ + memcpy(tx_buffer->packet, skb->data, skb->len); - at76_dbg(DBG_RX_BEACON, "%s: Finished processing beacon data", - priv->netdev->name); + at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr", + wiphy_name(priv->hw->wiphy), le16_to_cpu(tx_buffer->wlength), + tx_buffer->padding, tx_buffer->tx_rate); - match->last_rx = jiffies; /* record last rx of beacon */ + /* send stuff */ + at76_dbg_dump(DBG_TX_DATA_CONTENT, tx_buffer, submit_len, + "%s(): tx_buffer %d bytes:", __func__, submit_len); + usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer, + submit_len, at76_mac80211_tx_callback, priv); + ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); + if (ret) { + printk(KERN_ERR "%s: error in tx submit urb: %d\n", + wiphy_name(priv->hw->wiphy), ret); + if (ret == -EINVAL) + printk(KERN_ERR + "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n", + wiphy_name(priv->hw->wiphy), priv->tx_urb, + priv->tx_urb->hcpriv, priv->tx_urb->complete); + } -exit: - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); + return 0; } -/* Calculate the link level from a given rx_buffer */ -static void at76_calc_level(struct at76_priv *priv, struct at76_rx_buffer *buf, - struct iw_quality *qual) +static int at76_mac80211_start(struct ieee80211_hw *hw) { - /* just a guess for now, might be different for other chips */ - int max_rssi = 42; + struct at76_priv *priv = hw->priv; + int ret; - qual->level = (buf->rssi * 100 / max_rssi); - if (qual->level > 100) - qual->level = 100; - qual->updated |= IW_QUAL_LEVEL_UPDATED; -} + at76_dbg(DBG_MAC80211, "%s()", __func__); -/* Calculate the link quality from a given rx_buffer */ -static void at76_calc_qual(struct at76_priv *priv, struct at76_rx_buffer *buf, - struct iw_quality *qual) -{ - if (at76_is_intersil(priv->board_type)) - qual->qual = buf->link_quality; - else { - unsigned long elapsed; + mutex_lock(&priv->mtx); + + ret = at76_submit_rx_urb(priv); + if (ret < 0) { + printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); + goto error; + } - /* Update qual at most once a second */ - elapsed = jiffies - priv->beacons_last_qual; - if (elapsed < 1 * HZ) - return; + at76_startup_device(priv); - qual->qual = qual->level * priv->beacons_received * - msecs_to_jiffies(priv->beacon_period) / elapsed; + at76_start_monitor(priv); - priv->beacons_last_qual = jiffies; - priv->beacons_received = 0; - } - qual->qual = (qual->qual > 100) ? 100 : qual->qual; - qual->updated |= IW_QUAL_QUAL_UPDATED; -} +error: + mutex_unlock(&priv->mtx); -/* Calculate the noise quality from a given rx_buffer */ -static void at76_calc_noise(struct at76_priv *priv, struct at76_rx_buffer *buf, - struct iw_quality *qual) -{ - qual->noise = 0; - qual->updated |= IW_QUAL_NOISE_INVALID; + return 0; } -static void at76_update_wstats(struct at76_priv *priv, - struct at76_rx_buffer *buf) +static void at76_mac80211_stop(struct ieee80211_hw *hw) { - struct iw_quality *qual = &priv->wstats.qual; + struct at76_priv *priv = hw->priv; - if (buf->rssi && priv->mac_state == MAC_CONNECTED) { - qual->updated = 0; - at76_calc_level(priv, buf, qual); - at76_calc_qual(priv, buf, qual); - at76_calc_noise(priv, buf, qual); - } else { - qual->qual = 0; - qual->level = 0; - qual->noise = 0; - qual->updated = IW_QUAL_ALL_INVALID; - } -} + at76_dbg(DBG_MAC80211, "%s()", __func__); -static void at76_rx_mgmt(struct at76_priv *priv, struct at76_rx_buffer *buf) -{ - struct ieee80211_hdr_3addr *mgmt = - (struct ieee80211_hdr_3addr *)buf->packet; - u16 framectl = le16_to_cpu(mgmt->frame_ctl); - - /* update wstats */ - if (priv->mac_state != MAC_INIT && priv->mac_state != MAC_SCANNING) { - /* jal: this is a dirty hack needed by Tim in ad-hoc mode */ - /* Data packets always seem to have a 0 link level, so we - only read link quality info from management packets. - Atmel driver actually averages the present, and previous - values, we just present the raw value at the moment - TJS */ - if (priv->iw_mode == IW_MODE_ADHOC - || (priv->curr_bss - && !compare_ether_addr(mgmt->addr3, - priv->curr_bss->bssid))) - at76_update_wstats(priv, buf); - } + mutex_lock(&priv->mtx); + + if (!priv->device_unplugged) { + /* We are called by "ifconfig ethX down", not because the + * device is not available anymore. */ + if (at76_set_radio(priv, 0) == 1) + at76_wait_completion(priv, CMD_RADIO_ON); - at76_dbg(DBG_RX_MGMT_CONTENT, "%s rx mgmt framectl 0x%x %s", - priv->netdev->name, framectl, - hex2str(mgmt, le16_to_cpu(buf->wlength))); + /* We unlink rx_urb because at76_open() re-submits it. + * If unplugged, at76_delete_device() takes care of it. */ + usb_kill_urb(priv->rx_urb); + } - switch (framectl & IEEE80211_FCTL_STYPE) { - case IEEE80211_STYPE_BEACON: - case IEEE80211_STYPE_PROBE_RESP: - at76_rx_mgmt_beacon(priv, buf); - break; + mutex_unlock(&priv->mtx); +} - case IEEE80211_STYPE_ASSOC_RESP: - at76_rx_mgmt_assoc(priv, buf); - break; +static int at76_add_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) +{ + struct at76_priv *priv = hw->priv; + int ret = 0; - case IEEE80211_STYPE_DISASSOC: - at76_rx_mgmt_disassoc(priv, buf); - break; + at76_dbg(DBG_MAC80211, "%s()", __func__); - case IEEE80211_STYPE_AUTH: - at76_rx_mgmt_auth(priv, buf); - break; + mutex_lock(&priv->mtx); - case IEEE80211_STYPE_DEAUTH: - at76_rx_mgmt_deauth(priv, buf); + switch (conf->type) { + case NL80211_IFTYPE_STATION: + priv->iw_mode = IW_MODE_INFRA; break; - default: - printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n", - priv->netdev->name, framectl); + ret = -EOPNOTSUPP; + goto exit; } - return; +exit: + mutex_unlock(&priv->mtx); + + return ret; } -/* Convert the 802.11 header into an ethernet-style header, make skb - * ready for consumption by netif_rx() */ -static void at76_ieee80211_to_eth(struct sk_buff *skb, int iw_mode) +static void at76_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) { - struct ieee80211_hdr_3addr *i802_11_hdr; - struct ethhdr *eth_hdr_p; - u8 *src_addr; - u8 *dest_addr; + at76_dbg(DBG_MAC80211, "%s()", __func__); +} - i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data; +static int at76_join(struct at76_priv *priv) +{ + struct at76_req_join join; + int ret; - /* That would be the ethernet header if the hardware converted - * the frame for us. Make sure the source and the destination - * match the 802.11 header. Which hardware does it? */ - eth_hdr_p = (struct ethhdr *)skb_pull(skb, IEEE80211_3ADDR_LEN); + memset(&join, 0, sizeof(struct at76_req_join)); + memcpy(join.essid, priv->essid, priv->essid_size); + join.essid_size = priv->essid_size; + memcpy(join.bssid, priv->bssid, ETH_ALEN); + join.bss_type = INFRASTRUCTURE_MODE; + join.channel = priv->channel; + join.timeout = cpu_to_le16(2000); - dest_addr = i802_11_hdr->addr1; - if (iw_mode == IW_MODE_ADHOC) - src_addr = i802_11_hdr->addr2; - else - src_addr = i802_11_hdr->addr3; + at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__); + ret = at76_set_card_command(priv->udev, CMD_JOIN, &join, + sizeof(struct at76_req_join)); - if (!compare_ether_addr(eth_hdr_p->h_source, src_addr) && - !compare_ether_addr(eth_hdr_p->h_dest, dest_addr)) - /* Yes, we already have an ethernet header */ - skb_reset_mac_header(skb); - else { - u16 len; - - /* Need to build an ethernet header */ - if (!memcmp(skb->data, snapsig, sizeof(snapsig))) { - /* SNAP frame - decapsulate, keep proto */ - skb_push(skb, offsetof(struct ethhdr, h_proto) - - sizeof(rfc1042sig)); - len = 0; - } else { - /* 802.3 frame, proto is length */ - len = skb->len; - skb_push(skb, ETH_HLEN); - } + if (ret < 0) { + printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); + return 0; + } - skb_reset_mac_header(skb); - eth_hdr_p = eth_hdr(skb); - /* This needs to be done in this order (eth_hdr_p->h_dest may - * overlap src_addr) */ - memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN); - memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN); - if (len) - eth_hdr_p->h_proto = htons(len); + ret = at76_wait_completion(priv, CMD_JOIN); + at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret); + if (ret != CMD_STATUS_COMPLETE) { + printk(KERN_ERR "%s: at76_wait_completion failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); + return 0; } - skb->protocol = eth_type_trans(skb, skb->dev); + at76_set_tkip_bssid(priv, priv->bssid); + at76_set_pm_mode(priv); + + return 0; } -/* Check for fragmented data in priv->rx_skb. If the packet was no fragment - or it was the last of a fragment set a skb containing the whole packet - is returned for further processing. Otherwise we get NULL and are - done and the packet is either stored inside the fragment buffer - or thrown away. Every returned skb starts with the ieee802_11 header - and contains _no_ FCS at the end */ -static struct sk_buff *at76_check_for_rx_frags(struct at76_priv *priv) +static void at76_dwork_hw_scan(struct work_struct *work) { - struct sk_buff *skb = priv->rx_skb; - struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data; - struct ieee80211_hdr_3addr *i802_11_hdr = - (struct ieee80211_hdr_3addr *)buf->packet; - /* seq_ctrl, fragment_number, sequence number of new packet */ - u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl); - u16 fragnr = sctl & 0xf; - u16 seqnr = sctl >> 4; - u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl); - - /* Length including the IEEE802.11 header, but without the trailing - * FCS and without the Atmel Rx header */ - int length = le16_to_cpu(buf->wlength) - IEEE80211_FCS_LEN; + struct at76_priv *priv = container_of(work, struct at76_priv, + dwork_hw_scan.work); + int ret; - /* where does the data payload start in skb->data ? */ - u8 *data = i802_11_hdr->payload; + ret = at76_get_cmd_status(priv->udev, CMD_SCAN); + at76_dbg(DBG_MAC80211, "%s: CMD_SCAN status 0x%02x", __func__, ret); - /* length of payload, excl. the trailing FCS */ - int data_len = length - IEEE80211_3ADDR_LEN; + /* FIXME: add maximum time for scan to complete */ - int i; - struct rx_data_buf *bptr, *optr; - unsigned long oldest = ~0UL; - - at76_dbg(DBG_RX_FRAGS, - "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d " - "length %d data %d: %s ...", priv->netdev->name, frame_ctl, - mac2str(i802_11_hdr->addr2), seqnr, fragnr, length, data_len, - hex2str(data, 32)); - - at76_dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p " - "tail %p end %p len %d", priv->netdev->name, skb->head, - skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), - skb->len); - - if (data_len < 0) { - /* make sure data starts in the buffer */ - printk(KERN_INFO "%s: data frame too short\n", - priv->netdev->name); - return NULL; + if (ret != CMD_STATUS_COMPLETE) { + queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, + SCAN_POLL_INTERVAL); + goto exit; } - WARN_ON(length <= AT76_RX_HDRLEN); - if (length <= AT76_RX_HDRLEN) - return NULL; + ieee80211_scan_completed(priv->hw); - /* remove the at76_rx_buffer header - we don't need it anymore */ - /* we need the IEEE802.11 header (for the addresses) if this packet - is the first of a chain */ - skb_pull(skb, AT76_RX_HDRLEN); - - /* remove FCS at end */ - skb_trim(skb, length); - - at76_dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p " - "end %p len %d data %p data_len %d", priv->netdev->name, - skb->head, skb->data, skb_tail_pointer(skb), - skb_end_pointer(skb), skb->len, data, data_len); - - if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { - /* unfragmented packet received */ - /* Use a new skb for the next receive */ - priv->rx_skb = NULL; - at76_dbg(DBG_RX_FRAGS, "%s: unfragmented", priv->netdev->name); - return skb; + if (is_valid_ether_addr(priv->bssid)) { + ieee80211_wake_queues(priv->hw); + at76_join(priv); } - /* look if we've got a chain for the sender address. - afterwards optr points to first free or the oldest entry, - or, if i < NR_RX_DATA_BUF, bptr points to the entry for the - sender address */ - /* determining the oldest entry doesn't cope with jiffies wrapping - but I don't care to delete a young entry at these rare moments ... */ - - bptr = priv->rx_data; - optr = NULL; - for (i = 0; i < NR_RX_DATA_BUF; i++, bptr++) { - if (!bptr->skb) { - optr = bptr; - oldest = 0UL; - continue; - } + ieee80211_wake_queues(priv->hw); - if (!compare_ether_addr(i802_11_hdr->addr2, bptr->sender)) - break; +exit: + return; +} - if (!optr) { - optr = bptr; - oldest = bptr->last_rx; - } else if (bptr->last_rx < oldest) - optr = bptr; - } +static int at76_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) +{ + struct at76_priv *priv = hw->priv; + struct at76_req_scan scan; + int ret; - if (i < NR_RX_DATA_BUF) { - - at76_dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag = %d/%d) " - "matched sender addr", - priv->netdev->name, i, bptr->seqnr, bptr->fragnr); - - /* bptr points to an entry for the sender address */ - if (bptr->seqnr == seqnr) { - int left; - /* the fragment has the current sequence number */ - if (((bptr->fragnr + 1) & 0xf) != fragnr) { - /* wrong fragment number -> ignore it */ - /* is & 0xf necessary above ??? */ - at76_dbg(DBG_RX_FRAGS, - "%s: frag nr mismatch: %d + 1 != %d", - priv->netdev->name, bptr->fragnr, - fragnr); - return NULL; - } - bptr->last_rx = jiffies; - /* the next following fragment number -> - add the data at the end */ - - /* for test only ??? */ - left = skb_tailroom(bptr->skb); - if (left < data_len) - printk(KERN_INFO - "%s: only %d byte free (need %d)\n", - priv->netdev->name, left, data_len); - else - memcpy(skb_put(bptr->skb, data_len), data, - data_len); - - bptr->fragnr = fragnr; - if (frame_ctl & IEEE80211_FCTL_MOREFRAGS) - return NULL; - - /* this was the last fragment - send it */ - skb = bptr->skb; - bptr->skb = NULL; /* free the entry */ - at76_dbg(DBG_RX_FRAGS, "%s: last frag of seq %d", - priv->netdev->name, seqnr); - return skb; - } + at76_dbg(DBG_MAC80211, "%s():", __func__); + at76_dbg_dump(DBG_MAC80211, ssid, len, "ssid %zd bytes:", len); - /* got another sequence number */ - if (fragnr == 0) { - /* it's the start of a new chain - replace the - old one by this */ - /* bptr->sender has the correct value already */ - at76_dbg(DBG_RX_FRAGS, - "%s: start of new seq %d, removing old seq %d", - priv->netdev->name, seqnr, bptr->seqnr); - bptr->seqnr = seqnr; - bptr->fragnr = 0; - bptr->last_rx = jiffies; - /* swap bptr->skb and priv->rx_skb */ - skb = bptr->skb; - bptr->skb = priv->rx_skb; - priv->rx_skb = skb; - } else { - /* it from the middle of a new chain -> - delete the old entry and skip the new one */ - at76_dbg(DBG_RX_FRAGS, - "%s: middle of new seq %d (%d) " - "removing old seq %d", - priv->netdev->name, seqnr, fragnr, - bptr->seqnr); - dev_kfree_skb(bptr->skb); - bptr->skb = NULL; - } - return NULL; - } + mutex_lock(&priv->mtx); - /* if we didn't find a chain for the sender address, optr - points either to the first free or the oldest entry */ + ieee80211_stop_queues(hw); - if (fragnr != 0) { - /* this is not the begin of a fragment chain ... */ - at76_dbg(DBG_RX_FRAGS, - "%s: no chain for non-first fragment (%d)", - priv->netdev->name, fragnr); - return NULL; + memset(&scan, 0, sizeof(struct at76_req_scan)); + memset(scan.bssid, 0xFF, ETH_ALEN); + scan.scan_type = SCAN_TYPE_ACTIVE; + if (priv->essid_size > 0) { + memcpy(scan.essid, ssid, len); + scan.essid_size = len; } + scan.min_channel_time = cpu_to_le16(priv->scan_min_time); + scan.max_channel_time = cpu_to_le16(priv->scan_max_time); + scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000); + scan.international_scan = 0; - BUG_ON(!optr); - if (optr->skb) { - /* swap the skb's */ - skb = optr->skb; - optr->skb = priv->rx_skb; - priv->rx_skb = skb; + at76_dbg(DBG_MAC80211, "%s: sending CMD_SCAN", __func__); + ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan)); - at76_dbg(DBG_RX_FRAGS, - "%s: free old contents: sender %s seq/frag %d/%d", - priv->netdev->name, mac2str(optr->sender), - optr->seqnr, optr->fragnr); + if (ret < 0) { + err("CMD_SCAN failed: %d", ret); + goto exit; + } - } else { - /* take the skb from priv->rx_skb */ - optr->skb = priv->rx_skb; - /* let at76_submit_rx_urb() allocate a new skb */ - priv->rx_skb = NULL; + queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, + SCAN_POLL_INTERVAL); - at76_dbg(DBG_RX_FRAGS, "%s: use a free entry", - priv->netdev->name); - } - memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN); - optr->seqnr = seqnr; - optr->fragnr = 0; - optr->last_rx = jiffies; +exit: + mutex_unlock(&priv->mtx); - return NULL; + return 0; } -/* Rx interrupt: we expect the complete data buffer in priv->rx_skb */ -static void at76_rx_data(struct at76_priv *priv) +static int at76_config(struct ieee80211_hw *hw, u32 changed) { - struct net_device *netdev = priv->netdev; - struct net_device_stats *stats = &priv->stats; - struct sk_buff *skb = priv->rx_skb; - struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data; - struct ieee80211_hdr_3addr *i802_11_hdr; - int length = le16_to_cpu(buf->wlength); - - at76_dbg(DBG_RX_DATA, "%s received data packet: %s", netdev->name, - hex2str(skb->data, AT76_RX_HDRLEN)); - - at76_dbg(DBG_RX_DATA_CONTENT, "rx packet: %s", - hex2str(skb->data + AT76_RX_HDRLEN, length)); - - skb = at76_check_for_rx_frags(priv); - if (!skb) - return; + struct at76_priv *priv = hw->priv; + struct ieee80211_conf *conf = &hw->conf; - /* Atmel header and the FCS are already removed */ - i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data; + at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d", + __func__, conf->channel->hw_value, conf->radio_enabled); + at76_dbg_dump(DBG_MAC80211, priv->essid, priv->essid_size, "ssid:"); + at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:"); - skb->dev = netdev; - skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */ + mutex_lock(&priv->mtx); - if (is_broadcast_ether_addr(i802_11_hdr->addr1)) { - if (!compare_ether_addr(i802_11_hdr->addr1, netdev->broadcast)) - skb->pkt_type = PACKET_BROADCAST; - else - skb->pkt_type = PACKET_MULTICAST; - } else if (compare_ether_addr(i802_11_hdr->addr1, netdev->dev_addr)) - skb->pkt_type = PACKET_OTHERHOST; + priv->channel = conf->channel->hw_value; - at76_ieee80211_to_eth(skb, priv->iw_mode); + if (is_valid_ether_addr(priv->bssid)) { + at76_join(priv); + ieee80211_wake_queues(priv->hw); + } else { + ieee80211_stop_queues(priv->hw); + at76_start_monitor(priv); + }; - netdev->last_rx = jiffies; - netif_rx(skb); - stats->rx_packets++; - stats->rx_bytes += length; + mutex_unlock(&priv->mtx); - return; + return 0; } -static void at76_rx_monitor_mode(struct at76_priv *priv) +static int at76_config_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_if_conf *conf) { - struct at76_rx_radiotap *rt; - u8 *payload; - int skblen; - struct net_device *netdev = priv->netdev; - struct at76_rx_buffer *buf = - (struct at76_rx_buffer *)priv->rx_skb->data; - /* length including the IEEE802.11 header and the trailing FCS, - but not at76_rx_buffer */ - int length = le16_to_cpu(buf->wlength); - struct sk_buff *skb = priv->rx_skb; - struct net_device_stats *stats = &priv->stats; + struct at76_priv *priv = hw->priv; - if (length < IEEE80211_FCS_LEN) { - /* buffer contains no data */ - at76_dbg(DBG_MONITOR_MODE, - "%s: MONITOR MODE: rx skb without data", - priv->netdev->name); - return; - } + at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:"); - skblen = sizeof(struct at76_rx_radiotap) + length; + mutex_lock(&priv->mtx); - skb = dev_alloc_skb(skblen); - if (!skb) { - printk(KERN_ERR "%s: MONITOR MODE: dev_alloc_skb for radiotap " - "header returned NULL\n", priv->netdev->name); - return; - } + memcpy(priv->bssid, conf->bssid, ETH_ALEN); +// memcpy(priv->essid, conf->ssid, conf->ssid_len); +// priv->essid_size = conf->ssid_len; + + if (is_valid_ether_addr(priv->bssid)) { + /* mac80211 is joining a bss */ + ieee80211_wake_queues(priv->hw); + at76_join(priv); + } else + ieee80211_stop_queues(priv->hw); + + mutex_unlock(&priv->mtx); - skb_put(skb, skblen); - - rt = (struct at76_rx_radiotap *)skb->data; - payload = skb->data + sizeof(struct at76_rx_radiotap); - - rt->rt_hdr.it_version = 0; - rt->rt_hdr.it_pad = 0; - rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct at76_rx_radiotap)); - rt->rt_hdr.it_present = cpu_to_le32(AT76_RX_RADIOTAP_PRESENT); - - rt->rt_tsft = cpu_to_le64(le32_to_cpu(buf->rx_time)); - rt->rt_rate = hw_rates[buf->rx_rate] & (~0x80); - rt->rt_signal = buf->rssi; - rt->rt_noise = buf->noise_level; - rt->rt_flags = IEEE80211_RADIOTAP_F_FCS; - if (buf->fragmentation) - rt->rt_flags |= IEEE80211_RADIOTAP_F_FRAG; - - memcpy(payload, buf->packet, length); - skb->dev = netdev; - skb->ip_summed = CHECKSUM_NONE; - skb_reset_mac_header(skb); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_802_2); - - netdev->last_rx = jiffies; - netif_rx(skb); - stats->rx_packets++; - stats->rx_bytes += length; + return 0; } -/* Check if we spy on the sender address in buf and update stats */ -static void at76_iwspy_update(struct at76_priv *priv, - struct at76_rx_buffer *buf) +/* must be atomic */ +static void at76_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, int mc_count, + struct dev_addr_list *mc_list) { - struct ieee80211_hdr_3addr *hdr = - (struct ieee80211_hdr_3addr *)buf->packet; - struct iw_quality qual; + struct at76_priv *priv = hw->priv; + int flags; + + at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x " + "total_flags=0x%08x mc_count=%d", + __func__, changed_flags, *total_flags, mc_count); - /* We can only set the level here */ - qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID; - qual.level = 0; - qual.noise = 0; - at76_calc_level(priv, buf, &qual); + flags = changed_flags & AT76_SUPPORTED_FILTERS; + *total_flags = AT76_SUPPORTED_FILTERS; - spin_lock_bh(&priv->spy_spinlock); + /* FIXME: access to priv->promisc should be protected with + * priv->mtx, but it's impossible because this function needs to be + * atomic */ - if (priv->spy_data.spy_number > 0) - wireless_spy_update(priv->netdev, hdr->addr2, &qual); + if (flags && !priv->promisc) { + /* mac80211 wants us to enable promiscuous mode */ + priv->promisc = 1; + } else if (!flags && priv->promisc) { + /* we need to disable promiscuous mode */ + priv->promisc = 0; + } else + return; - spin_unlock_bh(&priv->spy_spinlock); + queue_work(hw->workqueue, &priv->work_set_promisc); } -static void at76_rx_tasklet(unsigned long param) +static int at76_set_key_oldfw(struct ieee80211_hw *hw, enum set_key_cmd cmd, + const u8 *local_address, const u8 *address, + struct ieee80211_key_conf *key) { - struct urb *urb = (struct urb *)param; - struct at76_priv *priv = urb->context; - struct net_device *netdev = priv->netdev; - struct at76_rx_buffer *buf; - struct ieee80211_hdr_3addr *i802_11_hdr; - u16 frame_ctl; + struct at76_priv *priv = hw->priv; - if (priv->device_unplugged) { - at76_dbg(DBG_DEVSTART, "device unplugged"); - if (urb) - at76_dbg(DBG_DEVSTART, "urb status %d", urb->status); - return; - } - - if (!priv->rx_skb || !netdev || !priv->rx_skb->data) - return; + int i; - buf = (struct at76_rx_buffer *)priv->rx_skb->data; + at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d " + "key->keylen %d", + __func__, cmd, key->alg, key->keyidx, key->keylen); - i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet; + if (key->alg != ALG_WEP) + return -EOPNOTSUPP; - frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl); + key->hw_key_idx = key->keyidx; - if (urb->status != 0) { - if (urb->status != -ENOENT && urb->status != -ECONNRESET) - at76_dbg(DBG_URB, - "%s %s: - nonzero Rx bulk status received: %d", - __func__, netdev->name, urb->status); - return; - } + mutex_lock(&priv->mtx); - at76_dbg(DBG_RX_ATMEL_HDR, - "%s: rx frame: rate %d rssi %d noise %d link %d %s", - priv->netdev->name, buf->rx_rate, buf->rssi, buf->noise_level, - buf->link_quality, hex2str(i802_11_hdr, 48)); - if (priv->iw_mode == IW_MODE_MONITOR) { - at76_rx_monitor_mode(priv); - goto exit; - } + switch (cmd) { + case SET_KEY: + memcpy(priv->wep_keys[key->keyidx], key->key, key->keylen); + priv->wep_keys_len[key->keyidx] = key->keylen; - /* there is a new bssid around, accept it: */ - if (buf->newbss && priv->iw_mode == IW_MODE_ADHOC) { - at76_dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name); - schedule_work(&priv->work_new_bss); - } + /* FIXME: find out how to do this properly */ + priv->wep_key_id = key->keyidx; - switch (frame_ctl & IEEE80211_FCTL_FTYPE) { - case IEEE80211_FTYPE_DATA: - at76_rx_data(priv); break; + case DISABLE_KEY: + default: + priv->wep_keys_len[key->keyidx] = 0; + break; + } - case IEEE80211_FTYPE_MGMT: - /* jal: TODO: find out if we can update iwspy also on - other frames than management (might depend on the - radio chip / firmware version !) */ + priv->wep_enabled = 0; - at76_iwspy_update(priv, buf); + for (i = 0; i < WEP_KEYS; i++) { + if (priv->wep_keys_len[i] != 0) + priv->wep_enabled = 1; + } - at76_rx_mgmt(priv, buf); - break; + at76_startup_device(priv); - case IEEE80211_FTYPE_CTL: - at76_dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x", - priv->netdev->name, frame_ctl); - break; + mutex_unlock(&priv->mtx); - default: - printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n", - priv->netdev->name, frame_ctl); - } -exit: - at76_submit_rx_urb(priv); + return 0; } -/* Load firmware into kernel memory and parse it */ -static struct fwentry *at76_load_firmware(struct usb_device *udev, - enum board_type board_type) +static int at76_set_key_newfw(struct ieee80211_hw *hw, enum set_key_cmd cmd, + const u8 *local_address, const u8 *address, + struct ieee80211_key_conf *key) { - int ret; - char *str; - struct at76_fw_header *fwh; - struct fwentry *fwe = &firmwares[board_type]; + struct at76_priv *priv = hw->priv; + int ret = -EOPNOTSUPP; - mutex_lock(&fw_mutex); + at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d " + "key->keylen %d", + __func__, cmd, key->alg, key->keyidx, key->keylen); - if (fwe->loaded) { - at76_dbg(DBG_FW, "re-using previously loaded fw"); - goto exit; - } + mutex_lock(&priv->mtx); - at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); - ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); - if (ret < 0) { - dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n", - fwe->fwname); - dev_printk(KERN_ERR, &udev->dev, - "you may need to download the firmware from " - "http://developer.berlios.de/projects/at76c503a/"); - goto exit; - } + priv->mib_buf.type = MIB_MAC_ENCRYPTION; - at76_dbg(DBG_FW, "got it."); - fwh = (struct at76_fw_header *)(fwe->fw->data); + if (cmd == DISABLE_KEY) { + priv->mib_buf.size = CIPHER_KEY_LEN; + priv->mib_buf.index = offsetof(struct mib_mac_encryption, + cipher_default_keyvalue[key->keyidx]); + memset(priv->mib_buf.data.data, 0, CIPHER_KEY_LEN); + if (at76_set_mib(priv, &priv->mib_buf) != CMD_STATUS_COMPLETE) + ret = -EOPNOTSUPP; /* -EIO would be probably better */ + else { - if (fwe->fw->size <= sizeof(*fwh)) { - dev_printk(KERN_ERR, &udev->dev, - "firmware is too short (0x%zx)\n", fwe->fw->size); - goto exit; - } + priv->keys[key->keyidx].cipher = CIPHER_NONE; + priv->keys[key->keyidx].keylen = 0; + }; + if (priv->default_group_key == key->keyidx) + priv->default_group_key = 0xff; - /* CRC currently not checked */ - fwe->board_type = le32_to_cpu(fwh->board_type); - if (fwe->board_type != board_type) { - dev_printk(KERN_ERR, &udev->dev, - "board type mismatch, requested %u, got %u\n", - board_type, fwe->board_type); + if (priv->default_pairwise_key == key->keyidx) + priv->default_pairwise_key = 0xff; + /* If default pairwise key is removed, fall back to + * group key? */ + ret = 0; goto exit; - } + }; - fwe->fw_version.major = fwh->major; - fwe->fw_version.minor = fwh->minor; - fwe->fw_version.patch = fwh->patch; - fwe->fw_version.build = fwh->build; + if (cmd == SET_KEY) { + /* store key into MIB */ + priv->mib_buf.size = CIPHER_KEY_LEN; + priv->mib_buf.index = offsetof(struct mib_mac_encryption, + cipher_default_keyvalue[key->keyidx]); + memset(priv->mib_buf.data.data, 0, CIPHER_KEY_LEN); + memcpy(priv->mib_buf.data.data, key->key, key->keylen); + + switch (key->alg) { + case ALG_WEP: + if (key->keylen == 5) { + priv->keys[key->keyidx].cipher = + CIPHER_WEP64; + priv->keys[key->keyidx].keylen = 8; + } else if (key->keylen == 13) { + priv->keys[key->keyidx].cipher = + CIPHER_WEP128; + /* Firmware needs this */ + priv->keys[key->keyidx].keylen = 8; + } else { + ret = -EOPNOTSUPP; + goto exit; + }; + break; + case ALG_TKIP: + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + priv->keys[key->keyidx].cipher = CIPHER_TKIP; + priv->keys[key->keyidx].keylen = 12; + break; - str = (char *)fwh + le32_to_cpu(fwh->str_offset); - fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset); - fwe->intfw_size = le32_to_cpu(fwh->int_fw_len); - fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset); - fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len); + case ALG_CCMP: + if (!at76_is_505a(priv->board_type)) { + ret = -EOPNOTSUPP; + goto exit; + }; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + priv->keys[key->keyidx].cipher = CIPHER_CCMP; + priv->keys[key->keyidx].keylen = 16; + break; - fwe->loaded = 1; + default: + ret = -EOPNOTSUPP; + goto exit; + }; + + priv->mib_buf.data.data[38] = priv->keys[key->keyidx].cipher; + priv->mib_buf.data.data[39] = 1; /* Taken from atmelwlandriver, + not documented */ + + if (is_valid_ether_addr(address)) + /* Pairwise key */ + priv->mib_buf.data.data[39] |= (KEY_PAIRWISE | KEY_TX); + else if (is_broadcast_ether_addr(address)) + /* Group key */ + priv->mib_buf.data.data[39] |= (KEY_TX); + else /* Key used only for transmission ??? */ + priv->mib_buf.data.data[39] |= (KEY_TX); + + if (at76_set_mib(priv, &priv->mib_buf) != + CMD_STATUS_COMPLETE) { + ret = -EOPNOTSUPP; /* -EIO would be probably better */ + goto exit; + }; - dev_printk(KERN_DEBUG, &udev->dev, - "using firmware %s (version %d.%d.%d-%d)\n", - fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build); + if ((key->alg == ALG_TKIP) || (key->alg == ALG_CCMP)) + at76_reset_rsc(priv); - at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type, - le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len), - le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len)); - at76_dbg(DBG_DEVSTART, "firmware id %s", str); + key->hw_key_idx = key->keyidx; + + /* Set up default keys */ + if (is_broadcast_ether_addr(address)) + priv->default_group_key = key->keyidx; + if (is_valid_ether_addr(address)) + priv->default_pairwise_key = key->keyidx; + + /* Set up encryption MIBs */ + + /* first block of settings */ + priv->mib_buf.size = 3; + priv->mib_buf.index = offsetof(struct mib_mac_encryption, + privacy_invoked); + priv->mib_buf.data.data[0] = 1; /* privacy_invoked */ + priv->mib_buf.data.data[1] = priv->default_pairwise_key; + priv->mib_buf.data.data[2] = priv->default_group_key; + + ret = at76_set_mib(priv, &priv->mib_buf); + if (ret != CMD_STATUS_COMPLETE) + goto exit; + + /* second block of settings */ + priv->mib_buf.size = 3; + priv->mib_buf.index = offsetof(struct mib_mac_encryption, + exclude_unencrypted); + priv->mib_buf.data.data[0] = 1; /* exclude_unencrypted */ + priv->mib_buf.data.data[1] = 0; /* wep_encryption_type */ + priv->mib_buf.data.data[2] = 0; /* ckip_key_permutation */ + ret = at76_set_mib(priv, &priv->mib_buf); + if (ret != CMD_STATUS_COMPLETE) + goto exit; + ret = 0; + }; exit: - mutex_unlock(&fw_mutex); + at76_dump_mib_mac_encryption(priv); + mutex_unlock(&priv->mtx); + return ret; +} - if (fwe->loaded) - return fwe; +static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + const u8 *local_address, const u8 *address, + struct ieee80211_key_conf *key) +{ + struct at76_priv *priv = hw->priv; + + at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d " + "key->keylen %d", + __func__, cmd, key->alg, key->keyidx, key->keylen); + + if (FIRMWARE_IS_WPA(priv->fw_version)) + return at76_set_key_newfw(hw, cmd, local_address, address, key); else - return NULL; + return at76_set_key_oldfw(hw, cmd, local_address, address, key); + } +static const struct ieee80211_ops at76_ops = { + .tx = at76_mac80211_tx, + .add_interface = at76_add_interface, + .remove_interface = at76_remove_interface, + .config = at76_config, + .config_interface = at76_config_interface, + .configure_filter = at76_configure_filter, + .start = at76_mac80211_start, + .stop = at76_mac80211_stop, + .hw_scan = at76_hw_scan, + .set_key = at76_set_key, +}; + /* Allocate network device and initialize private data */ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev) { - struct net_device *netdev; + struct ieee80211_hw *hw; struct at76_priv *priv; - int i; - /* allocate memory for our device state and initialize it */ - netdev = alloc_etherdev(sizeof(struct at76_priv)); - if (!netdev) { - dev_printk(KERN_ERR, &udev->dev, "out of memory\n"); + hw = ieee80211_alloc_hw(sizeof(struct at76_priv), &at76_ops); + if (!hw) { + printk(KERN_ERR DRIVER_NAME ": could not register" + " ieee80211_hw\n"); return NULL; } - priv = netdev_priv(netdev); + priv = hw->priv; + priv->hw = hw; priv->udev = udev; - priv->netdev = netdev; mutex_init(&priv->mtx); - INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done); - INIT_WORK(&priv->work_join, at76_work_join); - INIT_WORK(&priv->work_new_bss, at76_work_new_bss); - INIT_WORK(&priv->work_start_scan, at76_work_start_scan); INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc); INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx); - INIT_DELAYED_WORK(&priv->dwork_restart, at76_dwork_restart); - INIT_DELAYED_WORK(&priv->dwork_get_scan, at76_dwork_get_scan); - INIT_DELAYED_WORK(&priv->dwork_beacon, at76_dwork_beacon); - INIT_DELAYED_WORK(&priv->dwork_auth, at76_dwork_auth); - INIT_DELAYED_WORK(&priv->dwork_assoc, at76_dwork_assoc); - - spin_lock_init(&priv->mgmt_spinlock); - priv->next_mgmt_bulk = NULL; - priv->mac_state = MAC_INIT; - - /* initialize empty BSS list */ - priv->curr_bss = NULL; - INIT_LIST_HEAD(&priv->bss_list); - spin_lock_init(&priv->bss_list_spinlock); - - init_timer(&priv->bss_list_timer); - priv->bss_list_timer.data = (unsigned long)priv; - priv->bss_list_timer.function = at76_bss_list_timeout; - - spin_lock_init(&priv->spy_spinlock); - - /* mark all rx data entries as unused */ - for (i = 0; i < NR_RX_DATA_BUF; i++) - priv->rx_data[i].skb = NULL; + INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan); priv->rx_tasklet.func = at76_rx_tasklet; priv->rx_tasklet.data = 0; @@ -5197,6 +2371,9 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev) priv->pm_mode = AT76_PM_OFF; priv->pm_period = 0; + /* unit us */ + priv->hw->channel_change_time = 100000; + return priv; } @@ -5259,11 +2436,42 @@ static int at76_alloc_urbs(struct at76_priv *priv, return 0; } +static struct ieee80211_rate at76_rates[] = { + { .bitrate = 10, .hw_value = TX_RATE_1MBIT, }, + { .bitrate = 20, .hw_value = TX_RATE_2MBIT, }, + { .bitrate = 55, .hw_value = TX_RATE_5_5MBIT, }, + { .bitrate = 110, .hw_value = TX_RATE_11MBIT, }, +}; + +static struct ieee80211_channel at76_channels[] = { + { .center_freq = 2412, .hw_value = 1 }, + { .center_freq = 2417, .hw_value = 2 }, + { .center_freq = 2422, .hw_value = 3 }, + { .center_freq = 2427, .hw_value = 4 }, + { .center_freq = 2432, .hw_value = 5 }, + { .center_freq = 2437, .hw_value = 6 }, + { .center_freq = 2442, .hw_value = 7 }, + { .center_freq = 2447, .hw_value = 8 }, + { .center_freq = 2452, .hw_value = 9 }, + { .center_freq = 2457, .hw_value = 10 }, + { .center_freq = 2462, .hw_value = 11 }, + { .center_freq = 2467, .hw_value = 12 }, + { .center_freq = 2472, .hw_value = 13 }, + { .center_freq = 2484, .hw_value = 14 } +}; + +static struct ieee80211_supported_band at76_supported_band = { + .channels = at76_channels, + .n_channels = ARRAY_SIZE(at76_channels), + .bitrates = at76_rates, + .n_bitrates = ARRAY_SIZE(at76_rates), +}; + /* Register network device and initialize the hardware */ static int at76_init_new_device(struct at76_priv *priv, struct usb_interface *interface) { - struct net_device *netdev = priv->netdev; + struct device *dev = &interface->dev; int ret; /* set up the endpoint information */ @@ -5279,14 +2487,11 @@ static int at76_init_new_device(struct at76_priv *priv, /* MAC address */ ret = at76_get_hw_config(priv); if (ret < 0) { - dev_printk(KERN_ERR, &interface->dev, - "cannot get MAC address\n"); + dev_err(dev, "cannot get MAC address\n"); goto exit; } priv->domain = at76_get_reg_domain(priv->regulatory_domain); - /* init. netdev->dev_addr */ - memcpy(netdev->dev_addr, priv->mac_addr, ETH_ALEN); priv->channel = DEF_CHANNEL; priv->iw_mode = IW_MODE_INFRA; @@ -5296,47 +2501,54 @@ static int at76_init_new_device(struct at76_priv *priv, priv->txrate = TX_RATE_AUTO; priv->preamble_type = PREAMBLE_TYPE_LONG; priv->beacon_period = 100; - priv->beacons_last_qual = jiffies; priv->auth_mode = WLAN_AUTH_OPEN; priv->scan_min_time = DEF_SCAN_MIN_TIME; priv->scan_max_time = DEF_SCAN_MAX_TIME; priv->scan_mode = SCAN_TYPE_ACTIVE; + priv->default_pairwise_key = 0xff; + priv->default_group_key = 0xff; + + /* mac80211 initialisation */ + priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band; + + if (FIRMWARE_IS_WPA(priv->fw_version) && + (at76_is_503rfmd(priv->board_type) || + at76_is_505(priv->board_type))) + priv->hw->flags = IEEE80211_HW_SIGNAL_UNSPEC; + else + priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_SIGNAL_UNSPEC; + + priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - netdev->flags &= ~IFF_MULTICAST; /* not yet or never */ - netdev->open = at76_open; - netdev->stop = at76_stop; - netdev->get_stats = at76_get_stats; - netdev->ethtool_ops = &at76_ethtool_ops; - - /* Add pointers to enable iwspy support. */ - priv->wireless_data.spy_data = &priv->spy_data; - netdev->wireless_data = &priv->wireless_data; - - netdev->hard_start_xmit = at76_tx; - netdev->tx_timeout = at76_tx_timeout; - netdev->watchdog_timeo = 2 * HZ; - netdev->wireless_handlers = &at76_handler_def; - netdev->set_multicast_list = at76_set_multicast; - netdev->set_mac_address = at76_set_mac_address; - dev_alloc_name(netdev, "wlan%d"); - - ret = register_netdev(priv->netdev); + SET_IEEE80211_DEV(priv->hw, &interface->dev); + SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); + + ret = ieee80211_register_hw(priv->hw); if (ret) { - dev_printk(KERN_ERR, &interface->dev, - "cannot register netdevice (status %d)!\n", ret); + dev_err(dev, "cannot register mac80211 hw (status %d)!\n", ret); goto exit; } - priv->netdev_registered = 1; - printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n", - netdev->name, dev_name(&interface->dev), mac2str(priv->mac_addr), - priv->fw_version.major, priv->fw_version.minor, - priv->fw_version.patch, priv->fw_version.build); - printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name, - priv->regulatory_domain, priv->domain->name); + priv->mac80211_registered = 1; - /* we let this timer run the whole time this driver instance lives */ - mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT); + dev_info(dev, "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n", + wiphy_name(priv->hw->wiphy), + dev_name(&interface->dev), mac2str(priv->mac_addr), + priv->fw_version.major, priv->fw_version.minor, + priv->fw_version.patch, priv->fw_version.build); + dev_info(dev, "%s: regulatory domain 0x%02x: %s\n", + wiphy_name(priv->hw->wiphy), + priv->regulatory_domain, priv->domain->name); + dev_info(dev, "%s: WPA support: ", wiphy_name(priv->hw->wiphy)); + if (!FIRMWARE_IS_WPA(priv->fw_version)) + printk("none\n"); + else { + if (!at76_is_505a(priv->board_type)) + printk("TKIP\n"); + else + printk("TKIP, AES/CCMP\n"); + }; exit: return ret; @@ -5344,15 +2556,13 @@ static int at76_init_new_device(struct at76_priv *priv, static void at76_delete_device(struct at76_priv *priv) { - int i; - at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__); /* The device is gone, don't bother turning it off */ priv->device_unplugged = 1; - if (priv->netdev_registered) - unregister_netdev(priv->netdev); + if (priv->mac80211_registered) + ieee80211_unregister_hw(priv->hw); /* assuming we used keventd, it must quiesce too */ flush_scheduled_work(); @@ -5373,25 +2583,11 @@ static void at76_delete_device(struct at76_priv *priv) if (priv->rx_skb) kfree_skb(priv->rx_skb); - at76_free_bss_list(priv); - del_timer_sync(&priv->bss_list_timer); - cancel_delayed_work(&priv->dwork_get_scan); - cancel_delayed_work(&priv->dwork_beacon); - cancel_delayed_work(&priv->dwork_auth); - cancel_delayed_work(&priv->dwork_assoc); - - if (priv->mac_state == MAC_CONNECTED) - at76_iwevent_bss_disconnect(priv->netdev); - - for (i = 0; i < NR_RX_DATA_BUF; i++) - if (priv->rx_data[i].skb) { - dev_kfree_skb(priv->rx_data[i].skb); - priv->rx_data[i].skb = NULL; - } usb_put_dev(priv->udev); - at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/netdev", __func__); - free_netdev(priv->netdev); /* priv is in netdev */ + at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw", + __func__); + ieee80211_free_hw(priv->hw); at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__); } @@ -5425,8 +2621,8 @@ static int at76_probe(struct usb_interface *interface, we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */ if (op_mode == OPMODE_HW_CONFIG_MODE) { - dev_printk(KERN_ERR, &interface->dev, - "cannot handle a device in HW_CONFIG_MODE\n"); + dev_err(&interface->dev, + "cannot handle a device in HW_CONFIG_MODE\n"); ret = -EBUSY; goto error; } @@ -5434,13 +2630,12 @@ static int at76_probe(struct usb_interface *interface, if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { /* download internal firmware part */ - dev_printk(KERN_DEBUG, &interface->dev, - "downloading internal firmware\n"); + dev_dbg(&interface->dev, "downloading internal firmware\n"); ret = at76_load_internal_fw(udev, fwe); if (ret < 0) { - dev_printk(KERN_ERR, &interface->dev, - "error %d downloading internal firmware\n", - ret); + dev_err(&interface->dev, + "error %d downloading internal firmware\n", + ret); goto error; } usb_put_dev(udev); @@ -5465,8 +2660,7 @@ static int at76_probe(struct usb_interface *interface, need_ext_fw = 1; if (need_ext_fw) { - dev_printk(KERN_DEBUG, &interface->dev, - "downloading external firmware\n"); + dev_dbg(&interface->dev, "downloading external firmware\n"); ret = at76_load_external_fw(udev, fwe); if (ret) @@ -5475,8 +2669,8 @@ static int at76_probe(struct usb_interface *interface, /* Re-check firmware version */ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv)); if (ret < 0) { - dev_printk(KERN_ERR, &interface->dev, - "error %d getting firmware version\n", ret); + dev_err(&interface->dev, + "error %d getting firmware version\n", ret); goto error; } } @@ -5487,7 +2681,6 @@ static int at76_probe(struct usb_interface *interface, goto error; } - SET_NETDEV_DEV(priv->netdev, &interface->dev); usb_set_intfdata(interface, priv); memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version)); @@ -5515,7 +2708,7 @@ static void at76_disconnect(struct usb_interface *interface) if (!priv) return; - printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name); + printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy)); at76_delete_device(priv); dev_printk(KERN_INFO, &interface->dev, "disconnected\n"); } @@ -5571,5 +2764,8 @@ MODULE_AUTHOR("Alex "); MODULE_AUTHOR("Nick Jones"); MODULE_AUTHOR("Balint Seeber "); MODULE_AUTHOR("Pavel Roskin "); +MODULE_AUTHOR("Guido Guenther "); +MODULE_AUTHOR("Kalle Valo "); +MODULE_AUTHOR("Milan Plzik "); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/staging/at76_usb/at76_usb.h b/trunk/drivers/staging/at76_usb/at76_usb.h index b20be9da1fa1..8bb352f16d45 100644 --- a/trunk/drivers/staging/at76_usb/at76_usb.h +++ b/trunk/drivers/staging/at76_usb/at76_usb.h @@ -34,23 +34,6 @@ enum board_type { BOARD_505AMX = 8 }; -/* our private ioctl's */ -/* preamble length (0 - long, 1 - short, 2 - auto) */ -#define AT76_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0) -#define AT76_GET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 1) -/* which debug channels are enabled */ -#define AT76_SET_DEBUG (SIOCIWFIRSTPRIV + 2) -#define AT76_GET_DEBUG (SIOCIWFIRSTPRIV + 3) -/* power save mode (incl. the Atmel proprietary smart save mode) */ -#define AT76_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 4) -#define AT76_GET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 5) -/* min and max channel times for scan */ -#define AT76_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 6) -#define AT76_GET_SCAN_TIMES (SIOCIWFIRSTPRIV + 7) -/* scan mode (0 - active, 1 - passive) */ -#define AT76_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 8) -#define AT76_GET_SCAN_MODE (SIOCIWFIRSTPRIV + 9) - #define CMD_STATUS_IDLE 0x00 #define CMD_STATUS_COMPLETE 0x01 #define CMD_STATUS_UNKNOWN 0x02 @@ -82,6 +65,7 @@ enum board_type { #define MIB_MAC 0x03 #define MIB_MAC_MGMT 0x05 #define MIB_MAC_WEP 0x06 +#define MIB_MAC_ENCRYPTION 0x06 #define MIB_PHY 0x07 #define MIB_FW_VERSION 0x08 #define MIB_MDOMAIN 0x09 @@ -106,6 +90,26 @@ enum board_type { #define AT76_PM_ON 2 #define AT76_PM_SMART 3 +/* cipher values for encryption keys */ +#define CIPHER_NONE 0 /* this value is only guessed */ +#define CIPHER_WEP64 1 +#define CIPHER_TKIP 2 +#define CIPHER_CCMP 3 +#define CIPHER_CCX 4 /* for consistency sake only */ +#define CIPHER_WEP128 5 + +/* bit flags key types for encryption keys */ +#define KEY_PAIRWISE 2 +#define KEY_TX 4 + +#define CIPHER_KEYS (4) +#define CIPHER_KEY_LEN (40) + +struct key_config { + u8 cipher; + u8 keylen; +}; + struct hwcfg_r505 { u8 cr39_values[14]; u8 reserved1[14]; @@ -147,6 +151,9 @@ union at76_hwcfg { #define WEP_SMALL_KEY_LEN (40 / 8) #define WEP_LARGE_KEY_LEN (104 / 8) +#define WEP_KEYS (4) + + struct at76_card_config { u8 exclude_unencrypted; @@ -161,7 +168,7 @@ struct at76_card_config { u8 privacy_invoked; u8 wep_default_key_id; /* 0..3 */ u8 current_ssid[32]; - u8 wep_default_key_value[4][WEP_KEY_LEN]; + u8 wep_default_key_value[4][WEP_LARGE_KEY_LEN]; u8 ssid_len; u8 short_preamble; __le16 beacon_period; @@ -186,7 +193,7 @@ struct at76_rx_buffer { u8 link_quality; u8 noise_level; __le32 rx_time; - u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN]; + u8 packet[IEEE80211_MAX_FRAG_THRESHOLD]; } __attribute__((packed)); /* Length of Atmel-specific Tx header before 802.11 frame */ @@ -196,8 +203,11 @@ struct at76_tx_buffer { __le16 wlength; u8 tx_rate; u8 padding; - u8 reserved[4]; - u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN]; + u8 key_id; + u8 cipher_type; + u8 cipher_length; + u8 reserved; + u8 packet[IEEE80211_MAX_FRAG_THRESHOLD]; } __attribute__((packed)); /* defines for scan_type below */ @@ -244,6 +254,7 @@ struct set_mib_buffer { u8 byte; __le16 word; u8 addr[ETH_ALEN]; + u8 data[256]; /* we need more space for mib_mac_encryption */ } data; } __attribute__((packed)); @@ -317,10 +328,24 @@ struct mib_mac_wep { u8 exclude_unencrypted; __le32 wep_icv_error_count; __le32 wep_excluded_count; - u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN]; + u8 wep_default_keyvalue[WEP_KEYS][WEP_LARGE_KEY_LEN]; u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */ } __attribute__((packed)); +struct mib_mac_encryption { + u8 cipher_default_keyvalue[CIPHER_KEYS][CIPHER_KEY_LEN]; + u8 tkip_bssid[6]; + u8 privacy_invoked; + u8 cipher_default_key_id; + u8 cipher_default_group_key_id; + u8 exclude_unencrypted; + u8 wep_encryption_type; + u8 ckip_key_permutation; /* bool */ + __le32 wep_icv_error_count; + __le32 wep_excluded_count; + u8 key_rsc[CIPHER_KEYS][8]; +} __attribute__((packed)); + struct mib_phy { __le32 ed_threshold; @@ -364,16 +389,6 @@ struct at76_fw_header { __le32 ext_fw_len; /* external firmware image length */ } __attribute__((packed)); -enum mac_state { - MAC_INIT, - MAC_SCANNING, - MAC_AUTH, - MAC_ASSOC, - MAC_JOINING, - MAC_CONNECTED, - MAC_OWN_IBSS -}; - /* a description of a regulatory domain and the allowed channels */ struct reg_domain { u16 code; @@ -381,47 +396,6 @@ struct reg_domain { u32 channel_map; /* if bit N is set, channel (N+1) is allowed */ }; -/* how long do we keep a (I)BSS in the bss_list in jiffies - this should be long enough for the user to retrieve the table - (by iwlist ?) after the device started, because all entries from - other channels than the one the device locks on get removed, too */ -#define BSS_LIST_TIMEOUT (120 * HZ) -/* struct to store BSS info found during scan */ -#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */ - -struct bss_info { - struct list_head list; - - u8 bssid[ETH_ALEN]; /* bssid */ - u8 ssid[IW_ESSID_MAX_SIZE]; /* essid */ - u8 ssid_len; /* length of ssid above */ - u8 channel; - u16 capa; /* BSS capabilities */ - u16 beacon_interval; /* beacon interval, Kus (1024 microseconds) */ - u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates in units of - 500 kbps, ORed with 0x80 for - basic rates */ - u8 rates_len; - - /* quality of received beacon */ - u8 rssi; - u8 link_qual; - u8 noise_level; - - unsigned long last_rx; /* time (jiffies) of last beacon received */ -}; - -/* a rx data buffer to collect rx fragments */ -struct rx_data_buf { - u8 sender[ETH_ALEN]; /* sender address */ - u16 seqnr; /* sequence number */ - u16 fragnr; /* last fragment received */ - unsigned long last_rx; /* jiffies of last rx */ - struct sk_buff *skb; /* == NULL if entry is free */ -}; - -#define NR_RX_DATA_BUF 8 - /* Data for one loaded firmware file */ struct fwentry { const char *const fwname; @@ -438,11 +412,9 @@ struct fwentry { struct at76_priv { struct usb_device *udev; /* USB device pointer */ - struct net_device *netdev; /* net device pointer */ - struct net_device_stats stats; /* net device stats */ - struct iw_statistics wstats; /* wireless stats */ struct sk_buff *rx_skb; /* skbuff for receiving data */ + struct sk_buff *tx_skb; /* skbuff for transmitting data */ void *bulk_out_buffer; /* buffer for sending data */ struct urb *tx_urb; /* URB for sending data */ @@ -454,26 +426,17 @@ struct at76_priv { struct mutex mtx; /* locks this structure */ /* work queues */ - struct work_struct work_assoc_done; - struct work_struct work_join; - struct work_struct work_new_bss; - struct work_struct work_start_scan; struct work_struct work_set_promisc; struct work_struct work_submit_rx; - struct delayed_work dwork_restart; - struct delayed_work dwork_get_scan; - struct delayed_work dwork_beacon; - struct delayed_work dwork_auth; - struct delayed_work dwork_assoc; + struct delayed_work dwork_hw_scan; struct tasklet_struct rx_tasklet; /* the WEP stuff */ int wep_enabled; /* 1 if WEP is enabled */ int wep_key_id; /* key id to be used */ - u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys, - 5 or 13 bytes are used */ - u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */ + u8 wep_keys[WEP_KEYS][WEP_LARGE_KEY_LEN]; /* WEP keys */ + u8 wep_keys_len[WEP_KEYS]; /* length of WEP keys */ int channel; int iw_mode; @@ -495,44 +458,13 @@ struct at76_priv { int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */ int scan_need_any; /* if set, need to scan for any ESSID */ - /* the list we got from scanning */ - spinlock_t bss_list_spinlock; /* protects bss_list operations */ - struct list_head bss_list; /* list of BSS we got beacons from */ - struct timer_list bss_list_timer; /* timer to purge old entries - from bss_list */ - struct bss_info *curr_bss; /* current BSS */ u16 assoc_id; /* current association ID, if associated */ - u8 wanted_bssid[ETH_ALEN]; - int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */ - - /* some data for infrastructure mode only */ - spinlock_t mgmt_spinlock; /* this spinlock protects access to - next_mgmt_bulk */ - - struct at76_tx_buffer *next_mgmt_bulk; /* pending management msg to - send via bulk out */ - enum mac_state mac_state; - enum { - SCAN_IDLE, - SCAN_IN_PROGRESS, - SCAN_COMPLETED - } scan_state; - time_t last_scan; - - int retries; /* remaining retries in case of timeout when - * sending AuthReq or AssocReq */ u8 pm_mode; /* power management mode */ u32 pm_period; /* power management period in microseconds */ struct reg_domain const *domain; /* reg domain description */ - /* iwspy support */ - spinlock_t spy_spinlock; - struct iw_spy_data spy_data; - - struct iw_public_data wireless_data; - /* These fields contain HW config provided by the device (not all of * these fields are used by all board types) */ u8 mac_addr[ETH_ALEN]; @@ -540,9 +472,6 @@ struct at76_priv { struct at76_card_config card_config; - /* store rx fragments until complete */ - struct rx_data_buf rx_data[NR_RX_DATA_BUF]; - enum board_type board_type; struct mib_fw_version fw_version; @@ -550,58 +479,20 @@ struct at76_priv { unsigned int netdev_registered:1; struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */ - /* beacon counting */ int beacon_period; /* period of mgmt beacons, Kus */ - int beacons_received; - unsigned long beacons_last_qual; /* time we restarted counting - beacons */ -}; -struct at76_rx_radiotap { - struct ieee80211_radiotap_header rt_hdr; - __le64 rt_tsft; - u8 rt_flags; - u8 rt_rate; - s8 rt_signal; - s8 rt_noise; -}; - -#define AT76_RX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_TSFT) | \ - (1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTNOISE)) - -#define BEACON_MAX_DATA_LENGTH 1500 - -/* the maximum size of an AssocReq packet */ -#define ASSOCREQ_MAX_SIZE \ - (AT76_TX_HDRLEN + sizeof(struct ieee80211_assoc_request) + \ - 1 + 1 + IW_ESSID_MAX_SIZE + 1 + 1 + 4) - -/* for shared secret auth, add the challenge text size */ -#define AUTH_FRAME_SIZE (AT76_TX_HDRLEN + sizeof(struct ieee80211_auth)) + struct ieee80211_hw *hw; + int mac80211_registered; -/* Maximal number of AuthReq retries */ -#define AUTH_RETRIES 3 - -/* Maximal number of AssocReq retries */ -#define ASSOC_RETRIES 3 - -/* Beacon timeout in managed mode when we are connected */ -#define BEACON_TIMEOUT (10 * HZ) - -/* Timeout for authentication response */ -#define AUTH_TIMEOUT (1 * HZ) + struct key_config keys[4]; /* installed key types */ + u8 default_pairwise_key; + u8 default_group_key; +}; -/* Timeout for association response */ -#define ASSOC_TIMEOUT (1 * HZ) +#define AT76_SUPPORTED_FILTERS FIF_PROMISC_IN_BSS -/* Polling interval when scan is running */ #define SCAN_POLL_INTERVAL (HZ / 4) -/* Command completion timeout */ #define CMD_COMPLETION_TIMEOUT (5 * HZ) #define DEF_RTS_THRESHOLD 1536 @@ -611,8 +502,6 @@ struct at76_rx_radiotap { #define DEF_SCAN_MIN_TIME 10 #define DEF_SCAN_MAX_TIME 120 -#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1) - /* the max padding size for tx in bytes (see calc_padding) */ #define MAX_PADDING_SIZE 53 diff --git a/trunk/drivers/staging/panel/panel.c b/trunk/drivers/staging/panel/panel.c index c2747bc88c6f..5ffe269c2382 100644 --- a/trunk/drivers/staging/panel/panel.c +++ b/trunk/drivers/staging/panel/panel.c @@ -622,7 +622,7 @@ static int set_ctrl_bits(void) } /* sets ctrl & data port bits according to current signals values */ -static void panel_set_bits(void) +static void set_bits(void) { set_data_bits(); set_ctrl_bits(); @@ -707,12 +707,12 @@ static void lcd_send_serial(int byte) */ for (bit = 0; bit < 8; bit++) { bits.cl = BIT_CLR; /* CLK low */ - panel_set_bits(); + set_bits(); bits.da = byte & 1; - panel_set_bits(); + set_bits(); udelay(2); /* maintain the data during 2 us before CLK up */ bits.cl = BIT_SET; /* CLK high */ - panel_set_bits(); + set_bits(); udelay(1); /* maintain the strobe during 1 us */ byte >>= 1; } @@ -727,7 +727,7 @@ static void lcd_backlight(int on) /* The backlight is activated by seting the AUTOFEED line to +5V */ spin_lock(&pprt_lock); bits.bl = on; - panel_set_bits(); + set_bits(); spin_unlock(&pprt_lock); } @@ -2164,20 +2164,19 @@ static void __exit panel_cleanup_module(void) if (scan_timer.function != NULL) del_timer(&scan_timer); - if (pprt != NULL) { - if (keypad_enabled) - misc_deregister(&keypad_dev); - - if (lcd_enabled) { - panel_lcd_print("\x0cLCD driver " PANEL_VERSION - "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); - misc_deregister(&lcd_dev); - } + if (keypad_enabled) + misc_deregister(&keypad_dev); - /* TODO: free all input signals */ - parport_release(pprt); - parport_unregister_device(pprt); + if (lcd_enabled) { + panel_lcd_print("\x0cLCD driver " PANEL_VERSION + "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); + misc_deregister(&lcd_dev); } + + /* TODO: free all input signals */ + + parport_release(pprt); + parport_unregister_device(pprt); parport_unregister_driver(&panel_driver); } diff --git a/trunk/drivers/staging/rtl8187se/Kconfig b/trunk/drivers/staging/rtl8187se/Kconfig index f636296b54bc..79c225acd1ad 100644 --- a/trunk/drivers/staging/rtl8187se/Kconfig +++ b/trunk/drivers/staging/rtl8187se/Kconfig @@ -1,6 +1,5 @@ config RTL8187SE tristate "RealTek RTL8187SE Wireless LAN NIC driver" depends on PCI - depends on WIRELESS_EXT && COMPAT_NET_DEV_OPS default N ---help--- diff --git a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c index 7370296225e1..af64cfbe16db 100644 --- a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +++ b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c @@ -234,21 +234,20 @@ int ieee80211_crypto_init(void) void ieee80211_crypto_deinit(void) { struct list_head *ptr, *n; - struct ieee80211_crypto_alg *alg = NULL; if (hcrypt == NULL) return; - list_for_each_safe(ptr, n, &hcrypt->algs) { - alg = list_entry(ptr, struct ieee80211_crypto_alg, list); - if (alg) { - list_del(ptr); - printk(KERN_DEBUG - "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n", - alg->ops->name); - kfree(alg); - } + for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; + ptr = n, n = ptr->next) { + struct ieee80211_crypto_alg *alg = + (struct ieee80211_crypto_alg *) ptr; + list_del(ptr); + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " + "'%s' (deinit)\n", alg->ops->name); + kfree(alg); } + kfree(hcrypt); } diff --git a/trunk/drivers/staging/rtl8187se/r8180_core.c b/trunk/drivers/staging/rtl8187se/r8180_core.c index 66de5cc8ddf1..94534955e38b 100644 --- a/trunk/drivers/staging/rtl8187se/r8180_core.c +++ b/trunk/drivers/staging/rtl8187se/r8180_core.c @@ -6161,10 +6161,10 @@ static void __exit rtl8180_pci_module_exit(void) { pci_unregister_driver (&rtl8180_pci_driver); rtl8180_proc_module_remove(); + ieee80211_crypto_deinit(); ieee80211_crypto_tkip_exit(); ieee80211_crypto_ccmp_exit(); ieee80211_crypto_wep_exit(); - ieee80211_crypto_deinit(); DMESG("Exiting"); } diff --git a/trunk/drivers/staging/winbond/wbusb.c b/trunk/drivers/staging/winbond/wbusb.c index f716b2e92b65..b003f9a7e151 100644 --- a/trunk/drivers/staging/winbond/wbusb.c +++ b/trunk/drivers/staging/winbond/wbusb.c @@ -319,18 +319,16 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id struct usb_device *udev = interface_to_usbdev(intf); struct wbsoft_priv *priv; struct ieee80211_hw *dev; - int nr, err; + int err; usb_get_dev(udev); // 20060630.2 Check the device if it already be opened - nr = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ), - 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, - 0x0, 0x400, <mp, 4, HZ*100 ); - if (nr < 0) { - err = nr; + err = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ), + 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, + 0x0, 0x400, <mp, 4, HZ*100 ); + if (err) goto error; - } ltmp = cpu_to_le32(ltmp); if (ltmp) { // Is already initialized? @@ -339,10 +337,8 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id } dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops); - if (!dev) { - err = -ENOMEM; + if (!dev) goto error; - } priv = dev->priv; @@ -373,11 +369,9 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id } dev->extra_tx_headroom = 12; /* FIXME */ - dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; - dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + dev->flags = 0; dev->channel_change_time = 1000; - dev->max_signal = 100; dev->queues = 1; dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz; diff --git a/trunk/drivers/usb/Makefile b/trunk/drivers/usb/Makefile index b2ceb4aff233..8bcde8cde554 100644 --- a/trunk/drivers/usb/Makefile +++ b/trunk/drivers/usb/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_USB_MON) += mon/ obj-$(CONFIG_PCI) += host/ obj-$(CONFIG_USB_EHCI_HCD) += host/ obj-$(CONFIG_USB_ISP116X_HCD) += host/ -obj-$(CONFIG_USB_ISP1760_HCD) += host/ obj-$(CONFIG_USB_OHCI_HCD) += host/ obj-$(CONFIG_USB_UHCI_HCD) += host/ obj-$(CONFIG_USB_FHCI_HCD) += host/ diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index b3d5a23ab56f..97ba4a985edc 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -1349,6 +1349,9 @@ static struct usb_device_id acm_ids[] = { { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, + { USB_DEVICE(0x0e8d, 0x3329), /* i-blue 747, Qstarz BT-Q1000, Holux M-241 */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, { USB_DEVICE(0x0e8d, 0x3329), /* MediaTek Inc GPS */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, @@ -1376,15 +1379,6 @@ static struct usb_device_id acm_ids[] = { { USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, - { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ - }, - { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ - .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on - data interface instead of - communications interface. - Maybe we should define a new - quirk for this. */ - }, /* control interfaces with various AT-command sets */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, diff --git a/trunk/drivers/usb/core/hcd-pci.c b/trunk/drivers/usb/core/hcd-pci.c index a4301dc02d27..c54fc40458b1 100644 --- a/trunk/drivers/usb/core/hcd-pci.c +++ b/trunk/drivers/usb/core/hcd-pci.c @@ -297,6 +297,19 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message) } EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend); +/** + * usb_hcd_pci_resume_early - resume a PCI-based HCD before IRQs are enabled + * @dev: USB Host Controller being resumed + * + * Store this function in the HCD's struct pci_driver as .resume_early. + */ +int usb_hcd_pci_resume_early(struct pci_dev *dev) +{ + pci_restore_state(dev); + return 0; +} +EXPORT_SYMBOL_GPL(usb_hcd_pci_resume_early); + /** * usb_hcd_pci_resume - power management resume of a PCI-based HCD * @dev: USB Host Controller being resumed @@ -320,8 +333,6 @@ int usb_hcd_pci_resume(struct pci_dev *dev) } #endif - pci_restore_state(dev); - hcd = pci_get_drvdata(dev); if (hcd->state != HC_STATE_SUSPENDED) { dev_dbg(hcd->self.controller, diff --git a/trunk/drivers/usb/core/hcd.h b/trunk/drivers/usb/core/hcd.h index f750eb1ab595..5b94a56bec23 100644 --- a/trunk/drivers/usb/core/hcd.h +++ b/trunk/drivers/usb/core/hcd.h @@ -257,6 +257,7 @@ extern void usb_hcd_pci_remove(struct pci_dev *dev); #ifdef CONFIG_PM extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t msg); +extern int usb_hcd_pci_resume_early(struct pci_dev *dev); extern int usb_hcd_pci_resume(struct pci_dev *dev); #endif /* CONFIG_PM */ diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 49e7f56e0d7f..31fb204f44c6 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -653,7 +653,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, if (result <= 0 && result != -ETIMEDOUT) continue; if (result > 1 && ((u8 *)buf)[1] != type) { - result = -ENODATA; + result = -EPROTO; continue; } break; @@ -696,13 +696,8 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid, USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, (USB_DT_STRING << 8) + index, langid, buf, size, USB_CTRL_GET_TIMEOUT); - if (result == 0 || result == -EPIPE) - continue; - if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) { - result = -ENODATA; - continue; - } - break; + if (!(result == 0 || result == -EPIPE)) + break; } return result; } diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index e55fef52a5dc..3219d137340a 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -191,7 +191,6 @@ config USB_GADGET_OMAP boolean "OMAP USB Device Controller" depends on ARCH_OMAP select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG - select USB_OTG_UTILS if ARCH_OMAP help Many Texas Instruments OMAP processors have flexible full speed USB device controllers, with support for up to 30 diff --git a/trunk/drivers/usb/gadget/f_obex.c b/trunk/drivers/usb/gadget/f_obex.c index 38aa896cc5db..80c2e7e9622f 100644 --- a/trunk/drivers/usb/gadget/f_obex.c +++ b/trunk/drivers/usb/gadget/f_obex.c @@ -366,9 +366,9 @@ obex_bind(struct usb_configuration *c, struct usb_function *f) f->hs_descriptors = usb_copy_descriptors(hs_function); obex->hs.obex_in = usb_find_endpoint(hs_function, - f->hs_descriptors, &obex_hs_ep_in_desc); + f->descriptors, &obex_hs_ep_in_desc); obex->hs.obex_out = usb_find_endpoint(hs_function, - f->hs_descriptors, &obex_hs_ep_out_desc); + f->descriptors, &obex_hs_ep_out_desc); } /* Avoid letting this gadget enumerate until the userspace diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index 1ab9dac7e12d..b10fa31cc915 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -3879,11 +3879,7 @@ static int __init check_parameters(struct fsg_dev *fsg) mod_data.protocol_type = USB_SC_SCSI; mod_data.protocol_name = "Transparent SCSI"; - /* Some peripheral controllers are known not to be able to - * halt bulk endpoints correctly. If one of them is present, - * disable stalls. - */ - if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget)) + if (gadget_is_sh(fsg->gadget)) mod_data.can_stall = 0; if (mod_data.release == 0xffff) { // Parameter wasn't set diff --git a/trunk/drivers/usb/gadget/fsl_qe_udc.c b/trunk/drivers/usb/gadget/fsl_qe_udc.c index d701bf4698d2..d6c5bcd40064 100644 --- a/trunk/drivers/usb/gadget/fsl_qe_udc.c +++ b/trunk/drivers/usb/gadget/fsl_qe_udc.c @@ -1622,8 +1622,6 @@ static int qe_ep_disable(struct usb_ep *_ep) nuke(ep, -ESHUTDOWN); ep->desc = NULL; ep->stopped = 1; - ep->tx_req = NULL; - qe_ep_reset(udc, ep->epnum); spin_unlock_irqrestore(&udc->lock, flags); cpm_muram_free(cpm_muram_offset(ep->rxbase)); @@ -1683,11 +1681,14 @@ static void qe_free_request(struct usb_ep *_ep, struct usb_request *_req) kfree(req); } -static int __qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req) +/* queues (submits) an I/O request to an endpoint */ +static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, + gfp_t gfp_flags) { struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); struct qe_req *req = container_of(_req, struct qe_req, req); struct qe_udc *udc; + unsigned long flags; int reval; udc = ep->udc; @@ -1731,7 +1732,7 @@ static int __qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req) list_add_tail(&req->queue, &ep->queue); dev_vdbg(udc->dev, "gadget have request in %s! %d\n", ep->name, req->req.length); - + spin_lock_irqsave(&udc->lock, flags); /* push the request to device */ if (ep_is_in(ep)) reval = ep_req_send(ep, req); @@ -1747,22 +1748,9 @@ static int __qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req) if (ep->dir == USB_DIR_OUT) reval = ep_req_receive(ep, req); - return 0; -} - -/* queues (submits) an I/O request to an endpoint */ -static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, - gfp_t gfp_flags) -{ - struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); - struct qe_udc *udc = ep->udc; - unsigned long flags; - int ret; - - spin_lock_irqsave(&udc->lock, flags); - ret = __qe_ep_queue(_ep, _req); spin_unlock_irqrestore(&udc->lock, flags); - return ret; + + return 0; } /* dequeues (cancels, unlinks) an I/O request from an endpoint */ @@ -2020,7 +2008,7 @@ static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value, udc->ep0_dir = USB_DIR_IN; /* data phase */ - status = __qe_ep_queue(&ep->ep, &req->req); + status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC); if (status == 0) return; @@ -2163,9 +2151,6 @@ static int reset_irq(struct qe_udc *udc) { unsigned char i; - if (udc->usb_state == USB_STATE_DEFAULT) - return 0; - qe_usb_disable(); out_8(&udc->usb_regs->usb_usadr, 0); @@ -2457,12 +2442,8 @@ static int __devinit qe_udc_reg_init(struct qe_udc *udc) struct usb_ctlr __iomem *qe_usbregs; qe_usbregs = udc->usb_regs; - /* Spec says that we must enable the USB controller to change mode. */ + /* Init the usb register */ out_8(&qe_usbregs->usb_usmod, 0x01); - /* Mode changed, now disable it, since muram isn't initialized yet. */ - out_8(&qe_usbregs->usb_usmod, 0x00); - - /* Initialize the rest. */ out_be16(&qe_usbregs->usb_usbmr, 0); out_8(&qe_usbregs->usb_uscom, 0); out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR); @@ -2623,10 +2604,6 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, (unsigned long)udc_controller); /* request irq and disable DR */ udc_controller->usb_irq = irq_of_parse_and_map(np, 0); - if (!udc_controller->usb_irq) { - ret = -EINVAL; - goto err_noirq; - } ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0, driver_name, udc_controller); @@ -2648,8 +2625,6 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, err6: free_irq(udc_controller->usb_irq, udc_controller); err5: - irq_dispose_mapping(udc_controller->usb_irq); -err_noirq: if (udc_controller->nullmap) { dma_unmap_single(udc_controller->gadget.dev.parent, udc_controller->nullp, 256, @@ -2673,7 +2648,7 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, iounmap(udc_controller->usb_regs); err1: kfree(udc_controller); - udc_controller = NULL; + return ret; } @@ -2735,7 +2710,6 @@ static int __devexit qe_udc_remove(struct of_device *ofdev) kfree(ep->txframe); free_irq(udc_controller->usb_irq, udc_controller); - irq_dispose_mapping(udc_controller->usb_irq); tasklet_kill(&udc_controller->rx_tasklet); diff --git a/trunk/drivers/usb/gadget/fsl_usb2_udc.c b/trunk/drivers/usb/gadget/fsl_usb2_udc.c index d8d9a52a44b3..f3c6703cffda 100644 --- a/trunk/drivers/usb/gadget/fsl_usb2_udc.c +++ b/trunk/drivers/usb/gadget/fsl_usb2_udc.c @@ -404,10 +404,7 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num, } if (zlt) tmp |= EP_QUEUE_HEAD_ZLT_SEL; - p_QH->max_pkt_length = cpu_to_le32(tmp); - p_QH->next_dtd_ptr = 1; - p_QH->size_ioc_int_sts = 0; return; } diff --git a/trunk/drivers/usb/gadget/pxa25x_udc.c b/trunk/drivers/usb/gadget/pxa25x_udc.c index 0ce4e2819847..9b36205c5759 100644 --- a/trunk/drivers/usb/gadget/pxa25x_udc.c +++ b/trunk/drivers/usb/gadget/pxa25x_udc.c @@ -904,8 +904,8 @@ static void pxa25x_ep_fifo_flush(struct usb_ep *_ep) /* most IN status is the same, but ISO can't stall */ *ep->reg_udccs = UDCCS_BI_TPC|UDCCS_BI_FTF|UDCCS_BI_TUR - | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC - ? 0 : UDCCS_BI_SST); + | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) + ? 0 : UDCCS_BI_SST; } diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index e551bb38852b..4725d15d096f 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -485,7 +485,6 @@ static int ehci_init(struct usb_hcd *hcd) * periodic_size can shrink by USBCMD update if hcc_params allows. */ ehci->periodic_size = DEFAULT_I_TDPS; - INIT_LIST_HEAD(&ehci->cached_itd_list); if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) return retval; @@ -498,7 +497,6 @@ static int ehci_init(struct usb_hcd *hcd) ehci->reclaim = NULL; ehci->next_uframe = -1; - ehci->clock_frame = -1; /* * dedicate a qh for the async ring head, since we couldn't unlink diff --git a/trunk/drivers/usb/host/ehci-mem.c b/trunk/drivers/usb/host/ehci-mem.c index 10d52919abbb..0431397836f6 100644 --- a/trunk/drivers/usb/host/ehci-mem.c +++ b/trunk/drivers/usb/host/ehci-mem.c @@ -128,7 +128,6 @@ static inline void qh_put (struct ehci_qh *qh) static void ehci_mem_cleanup (struct ehci_hcd *ehci) { - free_cached_itd_list(ehci); if (ehci->async) qh_put (ehci->async); ehci->async = NULL; diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index abb9a7706ec7..bb21fb0a4969 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -432,6 +432,7 @@ static struct pci_driver ehci_pci_driver = { #ifdef CONFIG_PM .suspend = usb_hcd_pci_suspend, + .resume_early = usb_hcd_pci_resume_early, .resume = usb_hcd_pci_resume, #endif .shutdown = usb_hcd_pci_shutdown, diff --git a/trunk/drivers/usb/host/ehci-sched.c b/trunk/drivers/usb/host/ehci-sched.c index 07bcb931021b..a081ee65bde6 100644 --- a/trunk/drivers/usb/host/ehci-sched.c +++ b/trunk/drivers/usb/host/ehci-sched.c @@ -1004,8 +1004,7 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream) is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0; stream->bEndpointAddress &= 0x0f; - if (stream->ep) - stream->ep->hcpriv = NULL; + stream->ep->hcpriv = NULL; if (stream->rescheduled) { ehci_info (ehci, "ep%d%s-iso rescheduled " @@ -1654,28 +1653,14 @@ itd_complete ( (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); } iso_stream_put (ehci, stream); - + /* OK to recycle this ITD now that its completion callback ran. */ done: usb_put_urb(urb); itd->urb = NULL; - if (ehci->clock_frame != itd->frame || itd->index[7] != -1) { - /* OK to recycle this ITD now. */ - itd->stream = NULL; - list_move(&itd->itd_list, &stream->free_list); - iso_stream_put(ehci, stream); - } else { - /* HW might remember this ITD, so we can't recycle it yet. - * Move it to a safe place until a new frame starts. - */ - list_move(&itd->itd_list, &ehci->cached_itd_list); - if (stream->refcount == 2) { - /* If iso_stream_put() were called here, stream - * would be freed. Instead, just prevent reuse. - */ - stream->ep->hcpriv = NULL; - stream->ep = NULL; - } - } + itd->stream = NULL; + list_move(&itd->itd_list, &stream->free_list); + iso_stream_put(ehci, stream); + return retval; } @@ -2116,20 +2101,6 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, /*-------------------------------------------------------------------------*/ -static void free_cached_itd_list(struct ehci_hcd *ehci) -{ - struct ehci_itd *itd, *n; - - list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) { - struct ehci_iso_stream *stream = itd->stream; - itd->stream = NULL; - list_move(&itd->itd_list, &stream->free_list); - iso_stream_put(ehci, stream); - } -} - -/*-------------------------------------------------------------------------*/ - static void scan_periodic (struct ehci_hcd *ehci) { @@ -2144,17 +2115,10 @@ scan_periodic (struct ehci_hcd *ehci) * Touches as few pages as possible: cache-friendly. */ now_uframe = ehci->next_uframe; - if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { + if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) clock = ehci_readl(ehci, &ehci->regs->frame_index); - clock_frame = (clock >> 3) % ehci->periodic_size; - } else { + else clock = now_uframe + mod - 1; - clock_frame = -1; - } - if (ehci->clock_frame != clock_frame) { - free_cached_itd_list(ehci); - ehci->clock_frame = clock_frame; - } clock %= mod; clock_frame = clock >> 3; @@ -2313,10 +2277,6 @@ scan_periodic (struct ehci_hcd *ehci) /* rescan the rest of this frame, then ... */ clock = now; clock_frame = clock >> 3; - if (ehci->clock_frame != clock_frame) { - free_cached_itd_list(ehci); - ehci->clock_frame = clock_frame; - } } else { now_uframe++; now_uframe %= mod; diff --git a/trunk/drivers/usb/host/ehci.h b/trunk/drivers/usb/host/ehci.h index 262b00c9b334..fb7054ccf4fc 100644 --- a/trunk/drivers/usb/host/ehci.h +++ b/trunk/drivers/usb/host/ehci.h @@ -87,10 +87,6 @@ struct ehci_hcd { /* one per controller */ int next_uframe; /* scan periodic, start here */ unsigned periodic_sched; /* periodic activity count */ - /* list of itds completed while clock_frame was still active */ - struct list_head cached_itd_list; - unsigned clock_frame; - /* per root hub port */ unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; @@ -224,8 +220,6 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) } } -static void free_cached_itd_list(struct ehci_hcd *ehci); - /*-------------------------------------------------------------------------*/ #include diff --git a/trunk/drivers/usb/host/ohci-pci.c b/trunk/drivers/usb/host/ohci-pci.c index f9961b4c0da3..5d625c3fd423 100644 --- a/trunk/drivers/usb/host/ohci-pci.c +++ b/trunk/drivers/usb/host/ohci-pci.c @@ -487,6 +487,7 @@ static struct pci_driver ohci_pci_driver = { #ifdef CONFIG_PM .suspend = usb_hcd_pci_suspend, + .resume_early = usb_hcd_pci_resume_early, .resume = usb_hcd_pci_resume, #endif diff --git a/trunk/drivers/usb/host/uhci-hcd.c b/trunk/drivers/usb/host/uhci-hcd.c index cf5e4cf7ea42..944f7e0ca4df 100644 --- a/trunk/drivers/usb/host/uhci-hcd.c +++ b/trunk/drivers/usb/host/uhci-hcd.c @@ -942,6 +942,7 @@ static struct pci_driver uhci_pci_driver = { #ifdef CONFIG_PM .suspend = usb_hcd_pci_suspend, + .resume_early = usb_hcd_pci_resume_early, .resume = usb_hcd_pci_resume, #endif /* PM */ }; diff --git a/trunk/drivers/usb/host/whci/asl.c b/trunk/drivers/usb/host/whci/asl.c index 958751ccea43..2291c5f5af51 100644 --- a/trunk/drivers/usb/host/whci/asl.c +++ b/trunk/drivers/usb/host/whci/asl.c @@ -227,13 +227,13 @@ void scan_async_work(struct work_struct *work) * Now that the ASL is updated, complete the removal of any * removed qsets. */ - spin_lock_irq(&whc->lock); + spin_lock(&whc->lock); list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) { qset_remove_complete(whc, qset); } - spin_unlock_irq(&whc->lock); + spin_unlock(&whc->lock); } /** diff --git a/trunk/drivers/usb/host/whci/pzl.c b/trunk/drivers/usb/host/whci/pzl.c index df8b85f07092..7dc85a0bee7c 100644 --- a/trunk/drivers/usb/host/whci/pzl.c +++ b/trunk/drivers/usb/host/whci/pzl.c @@ -255,13 +255,13 @@ void scan_periodic_work(struct work_struct *work) * Now that the PZL is updated, complete the removal of any * removed qsets. */ - spin_lock_irq(&whc->lock); + spin_lock(&whc->lock); list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) { qset_remove_complete(whc, qset); } - spin_unlock_irq(&whc->lock); + spin_unlock(&whc->lock); } /** diff --git a/trunk/drivers/usb/musb/davinci.c b/trunk/drivers/usb/musb/davinci.c index 2dc7606f319c..5a8fd5d57a11 100644 --- a/trunk/drivers/usb/musb/davinci.c +++ b/trunk/drivers/usb/musb/davinci.c @@ -377,8 +377,18 @@ int __init musb_platform_init(struct musb *musb) u32 revision; musb->mregs += DAVINCI_BASE_OFFSET; +#if 0 + /* REVISIT there's something odd about clocking, this + * didn't appear do the job ... + */ + musb->clock = clk_get(pDevice, "usb"); + if (IS_ERR(musb->clock)) + return PTR_ERR(musb->clock); - clk_enable(musb->clock); + status = clk_enable(musb->clock); + if (status < 0) + return -ENODEV; +#endif /* returns zero if e.g. not clocked */ revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); @@ -443,8 +453,5 @@ int musb_platform_exit(struct musb *musb) } phy_off(); - - clk_disable(musb->clock); - return 0; } diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index af77e4659006..2cc34fa05b73 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -115,7 +115,7 @@ unsigned musb_debug; -module_param_named(debug, musb_debug, uint, S_IRUGO | S_IWUSR); +module_param(musb_debug, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" @@ -767,7 +767,6 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, #ifdef CONFIG_USB_MUSB_HDRC_HCD case OTG_STATE_A_HOST: case OTG_STATE_A_SUSPEND: - usb_hcd_resume_root_hub(musb_to_hcd(musb)); musb_root_disconnect(musb); if (musb->a_wait_bcon != 0) musb_platform_try_idle(musb, jiffies @@ -1816,7 +1815,7 @@ static void musb_free(struct musb *musb) #ifdef CONFIG_SYSFS device_remove_file(musb->controller, &dev_attr_mode); device_remove_file(musb->controller, &dev_attr_vbus); -#ifdef CONFIG_USB_GADGET_MUSB_HDRC +#ifdef CONFIG_USB_MUSB_OTG device_remove_file(musb->controller, &dev_attr_srp); #endif #endif @@ -2064,7 +2063,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) #ifdef CONFIG_SYSFS device_remove_file(musb->controller, &dev_attr_mode); device_remove_file(musb->controller, &dev_attr_vbus); -#ifdef CONFIG_USB_GADGET_MUSB_HDRC +#ifdef CONFIG_USB_MUSB_OTG device_remove_file(musb->controller, &dev_attr_srp); #endif #endif @@ -2244,10 +2243,10 @@ static int __init musb_init(void) return platform_driver_probe(&musb_driver, musb_probe); } -/* make us init after usbcore and i2c (transceivers, regulators, etc) - * and before usb gadget and host-side drivers start to register +/* make us init after usbcore and before usb + * gadget and host-side drivers start to register */ -fs_initcall(musb_init); +subsys_initcall(musb_init); static void __exit musb_cleanup(void) { diff --git a/trunk/drivers/usb/musb/musb_gadget.c b/trunk/drivers/usb/musb/musb_gadget.c index c7ebd0867fcc..4ea305387981 100644 --- a/trunk/drivers/usb/musb/musb_gadget.c +++ b/trunk/drivers/usb/musb/musb_gadget.c @@ -575,7 +575,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) struct usb_request *request = &req->request; struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; void __iomem *epio = musb->endpoints[epnum].regs; - unsigned fifo_count = 0; + u16 fifo_count = 0; u16 len = musb_ep->packet_sz; csr = musb_readw(epio, MUSB_RXCSR); @@ -687,7 +687,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) len, fifo_count, musb_ep->packet_sz); - fifo_count = min_t(unsigned, len, fifo_count); + fifo_count = min(len, fifo_count); #ifdef CONFIG_USB_TUSB_OMAP_DMA if (tusb_dma_omap() && musb_ep->dma) { diff --git a/trunk/drivers/usb/musb/musb_host.c b/trunk/drivers/usb/musb/musb_host.c index 6dbbd0786a6a..a035ceccf950 100644 --- a/trunk/drivers/usb/musb/musb_host.c +++ b/trunk/drivers/usb/musb/musb_host.c @@ -335,11 +335,16 @@ musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb) static struct musb_qh * musb_giveback(struct musb_qh *qh, struct urb *urb, int status) { + int is_in; struct musb_hw_ep *ep = qh->hw_ep; struct musb *musb = ep->musb; - int is_in = usb_pipein(urb->pipe); int ready = qh->is_ready; + if (ep->is_shared_fifo) + is_in = 1; + else + is_in = usb_pipein(urb->pipe); + /* save toggle eagerly, for paranoia */ switch (qh->type) { case USB_ENDPOINT_XFER_BULK: @@ -427,7 +432,7 @@ musb_advance_schedule(struct musb *musb, struct urb *urb, else qh = musb_giveback(qh, urb, urb->status); - if (qh != NULL && qh->is_ready) { + if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) { DBG(4, "... next ep%d %cX urb %p\n", hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); @@ -937,8 +942,8 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) switch (musb->ep0_stage) { case MUSB_EP0_IN: fifo_dest = urb->transfer_buffer + urb->actual_length; - fifo_count = min_t(size_t, len, urb->transfer_buffer_length - - urb->actual_length); + fifo_count = min(len, ((u16) (urb->transfer_buffer_length + - urb->actual_length))); if (fifo_count < len) urb->status = -EOVERFLOW; @@ -971,9 +976,10 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) } /* FALLTHROUGH */ case MUSB_EP0_OUT: - fifo_count = min_t(size_t, qh->maxpacket, - urb->transfer_buffer_length - - urb->actual_length); + fifo_count = min(qh->maxpacket, ((u16) + (urb->transfer_buffer_length + - urb->actual_length))); + if (fifo_count) { fifo_dest = (u8 *) (urb->transfer_buffer + urb->actual_length); @@ -1155,8 +1161,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) struct urb *urb; struct musb_hw_ep *hw_ep = musb->endpoints + epnum; void __iomem *epio = hw_ep->regs; - struct musb_qh *qh = hw_ep->is_shared_fifo ? hw_ep->in_qh - : hw_ep->out_qh; + struct musb_qh *qh = hw_ep->out_qh; u32 status = 0; void __iomem *mbase = musb->mregs; struct dma_channel *dma; @@ -1303,8 +1308,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) * packets before updating TXCSR ... other docs disagree ... */ /* PIO: start next packet in this URB */ - if (wLength > qh->maxpacket) - wLength = qh->maxpacket; + wLength = min(qh->maxpacket, (u16) wLength); musb_write_fifo(hw_ep, wLength, buf); qh->segsize = wLength; @@ -1863,21 +1867,19 @@ static int musb_urb_enqueue( } qh->type_reg = type_reg; - /* Precompute RXINTERVAL/TXINTERVAL register */ + /* precompute rxinterval/txinterval register */ + interval = min((u8)16, epd->bInterval); /* log encoding */ switch (qh->type) { case USB_ENDPOINT_XFER_INT: - /* - * Full/low speeds use the linear encoding, - * high speed uses the logarithmic encoding. - */ - if (urb->dev->speed <= USB_SPEED_FULL) { - interval = max_t(u8, epd->bInterval, 1); - break; + /* fullspeed uses linear encoding */ + if (USB_SPEED_FULL == urb->dev->speed) { + interval = epd->bInterval; + if (!interval) + interval = 1; } /* FALLTHROUGH */ case USB_ENDPOINT_XFER_ISOC: - /* ISO always uses logarithmic encoding */ - interval = min_t(u8, epd->bInterval, 16); + /* iso always uses log encoding */ break; default: /* REVISIT we actually want to use NAK limits, hinting to the @@ -2035,9 +2037,9 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) goto done; /* Any URB not actively programmed into endpoint hardware can be - * immediately given back; that's any URB not at the head of an + * immediately given back. Such an URB must be at the head of its * endpoint queue, unless someday we get real DMA queues. And even - * if it's at the head, it might not be known to the hardware... + * then, it might not be known to the hardware... * * Otherwise abort current transfer, pending dma, etc.; urb->status * has already been updated. This is a synchronous abort; it'd be @@ -2076,15 +2078,6 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) qh->is_ready = 0; __musb_giveback(musb, urb, 0); qh->is_ready = ready; - - /* If nothing else (usually musb_giveback) is using it - * and its URB list has emptied, recycle this qh. - */ - if (ready && list_empty(&qh->hep->urb_list)) { - qh->hep->hcpriv = NULL; - list_del(&qh->ring); - kfree(qh); - } } else ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); done: @@ -2100,15 +2093,14 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) unsigned long flags; struct musb *musb = hcd_to_musb(hcd); u8 is_in = epnum & USB_DIR_IN; - struct musb_qh *qh; - struct urb *urb; + struct musb_qh *qh = hep->hcpriv; + struct urb *urb, *tmp; struct list_head *sched; - spin_lock_irqsave(&musb->lock, flags); + if (!qh) + return; - qh = hep->hcpriv; - if (qh == NULL) - goto exit; + spin_lock_irqsave(&musb->lock, flags); switch (qh->type) { case USB_ENDPOINT_XFER_CONTROL: @@ -2143,28 +2135,13 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) /* cleanup */ musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); + } else + urb = NULL; - /* Then nuke all the others ... and advance the - * queue on hw_ep (e.g. bulk ring) when we're done. - */ - while (!list_empty(&hep->urb_list)) { - urb = next_urb(qh); - urb->status = -ESHUTDOWN; - musb_advance_schedule(musb, urb, qh->hw_ep, is_in); - } - } else { - /* Just empty the queue; the hardware is busy with - * other transfers, and since !qh->is_ready nothing - * will activate any of these as it advances. - */ - while (!list_empty(&hep->urb_list)) - __musb_giveback(musb, next_urb(qh), -ESHUTDOWN); + /* then just nuke all the others */ + list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list) + musb_giveback(qh, urb, -ESHUTDOWN); - hep->hcpriv = NULL; - list_del(&qh->ring); - kfree(qh); - } -exit: spin_unlock_irqrestore(&musb->lock, flags); } diff --git a/trunk/drivers/usb/serial/aircable.c b/trunk/drivers/usb/serial/aircable.c index 6d106e74265e..537f953bd7f8 100644 --- a/trunk/drivers/usb/serial/aircable.c +++ b/trunk/drivers/usb/serial/aircable.c @@ -621,9 +621,9 @@ static int __init aircable_init(void) goto failed_usb_register; return 0; -failed_usb_register: - usb_serial_deregister(&aircable_device); failed_serial_register: + usb_serial_deregister(&aircable_device); +failed_usb_register: return retval; } diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index f92f4d773374..75597337583e 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -662,7 +662,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; @@ -1065,10 +1064,8 @@ static int set_serial_info(struct tty_struct *tty, if (!capable(CAP_SYS_ADMIN)) { if (((new_serial.flags & ~ASYNC_USR_MASK) != - (priv->flags & ~ASYNC_USR_MASK))) { - unlock_kernel(); + (priv->flags & ~ASYNC_USR_MASK))) return -EPERM; - } priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK)); priv->custom_divisor = new_serial.custom_divisor; diff --git a/trunk/drivers/usb/serial/ftdi_sio.h b/trunk/drivers/usb/serial/ftdi_sio.h index e300c840f8ca..1b62eff475d2 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.h +++ b/trunk/drivers/usb/serial/ftdi_sio.h @@ -844,9 +844,6 @@ #define TML_VID 0x1B91 /* Vendor ID */ #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ -/* NDI Polaris System */ -#define FTDI_NDI_HUC_PID 0xDA70 - /* Propox devices */ #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index b7c132bded7f..6c89da9c6fea 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -199,15 +199,14 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 /* FUTURE NOVATEL PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000 -#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 -#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001 -#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0X8000 -#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0X8001 -#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0X9000 -#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0X9001 -#define NOVATELWIRELESS_PRODUCT_GLOBAL 0XA001 +#define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000 +#define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000 +#define NOVATELWIRELESS_PRODUCT_EMBEDDED_1 0x8000 +#define NOVATELWIRELESS_PRODUCT_GLOBAL_1 0x9000 +#define NOVATELWIRELESS_PRODUCT_EVDO_2 0x6001 +#define NOVATELWIRELESS_PRODUCT_HSPA_2 0x7001 +#define NOVATELWIRELESS_PRODUCT_EMBEDDED_2 0x8001 +#define NOVATELWIRELESS_PRODUCT_GLOBAL_2 0x9001 /* AMOI PRODUCTS */ #define AMOI_VENDOR_ID 0x1614 @@ -217,27 +216,6 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po #define DELL_VENDOR_ID 0x413C -/* Dell modems */ -#define DELL_PRODUCT_5700_MINICARD 0x8114 -#define DELL_PRODUCT_5500_MINICARD 0x8115 -#define DELL_PRODUCT_5505_MINICARD 0x8116 -#define DELL_PRODUCT_5700_EXPRESSCARD 0x8117 -#define DELL_PRODUCT_5510_EXPRESSCARD 0x8118 - -#define DELL_PRODUCT_5700_MINICARD_SPRINT 0x8128 -#define DELL_PRODUCT_5700_MINICARD_TELUS 0x8129 - -#define DELL_PRODUCT_5720_MINICARD_VZW 0x8133 -#define DELL_PRODUCT_5720_MINICARD_SPRINT 0x8134 -#define DELL_PRODUCT_5720_MINICARD_TELUS 0x8135 -#define DELL_PRODUCT_5520_MINICARD_CINGULAR 0x8136 -#define DELL_PRODUCT_5520_MINICARD_GENERIC_L 0x8137 -#define DELL_PRODUCT_5520_MINICARD_GENERIC_I 0x8138 - -#define DELL_PRODUCT_5730_MINICARD_SPRINT 0x8180 -#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 -#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 - #define KYOCERA_VENDOR_ID 0x0c88 #define KYOCERA_PRODUCT_KPC650 0x17da #define KYOCERA_PRODUCT_KPC680 0x180a @@ -294,11 +272,13 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po /* Ericsson products */ #define ERICSSON_VENDOR_ID 0x0bdb -#define ERICSSON_PRODUCT_F3507G_1 0x1900 -#define ERICSSON_PRODUCT_F3507G_2 0x1902 +#define ERICSSON_PRODUCT_F3507G 0x1900 -#define BENQ_VENDOR_ID 0x04a5 -#define BENQ_PRODUCT_H10 0x4068 +/* Pantech products */ +#define PANTECH_VENDOR_ID 0x106c +#define PANTECH_PRODUCT_PC5740 0x3701 +#define PANTECH_PRODUCT_PC5750 0x3702 /* PX-500 */ +#define PANTECH_PRODUCT_UM150 0x3711 static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, @@ -415,37 +395,31 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, /* Novatel EVDO product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, /* Novatel HSPA product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, /* Novatel EVDO Embedded product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, /* Novatel HSPA Embedded product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL) }, /* Novatel Global product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_1) }, /* Novatel Global product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_2) }, /* Novatel EVDO product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_2) }, /* Novatel HSPA product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_2) }, /* Novatel Embedded product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_2) }, /* Novatel Global product */ { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) }, - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5505_MINICARD) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_EXPRESSCARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5510_EXPRESSCARD) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_SPRINT) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_TELUS) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_VZW) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_SPRINT) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_TELUS) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) }, /* Dell Wireless HSDPA 5520 */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, @@ -513,10 +487,10 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, - { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_1) }, - { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_2) }, - { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, - { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ + { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) }, + { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5740) }, + { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5750) }, + { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_UM150) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/trunk/drivers/usb/serial/ti_usb_3410_5052.c b/trunk/drivers/usb/serial/ti_usb_3410_5052.c index 2620bf6fe5e1..baf591137b80 100644 --- a/trunk/drivers/usb/serial/ti_usb_3410_5052.c +++ b/trunk/drivers/usb/serial/ti_usb_3410_5052.c @@ -176,7 +176,7 @@ static unsigned int product_5052_count; /* the array dimension is the number of default entries plus */ /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ /* null entry */ -static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = { +static struct usb_device_id ti_id_table_3410[7+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, @@ -185,11 +185,9 @@ static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, - { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, - { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, }; -static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { +static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, @@ -197,7 +195,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, }; -static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { +static struct usb_device_id ti_id_table_combined[6+2*TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, @@ -210,8 +208,6 @@ static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, - { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, - { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, { } }; diff --git a/trunk/drivers/usb/serial/ti_usb_3410_5052.h b/trunk/drivers/usb/serial/ti_usb_3410_5052.h index f323c6025858..b7ea5dbadee5 100644 --- a/trunk/drivers/usb/serial/ti_usb_3410_5052.h +++ b/trunk/drivers/usb/serial/ti_usb_3410_5052.h @@ -30,8 +30,6 @@ #define IBM_VENDOR_ID 0x04b3 #define TI_3410_PRODUCT_ID 0x3410 #define IBM_4543_PRODUCT_ID 0x4543 -#define IBM_454B_PRODUCT_ID 0x454b -#define IBM_454C_PRODUCT_ID 0x454c #define TI_3410_EZ430_ID 0xF430 /* TI ez430 development tool */ #define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */ #define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */ diff --git a/trunk/drivers/usb/storage/scsiglue.c b/trunk/drivers/usb/storage/scsiglue.c index 727c506417cc..2a42b862aa9f 100644 --- a/trunk/drivers/usb/storage/scsiglue.c +++ b/trunk/drivers/usb/storage/scsiglue.c @@ -64,7 +64,6 @@ */ #define VENDOR_ID_NOKIA 0x0421 #define VENDOR_ID_NIKON 0x04b0 -#define VENDOR_ID_PENTAX 0x0a17 #define VENDOR_ID_MOTOROLA 0x22b8 /*********************************************************************** @@ -159,7 +158,6 @@ static int slave_configure(struct scsi_device *sdev) switch (le16_to_cpu(us->pusb_dev->descriptor.idVendor)) { case VENDOR_ID_NOKIA: case VENDOR_ID_NIKON: - case VENDOR_ID_PENTAX: case VENDOR_ID_MOTOROLA: if (!(us->fflags & (US_FL_FIX_CAPACITY | US_FL_CAPACITY_OK))) diff --git a/trunk/drivers/usb/storage/transport.c b/trunk/drivers/usb/storage/transport.c index fb65d221cedf..1d5438e6363b 100644 --- a/trunk/drivers/usb/storage/transport.c +++ b/trunk/drivers/usb/storage/transport.c @@ -558,10 +558,32 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb) if (srb->result == SAM_STAT_GOOD && scsi_get_resid(srb) == 0) { - /* The command succeeded. We know this device doesn't - * have the last-sector bug, so stop checking it. + /* The command succeeded. If the capacity is odd + * (i.e., if the sector number is even) then the + * "always-even" heuristic would be wrong for this + * device. Issue a WARN() so that the kerneloops.org + * project will be notified and we will then know to + * mark the device with a CAPACITY_OK flag. Hopefully + * this will occur for only a few devices. + * + * Use the sign of us->last_sector_hacks to tell whether + * the warning has already been issued; we don't need + * more than one warning per device. */ - us->use_last_sector_hacks = 0; + if (!(sector & 1) && us->use_last_sector_hacks > 0) { + unsigned vid = le16_to_cpu( + us->pusb_dev->descriptor.idVendor); + unsigned pid = le16_to_cpu( + us->pusb_dev->descriptor.idProduct); + unsigned rev = le16_to_cpu( + us->pusb_dev->descriptor.bcdDevice); + + WARN(1, "%s: Successful last sector success at %u, " + "device %04x:%04x:%04x\n", + sdkp->disk->disk_name, sector, + vid, pid, rev); + us->use_last_sector_hacks = -1; + } } else { /* The command failed. Allow up to 3 retries in case this @@ -577,6 +599,14 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb) srb->result = SAM_STAT_CHECK_CONDITION; memcpy(srb->sense_buffer, record_not_found, sizeof(record_not_found)); + + /* In theory we might want to issue a WARN() here if the + * capacity is even, since it could indicate the device + * has the READ CAPACITY bug _and_ the real capacity is + * odd. But it could also indicate that the device + * simply can't access its last sector, a failure mode + * which is surprisingly common. So no warning. + */ } done: diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index 6f59c8e510ea..69269f739563 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -907,13 +907,13 @@ UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff, "Genesys Logic", "USB to IDE Optical", US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), + US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ), UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff, "Genesys Logic", "USB to IDE Disk", US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), + US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ), /* Reported by Ben Efros */ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451, @@ -1214,7 +1214,7 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff, "Datafab", "KECF-USB", US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ), + US_FL_FIX_INQUIRY ), /* Reported by Rauch Wolke */ UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff, @@ -1354,6 +1354,21 @@ UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), + +/* Submitted by Per Winkvist */ +UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, + "Pentax", + "Optio S/S4", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* Reported by Jaak Ristioja */ +UNUSUAL_DEV( 0x0a17, 0x006e, 0x0100, 0x0100, + "Pentax", + "K10D", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + /* These are virtual windows driver CDs, which the zd1211rw driver * automatically converts into WLAN devices. */ UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index fb19803060cf..f0267706cb45 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -1054,7 +1054,9 @@ config FB_RIVA_BACKLIGHT config FB_I810 tristate "Intel 810/815 support (EXPERIMENTAL)" - depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL + depends on FB && EXPERIMENTAL && PCI && X86_32 + select AGP + select AGP_INTEL select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -1117,7 +1119,9 @@ config FB_CARILLO_RANCH config FB_INTEL tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" - depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL + depends on FB && EXPERIMENTAL && PCI && X86 + select AGP + select AGP_INTEL select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/trunk/drivers/video/atafb.c b/trunk/drivers/video/atafb.c index 018850c116c6..8058572a7428 100644 --- a/trunk/drivers/video/atafb.c +++ b/trunk/drivers/video/atafb.c @@ -841,7 +841,7 @@ static int tt_detect(void) tt_dmasnd.ctrl = DMASND_CTRL_OFF; udelay(20); /* wait a while for things to settle down */ } - mono_moni = (st_mfp.par_dt_reg & 0x80) == 0; + mono_moni = (mfp.par_dt_reg & 0x80) == 0; tt_get_par(&par); tt_encode_var(&atafb_predefined[0], &par); @@ -2035,7 +2035,7 @@ static int stste_detect(void) tt_dmasnd.ctrl = DMASND_CTRL_OFF; udelay(20); /* wait a while for things to settle down */ } - mono_moni = (st_mfp.par_dt_reg & 0x80) == 0; + mono_moni = (mfp.par_dt_reg & 0x80) == 0; stste_get_par(&par); stste_encode_var(&atafb_predefined[0], &par); @@ -2086,20 +2086,20 @@ static void st_ovsc_switch(void) return; local_irq_save(flags); - st_mfp.tim_ct_b = 0x10; - st_mfp.active_edge |= 8; - st_mfp.tim_ct_b = 0; - st_mfp.tim_dt_b = 0xf0; - st_mfp.tim_ct_b = 8; - while (st_mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */ + mfp.tim_ct_b = 0x10; + mfp.active_edge |= 8; + mfp.tim_ct_b = 0; + mfp.tim_dt_b = 0xf0; + mfp.tim_ct_b = 8; + while (mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */ ; - new = st_mfp.tim_dt_b; + new = mfp.tim_dt_b; do { udelay(LINE_DELAY); old = new; - new = st_mfp.tim_dt_b; + new = mfp.tim_dt_b; } while (old != new); - st_mfp.tim_ct_b = 0x10; + mfp.tim_ct_b = 0x10; udelay(SYNC_DELAY); if (atari_switches & ATARI_SWITCH_OVSC_IKBD) diff --git a/trunk/drivers/video/aty/aty128fb.c b/trunk/drivers/video/aty/aty128fb.c index 2181ce4d7ebd..db16112cf197 100644 --- a/trunk/drivers/video/aty/aty128fb.c +++ b/trunk/drivers/video/aty/aty128fb.c @@ -1475,7 +1475,7 @@ static int aty128fb_set_par(struct fb_info *info) aty128_set_pll(&par->pll, par); aty128_set_fifo(&par->fifo_reg, par); - config = aty_ld_le32(CNFG_CNTL) & ~3; + config = aty_ld_le32(CONFIG_CNTL) & ~3; #if defined(__BIG_ENDIAN) if (par->crtc.bpp == 32) @@ -1484,7 +1484,7 @@ static int aty128fb_set_par(struct fb_info *info) config |= 1; /* make aperture do 16 bit swapping */ #endif - aty_st_le32(CNFG_CNTL, config); + aty_st_le32(CONFIG_CNTL, config); aty_st_8(CRTC_EXT_CNTL + 1, 0); /* turn the video back on */ info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3; @@ -1875,7 +1875,7 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i u32 dac; /* Get the chip revision */ - chip_rev = (aty_ld_le32(CNFG_CNTL) >> 16) & 0x1F; + chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F; strcpy(video_card, "Rage128 XX "); video_card[8] = ent->device >> 8; @@ -2057,7 +2057,7 @@ static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_ /* Grab memory size from the card */ // How does this relate to the resource length from the PCI hardware? - par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF; + par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF; /* Virtualize the framebuffer */ info->screen_base = ioremap(fb_addr, par->vram_size); @@ -2365,6 +2365,7 @@ static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx static void aty128_set_suspend(struct aty128fb_par *par, int suspend) { u32 pmgt; + u16 pwr_command; struct pci_dev *pdev = par->pdev; if (!par->pm_reg) @@ -2373,8 +2374,6 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend) /* Set the chip into the appropriate suspend mode (we use D2, * D3 would require a complete re-initialisation of the chip, * including PCI config registers, clocks, AGP configuration, ...) - * - * For resume, the core will have already brought us back to D0 */ if (suspend) { /* Make sure CRTC2 is reset. Remove that the day we decide to @@ -2392,9 +2391,17 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend) aty_st_le32(BUS_CNTL1, 0x00000010); aty_st_le32(MEM_POWER_MISC, 0x0c830000); mdelay(100); - + pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); /* Switch PCI power management to D2 */ - pci_set_power_state(pdev, PCI_D2); + pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, + (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2); + pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); + } else { + /* Switch back PCI power management to D0 */ + mdelay(100); + pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0); + pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); + mdelay(100); } } @@ -2403,12 +2410,6 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state) struct fb_info *info = pci_get_drvdata(pdev); struct aty128fb_par *par = info->par; - /* Because we may change PCI D state ourselves, we need to - * first save the config space content so the core can - * restore it properly on resume. - */ - pci_save_state(pdev); - /* We don't do anything but D2, for now we return 0, but * we may want to change that. How do we know if the BIOS * can properly take care of D3 ? Also, with swsusp, we @@ -2475,11 +2476,6 @@ static int aty128_do_resume(struct pci_dev *pdev) if (pdev->dev.power.power_state.event == PM_EVENT_ON) return 0; - /* PCI state will have been restored by the core, so - * we should be in D0 now with our config space fully - * restored - */ - /* Wakeup chip */ aty128_set_suspend(par, 0); par->asleep = 0; diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 1207c208a30b..cc6b470073da 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -135,7 +135,7 @@ #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \ defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT) static const u32 lt_lcd_regs[] = { - CNFG_PANEL_LG, + CONFIG_PANEL_LG, LCD_GEN_CNTL_LG, DSTN_CONTROL_LG, HFB_PITCH_ADDR_LG, @@ -446,7 +446,7 @@ static int __devinit correct_chipset(struct atyfb_par *par) par->pll_limits.ecp_max = aty_chips[i].ecp_max; par->features = aty_chips[i].features; - chip_id = aty_ld_le32(CNFG_CHIP_ID, par); + chip_id = aty_ld_le32(CONFIG_CHIP_ID, par); type = chip_id & CFG_CHIP_TYPE; rev = (chip_id & CFG_CHIP_REV) >> 24; @@ -629,7 +629,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) crtc->lcd_index = aty_ld_le32(LCD_INDEX, par); aty_st_le32(LCD_INDEX, crtc->lcd_index, par); } - crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par); + crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par); crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par); @@ -676,7 +676,7 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par); /* update non-shadow registers first */ - aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par); + aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par); aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); @@ -858,7 +858,7 @@ static int aty_var_to_crtc(const struct fb_info *info, if (!M64_HAS(MOBIL_BUS)) crtc->lcd_index |= CRTC2_DISPLAY_DIS; - crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par) | 0x4000; + crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000; crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT; crtc->lcd_gen_cntl &= @@ -1978,7 +1978,7 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par) return timeout ? 0 : -EIO; } -#endif /* CONFIG_PPC_PMAC */ +#endif static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) { @@ -2002,15 +2002,9 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) par->asleep = 1; par->lock_blank = 1; - /* Because we may change PCI D state ourselves, we need to - * first save the config space content so the core can - * restore it properly on resume. - */ - pci_save_state(pdev); - #ifdef CONFIG_PPC_PMAC /* Set chip to "suspend" mode */ - if (machine_is(powermac) && aty_power_mgmt(1, par)) { + if (aty_power_mgmt(1, par)) { par->asleep = 0; par->lock_blank = 0; atyfb_blank(FB_BLANK_UNBLANK, info); @@ -2053,15 +2047,11 @@ static int atyfb_pci_resume(struct pci_dev *pdev) acquire_console_sem(); - /* PCI state will have been restored by the core, so - * we should be in D0 now with our config space fully - * restored - */ - #ifdef CONFIG_PPC_PMAC - if (machine_is(powermac) && - pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) + if (pdev->dev.power.power_state.event == 2) aty_power_mgmt(0, par); +#else + pci_set_power_state(pdev, PCI_D0); #endif aty_resume_chip(info); @@ -2264,7 +2254,7 @@ static int __devinit aty_init(struct fb_info *info) if (!M64_HAS(INTEGRATED)) { u32 stat0; u8 dac_type, dac_subtype, clk_type; - stat0 = aty_ld_le32(CNFG_STAT0, par); + stat0 = aty_ld_le32(CONFIG_STAT0, par); par->bus_type = (stat0 >> 0) & 0x07; par->ram_type = (stat0 >> 3) & 0x07; ramname = aty_gx_ram[par->ram_type]; @@ -2334,7 +2324,7 @@ static int __devinit aty_init(struct fb_info *info) par->dac_ops = &aty_dac_ct; par->pll_ops = &aty_pll_ct; par->bus_type = PCI; - par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); + par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07); ramname = aty_ct_ram[par->ram_type]; /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) @@ -2443,7 +2433,7 @@ static int __devinit aty_init(struct fb_info *info) } if (M64_HAS(MAGIC_VRAM_SIZE)) { - if (aty_ld_le32(CNFG_STAT1, par) & 0x40000000) + if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000) info->fix.smem_len += 0x400000; } @@ -2956,7 +2946,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, * Fix PROMs idea of MEM_CNTL settings... */ mem = aty_ld_le32(MEM_CNTL, par); - chip_id = aty_ld_le32(CNFG_CHIP_ID, par); + chip_id = aty_ld_le32(CONFIG_CHIP_ID, par); if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) { switch (mem & 0x0f) { case 3: @@ -2974,7 +2964,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, default: break; } - if ((aty_ld_le32(CNFG_STAT0, par) & 7) >= SDRAM) + if ((aty_ld_le32(CONFIG_STAT0, par) & 7) >= SDRAM) mem &= ~(0x00700000); } mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */ @@ -3582,7 +3572,7 @@ static int __init atyfb_atari_probe(void) } /* Fake pci_id for correct_chipset() */ - switch (aty_ld_le32(CNFG_CHIP_ID, par) & CFG_CHIP_TYPE) { + switch (aty_ld_le32(CONFIG_CHIP_ID, par) & CFG_CHIP_TYPE) { case 0x00d7: par->pci_id = PCI_CHIP_MACH64GX; break; diff --git a/trunk/drivers/video/aty/radeon_base.c b/trunk/drivers/video/aty/radeon_base.c index 16bb7e3c0310..d0f1a7fc2c9d 100644 --- a/trunk/drivers/video/aty/radeon_base.c +++ b/trunk/drivers/video/aty/radeon_base.c @@ -1936,8 +1936,8 @@ static void fixup_memory_mappings(struct radeonfb_info *rinfo) OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B); mdelay(100); - aper_base = INREG(CNFG_APER_0_BASE); - aper_size = INREG(CNFG_APER_SIZE); + aper_base = INREG(CONFIG_APER_0_BASE); + aper_size = INREG(CONFIG_APER_SIZE); #ifdef SET_MC_FB_FROM_APERTURE /* Set framebuffer to be at the same address as set in PCI BAR */ @@ -2024,11 +2024,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo) ~CRTC_H_CUTOFF_ACTIVE_EN); } } else { - tmp = INREG(CNFG_MEMSIZE); + tmp = INREG(CONFIG_MEMSIZE); } /* mem size is bits [28:0], mask off the rest */ - rinfo->video_ram = tmp & CNFG_MEMSIZE_MASK; + rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; /* * Hack to get around some busted production M6's @@ -2228,7 +2228,7 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev, */ rinfo->errata = 0; if (rinfo->family == CHIP_FAMILY_R300 && - (INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) + (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) == CFG_ATI_REV_A11) rinfo->errata |= CHIP_ERRATA_R300_CG; diff --git a/trunk/drivers/video/aty/radeon_pm.c b/trunk/drivers/video/aty/radeon_pm.c index ca5f0dc28546..675abdafc2d8 100644 --- a/trunk/drivers/video/aty/radeon_pm.c +++ b/trunk/drivers/video/aty/radeon_pm.c @@ -333,7 +333,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo) if (!rinfo->has_CRTC2) { tmp = INPLL(pllSCLK_CNTL); - if ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13) + if ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13) tmp &= ~(SCLK_CNTL__FORCE_CP | SCLK_CNTL__FORCE_RB); tmp &= ~(SCLK_CNTL__FORCE_HDP | SCLK_CNTL__FORCE_DISP1 | SCLK_CNTL__FORCE_TOP | SCLK_CNTL__FORCE_SE | @@ -468,9 +468,9 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo) /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/ if ((rinfo->family == CHIP_FAMILY_RV250 && - ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) || + ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) || ((rinfo->family == CHIP_FAMILY_RV100) && - ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) { + ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) { tmp |= SCLK_CNTL__FORCE_CP; tmp |= SCLK_CNTL__FORCE_VIP; } @@ -486,7 +486,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo) /* RV200::A11 A12 RV250::A11 A12 */ if (((rinfo->family == CHIP_FAMILY_RV200) || (rinfo->family == CHIP_FAMILY_RV250)) && - ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) + ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) tmp |= SCLK_MORE_CNTL__FORCEON; OUTPLL(pllSCLK_MORE_CNTL, tmp); @@ -497,7 +497,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo) /* RV200::A11 A12, RV250::A11 A12 */ if (((rinfo->family == CHIP_FAMILY_RV200) || (rinfo->family == CHIP_FAMILY_RV250)) && - ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) { + ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) { tmp = INPLL(pllPLL_PWRMGT_CNTL); tmp |= PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE; OUTPLL(pllPLL_PWRMGT_CNTL, tmp); @@ -702,7 +702,7 @@ static void radeon_pm_restore_regs(struct radeonfb_info *rinfo) OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]); OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]); OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]); - OUTREG(CNFG_MEMSIZE, rinfo->video_ram); + OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]); OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]); @@ -1723,7 +1723,7 @@ static void radeon_reinitialize_M10(struct radeonfb_info *rinfo) OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]); OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]); OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]); - OUTREG(CNFG_MEMSIZE, rinfo->video_ram); + OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); OUTREG(BUS_CNTL, rinfo->save_regs[36]); OUTREG(BUS_CNTL1, rinfo->save_regs[14]); OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]); @@ -1961,7 +1961,7 @@ static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo) OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, rinfo->save_regs[68] /*0x141555ff*/); OUTMC(rinfo, ixMC_IMP_CNTL_0, rinfo->save_regs[71] /*0x00009249*/); OUTREG(MC_IND_INDEX, 0); - OUTREG(CNFG_MEMSIZE, rinfo->video_ram); + OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); mdelay(20); } @@ -2361,7 +2361,7 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo) OUTMC(rinfo, ixMC_IMP_CNTL_0, 0x00009249); OUTREG(MC_IND_INDEX, 0); - OUTREG(CNFG_MEMSIZE, rinfo->video_ram); + OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); radeon_pm_full_reset_sdram(rinfo); @@ -2509,7 +2509,9 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo) static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) { + u16 pwr_cmd; u32 tmp; + int i; if (!rinfo->pm_reg) return; @@ -2555,14 +2557,32 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) } } + for (i = 0; i < 64; ++i) + pci_read_config_dword(rinfo->pdev, i * 4, + &rinfo->cfg_save[i]); + /* Switch PCI power management to D2. */ pci_disable_device(rinfo->pdev); - pci_save_state(rinfo->pdev); - pci_set_power_state(rinfo->pdev, PCI_D2); + for (;;) { + pci_read_config_word( + rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, + &pwr_cmd); + if (pwr_cmd & 2) + break; + pci_write_config_word( + rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, + (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2); + mdelay(500); + } } else { printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n", pci_name(rinfo->pdev)); + /* Switch back PCI powermanagment to D0 */ + mdelay(200); + pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0); + mdelay(500); + if (rinfo->family <= CHIP_FAMILY_RV250) { /* Reset the SDRAM controller */ radeon_pm_full_reset_sdram(rinfo); @@ -2578,10 +2598,37 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) } } +static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo) +{ + int i; + static u32 radeon_cfg_after_resume[64]; + + for (i = 0; i < 64; ++i) + pci_read_config_dword(rinfo->pdev, i * 4, + &radeon_cfg_after_resume[i]); + + if (radeon_cfg_after_resume[PCI_BASE_ADDRESS_0/4] + == rinfo->cfg_save[PCI_BASE_ADDRESS_0/4]) + return 0; /* assume everything is ok */ + + for (i = PCI_BASE_ADDRESS_0/4; i < 64; ++i) { + if (radeon_cfg_after_resume[i] != rinfo->cfg_save[i]) + pci_write_config_dword(rinfo->pdev, i * 4, + rinfo->cfg_save[i]); + } + pci_write_config_word(rinfo->pdev, PCI_CACHE_LINE_SIZE, + rinfo->cfg_save[PCI_CACHE_LINE_SIZE/4]); + pci_write_config_word(rinfo->pdev, PCI_COMMAND, + rinfo->cfg_save[PCI_COMMAND/4]); + return 1; +} + + int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) { struct fb_info *info = pci_get_drvdata(pdev); struct radeonfb_info *rinfo = info->par; + int i; if (mesg.event == pdev->dev.power.power_state.event) return 0; @@ -2627,11 +2674,6 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) pmac_suspend_agp_for_card(pdev); #endif /* CONFIG_PPC_PMAC */ - /* It's unclear whether or when the generic code will do that, so let's - * do it ourselves. We save state before we do any power management - */ - pci_save_state(pdev); - /* If we support wakeup from poweroff, we save all regs we can including cfg * space */ @@ -2656,6 +2698,9 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) mdelay(20); OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_DIGON)); } + // FIXME: Use PCI layer + for (i = 0; i < 64; ++i) + pci_read_config_dword(pdev, i * 4, &rinfo->cfg_save[i]); pci_disable_device(pdev); } /* If we support D2, we go to it (should be fixed later with a flag forcing @@ -2672,13 +2717,6 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) return 0; } -static int radeon_check_power_loss(struct radeonfb_info *rinfo) -{ - return rinfo->save_regs[4] != INPLL(CLK_PIN_CNTL) || - rinfo->save_regs[2] != INPLL(MCLK_CNTL) || - rinfo->save_regs[3] != INPLL(SCLK_CNTL); -} - int radeonfb_pci_resume(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); @@ -2697,13 +2735,20 @@ int radeonfb_pci_resume(struct pci_dev *pdev) printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n", pci_name(pdev), pdev->dev.power.power_state.event); - /* PCI state will have been restored by the core, so - * we should be in D0 now with our config space fully - * restored - */ + + if (pci_enable_device(pdev)) { + rc = -ENODEV; + printk(KERN_ERR "radeonfb (%s): can't enable PCI device !\n", + pci_name(pdev)); + goto bail; + } + pci_set_master(pdev); + if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { - /* Wakeup chip */ - if ((rinfo->pm_mode & radeon_pm_off) && radeon_check_power_loss(rinfo)) { + /* Wakeup chip. Check from config space if we were powered off + * (todo: additionally, check CLK_PIN_CNTL too) + */ + if ((rinfo->pm_mode & radeon_pm_off) && radeon_restore_pci_cfg(rinfo)) { if (rinfo->reinit_func != NULL) rinfo->reinit_func(rinfo); else { diff --git a/trunk/drivers/video/aty/radeonfb.h b/trunk/drivers/video/aty/radeonfb.h index 7351e66c7f54..3ea1b00fdd22 100644 --- a/trunk/drivers/video/aty/radeonfb.h +++ b/trunk/drivers/video/aty/radeonfb.h @@ -361,6 +361,8 @@ struct radeonfb_info { #ifdef CONFIG_FB_RADEON_I2C struct radeon_i2c_chan i2c[4]; #endif + + u32 cfg_save[64]; }; diff --git a/trunk/drivers/video/backlight/Makefile b/trunk/drivers/video/backlight/Makefile index 63d759498165..363b3cb2f01b 100644 --- a/trunk/drivers/video/backlight/Makefile +++ b/trunk/drivers/video/backlight/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o -obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o +obj-$(CONFIG_BACKLIGHT_DA903X) += da903x.o obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o diff --git a/trunk/drivers/video/backlight/da903x_bl.c b/trunk/drivers/video/backlight/da903x.c similarity index 100% rename from trunk/drivers/video/backlight/da903x_bl.c rename to trunk/drivers/video/backlight/da903x.c diff --git a/trunk/drivers/video/bfin-t350mcqb-fb.c b/trunk/drivers/video/bfin-t350mcqb-fb.c index 90cfddabf1f7..2a423d3a2a8e 100644 --- a/trunk/drivers/video/bfin-t350mcqb-fb.c +++ b/trunk/drivers/video/bfin-t350mcqb-fb.c @@ -447,7 +447,7 @@ static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) +static int __init bfin_t350mcqb_probe(struct platform_device *pdev) { struct bfin_t350mcqbfb_info *info; struct fb_info *fbinfo; diff --git a/trunk/drivers/video/fbcmap.c b/trunk/drivers/video/fbcmap.c index f53b9f1d6aba..91b78e691505 100644 --- a/trunk/drivers/video/fbcmap.c +++ b/trunk/drivers/video/fbcmap.c @@ -250,6 +250,10 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) int rc, size = cmap->len * sizeof(u16); struct fb_cmap umap; + if (cmap->start < 0 || (!info->fbops->fb_setcolreg && + !info->fbops->fb_setcmap)) + return -EINVAL; + memset(&umap, 0, sizeof(struct fb_cmap)); rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL); if (rc) @@ -258,23 +262,11 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) copy_from_user(umap.green, cmap->green, size) || copy_from_user(umap.blue, cmap->blue, size) || (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) { - rc = -EFAULT; - goto out; + fb_dealloc_cmap(&umap); + return -EFAULT; } umap.start = cmap->start; - if (!lock_fb_info(info)) { - rc = -ENODEV; - goto out; - } - if (cmap->start < 0 || (!info->fbops->fb_setcolreg && - !info->fbops->fb_setcmap)) { - rc = -EINVAL; - goto out1; - } rc = fb_set_cmap(&umap, info); -out1: - unlock_fb_info(info); -out: fb_dealloc_cmap(&umap); return rc; } diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index cfd9dce1ce0b..756efeb91abc 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -1013,139 +1013,132 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; struct fb_con2fbmap con2fb; - struct fb_cmap cmap_from; struct fb_cmap_user cmap; struct fb_event event; void __user *argp = (void __user *)arg; long ret = 0; + fb = info->fbops; + if (!fb) + return -ENODEV; + switch (cmd) { case FBIOGET_VSCREENINFO: - if (!lock_fb_info(info)) - return -ENODEV; - var = info->var; - unlock_fb_info(info); - - ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0; + ret = copy_to_user(argp, &info->var, + sizeof(var)) ? -EFAULT : 0; break; case FBIOPUT_VSCREENINFO: - if (copy_from_user(&var, argp, sizeof(var))) - return -EFAULT; - if (!lock_fb_info(info)) - return -ENODEV; + if (copy_from_user(&var, argp, sizeof(var))) { + ret = -EFAULT; + break; + } acquire_console_sem(); info->flags |= FBINFO_MISC_USEREVENT; ret = fb_set_var(info, &var); info->flags &= ~FBINFO_MISC_USEREVENT; release_console_sem(); - unlock_fb_info(info); - if (!ret && copy_to_user(argp, &var, sizeof(var))) + if (ret == 0 && copy_to_user(argp, &var, sizeof(var))) ret = -EFAULT; break; case FBIOGET_FSCREENINFO: - if (!lock_fb_info(info)) - return -ENODEV; - fix = info->fix; - unlock_fb_info(info); - - ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0; + ret = copy_to_user(argp, &info->fix, + sizeof(fix)) ? -EFAULT : 0; break; case FBIOPUTCMAP: if (copy_from_user(&cmap, argp, sizeof(cmap))) - return -EFAULT; - ret = fb_set_user_cmap(&cmap, info); + ret = -EFAULT; + else + ret = fb_set_user_cmap(&cmap, info); break; case FBIOGETCMAP: if (copy_from_user(&cmap, argp, sizeof(cmap))) - return -EFAULT; - if (!lock_fb_info(info)) - return -ENODEV; - cmap_from = info->cmap; - unlock_fb_info(info); - ret = fb_cmap_to_user(&cmap_from, &cmap); + ret = -EFAULT; + else + ret = fb_cmap_to_user(&info->cmap, &cmap); break; case FBIOPAN_DISPLAY: - if (copy_from_user(&var, argp, sizeof(var))) - return -EFAULT; - if (!lock_fb_info(info)) - return -ENODEV; + if (copy_from_user(&var, argp, sizeof(var))) { + ret = -EFAULT; + break; + } acquire_console_sem(); ret = fb_pan_display(info, &var); release_console_sem(); - unlock_fb_info(info); if (ret == 0 && copy_to_user(argp, &var, sizeof(var))) - return -EFAULT; + ret = -EFAULT; break; case FBIO_CURSOR: ret = -EINVAL; break; case FBIOGET_CON2FBMAP: if (copy_from_user(&con2fb, argp, sizeof(con2fb))) - return -EFAULT; - if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) - return -EINVAL; - con2fb.framebuffer = -1; - event.data = &con2fb; - - if (!lock_fb_info(info)) - return -ENODEV; - event.info = info; - fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); - unlock_fb_info(info); - - ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; + ret = -EFAULT; + else if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) + ret = -EINVAL; + else { + con2fb.framebuffer = -1; + event.info = info; + event.data = &con2fb; + fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, + &event); + ret = copy_to_user(argp, &con2fb, + sizeof(con2fb)) ? -EFAULT : 0; + } break; case FBIOPUT_CON2FBMAP: - if (copy_from_user(&con2fb, argp, sizeof(con2fb))) - return -EFAULT; - if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) - return -EINVAL; - if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) - return -EINVAL; + if (copy_from_user(&con2fb, argp, sizeof(con2fb))) { + ret = -EFAULT; + break; + } + if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) { + ret = -EINVAL; + break; + } + if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) { + ret = -EINVAL; + break; + } if (!registered_fb[con2fb.framebuffer]) request_module("fb%d", con2fb.framebuffer); if (!registered_fb[con2fb.framebuffer]) { ret = -EINVAL; break; } - event.data = &con2fb; - if (!lock_fb_info(info)) - return -ENODEV; event.info = info; + event.data = &con2fb; ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); - unlock_fb_info(info); break; case FBIOBLANK: - if (!lock_fb_info(info)) - return -ENODEV; acquire_console_sem(); info->flags |= FBINFO_MISC_USEREVENT; ret = fb_blank(info, arg); info->flags &= ~FBINFO_MISC_USEREVENT; release_console_sem(); - unlock_fb_info(info); - break; + break;; default: - if (!lock_fb_info(info)) - return -ENODEV; - fb = info->fbops; - if (fb->fb_ioctl) - ret = fb->fb_ioctl(info, cmd, arg); - else + if (fb->fb_ioctl == NULL) ret = -ENOTTY; - unlock_fb_info(info); + else + ret = fb->fb_ioctl(info, cmd, arg); } return ret; } static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +__acquires(&info->lock) +__releases(&info->lock) { struct inode *inode = file->f_path.dentry->d_inode; int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; + struct fb_info *info; + long ret; - return do_fb_ioctl(info, cmd, arg); + info = registered_fb[fbidx]; + mutex_lock(&info->lock); + ret = do_fb_ioctl(info, cmd, arg); + mutex_unlock(&info->lock); + return ret; } #ifdef CONFIG_COMPAT @@ -1264,6 +1257,8 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, static long fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +__acquires(&info->lock) +__releases(&info->lock) { struct inode *inode = file->f_path.dentry->d_inode; int fbidx = iminor(inode); @@ -1271,6 +1266,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, struct fb_ops *fb = info->fbops; long ret = -ENOIOCTLCMD; + mutex_lock(&info->lock); switch(cmd) { case FBIOGET_VSCREENINFO: case FBIOPUT_VSCREENINFO: @@ -1296,6 +1292,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, ret = fb->fb_compat_ioctl(info, cmd, arg); break; } + mutex_unlock(&info->lock); return ret; } #endif diff --git a/trunk/drivers/video/geode/gx1fb_core.c b/trunk/drivers/video/geode/gx1fb_core.c index f20eff8c4a81..751e491ca8c8 100644 --- a/trunk/drivers/video/geode/gx1fb_core.c +++ b/trunk/drivers/video/geode/gx1fb_core.c @@ -136,10 +136,13 @@ static int gx1fb_set_par(struct fb_info *info) { struct geodefb_par *par = info->par; - if (info->var.bits_per_pixel == 16) + if (info->var.bits_per_pixel == 16) { info->fix.visual = FB_VISUAL_TRUECOLOR; - else + fb_dealloc_cmap(&info->cmap); + } else { info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + fb_alloc_cmap(&info->cmap, 1<var.bits_per_pixel, 0); + } info->fix.line_length = gx1_line_delta(info->var.xres, info->var.bits_per_pixel); @@ -312,10 +315,6 @@ static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev) if (!par->panel_x) par->enable_crt = 1; /* fall back to CRT if no panel is specified */ - if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { - framebuffer_release(info); - return NULL; - } return info; } @@ -375,11 +374,8 @@ static int __init gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id * release_mem_region(gx1_gx_base() + 0x8300, 0x100); } - if (info) { - fb_dealloc_cmap(&info->cmap); + if (info) framebuffer_release(info); - } - return ret; } @@ -399,7 +395,6 @@ static void gx1fb_remove(struct pci_dev *pdev) iounmap(par->dc_regs); release_mem_region(gx1_gx_base() + 0x8300, 0x100); - fb_dealloc_cmap(&info->cmap); pci_set_drvdata(pdev, NULL); framebuffer_release(info); diff --git a/trunk/drivers/video/geode/gxfb_core.c b/trunk/drivers/video/geode/gxfb_core.c index 2552cac39e1c..484118926318 100644 --- a/trunk/drivers/video/geode/gxfb_core.c +++ b/trunk/drivers/video/geode/gxfb_core.c @@ -171,10 +171,13 @@ static int gxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) static int gxfb_set_par(struct fb_info *info) { - if (info->var.bits_per_pixel > 8) + if (info->var.bits_per_pixel > 8) { info->fix.visual = FB_VISUAL_TRUECOLOR; - else + fb_dealloc_cmap(&info->cmap); + } else { info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + fb_alloc_cmap(&info->cmap, 1<var.bits_per_pixel, 0); + } info->fix.line_length = gx_line_delta(info->var.xres, info->var.bits_per_pixel); @@ -328,11 +331,6 @@ static struct fb_info * __init gxfb_init_fbinfo(struct device *dev) info->var.grayscale = 0; - if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { - framebuffer_release(info); - return NULL; - } - return info; } @@ -445,10 +443,8 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i pci_release_region(pdev, 1); } - if (info) { - fb_dealloc_cmap(&info->cmap); + if (info) framebuffer_release(info); - } return ret; } @@ -471,7 +467,6 @@ static void gxfb_remove(struct pci_dev *pdev) iounmap(par->gp_regs); pci_release_region(pdev, 1); - fb_dealloc_cmap(&info->cmap); pci_set_drvdata(pdev, NULL); framebuffer_release(info); diff --git a/trunk/drivers/video/geode/lxfb_core.c b/trunk/drivers/video/geode/lxfb_core.c index 889cbe39e580..b965ecdbc604 100644 --- a/trunk/drivers/video/geode/lxfb_core.c +++ b/trunk/drivers/video/geode/lxfb_core.c @@ -278,10 +278,13 @@ static int lxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) static int lxfb_set_par(struct fb_info *info) { - if (info->var.bits_per_pixel > 8) + if (info->var.bits_per_pixel > 8) { info->fix.visual = FB_VISUAL_TRUECOLOR; - else + fb_dealloc_cmap(&info->cmap); + } else { info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + fb_alloc_cmap(&info->cmap, 1<var.bits_per_pixel, 0); + } info->fix.line_length = lx_get_pitch(info->var.xres, info->var.bits_per_pixel); @@ -448,11 +451,6 @@ static struct fb_info * __init lxfb_init_fbinfo(struct device *dev) info->pseudo_palette = (void *)par + sizeof(struct lxfb_par); - if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { - framebuffer_release(info); - return NULL; - } - info->var.grayscale = 0; return info; @@ -581,10 +579,8 @@ static int __init lxfb_probe(struct pci_dev *pdev, pci_release_region(pdev, 3); } - if (info) { - fb_dealloc_cmap(&info->cmap); + if (info) framebuffer_release(info); - } return ret; } @@ -608,7 +604,6 @@ static void lxfb_remove(struct pci_dev *pdev) iounmap(par->vp_regs); pci_release_region(pdev, 3); - fb_dealloc_cmap(&info->cmap); pci_set_drvdata(pdev, NULL); framebuffer_release(info); } diff --git a/trunk/drivers/w1/slaves/Kconfig b/trunk/drivers/w1/slaves/Kconfig index 1f51366417b9..8d0b1fb1e52e 100644 --- a/trunk/drivers/w1/slaves/Kconfig +++ b/trunk/drivers/w1/slaves/Kconfig @@ -16,12 +16,6 @@ config W1_SLAVE_SMEM Say Y here if you want to connect 1-wire simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire. -config W1_SLAVE_DS2431 - tristate "1kb EEPROM family support (DS2431)" - help - Say Y here if you want to use a 1-wire - 1kb EEPROM family device (DS2431) - config W1_SLAVE_DS2433 tristate "4kb EEPROM family support (DS2433)" help diff --git a/trunk/drivers/w1/slaves/Makefile b/trunk/drivers/w1/slaves/Makefile index f1f51f19b129..990f400b6d22 100644 --- a/trunk/drivers/w1/slaves/Makefile +++ b/trunk/drivers/w1/slaves/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o -obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o diff --git a/trunk/drivers/w1/slaves/w1_ds2433.c b/trunk/drivers/w1/slaves/w1_ds2433.c index 139447148822..858c16a544c2 100644 --- a/trunk/drivers/w1/slaves/w1_ds2433.c +++ b/trunk/drivers/w1/slaves/w1_ds2433.c @@ -156,9 +156,6 @@ static ssize_t w1_f23_read_bin(struct kobject *kobj, */ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data) { -#ifdef CONFIG_W1_SLAVE_DS2433_CRC - struct w1_f23_data *f23 = sl->family_data; -#endif u8 wrbuf[4]; u8 rdbuf[W1_PAGE_SIZE + 3]; u8 es = (addr + len - 1) & 0x1f; @@ -199,9 +196,7 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data) /* Reset the bus to wake up the EEPROM (this may not be needed) */ w1_reset_bus(sl->master); -#ifdef CONFIG_W1_SLAVE_DS2433_CRC - f23->validcrc &= ~(1 << (addr >> W1_PAGE_BITS)); -#endif + return 0; } diff --git a/trunk/drivers/w1/slaves/w1_therm.c b/trunk/drivers/w1/slaves/w1_therm.c index 1ed3d554e372..2c8dff9f77da 100644 --- a/trunk/drivers/w1/slaves/w1_therm.c +++ b/trunk/drivers/w1/slaves/w1_therm.c @@ -115,7 +115,7 @@ static struct w1_therm_family_converter w1_therm_families[] = { static inline int w1_DS18B20_convert_temp(u8 rom[9]) { - int t = ((s16)rom[1] << 8) | rom[0]; + s16 t = (rom[1] << 8) | rom[0]; t = t*1000/16; return t; } diff --git a/trunk/drivers/watchdog/Kconfig b/trunk/drivers/watchdog/Kconfig index 325c10ff6a2c..09a3d5522b43 100644 --- a/trunk/drivers/watchdog/Kconfig +++ b/trunk/drivers/watchdog/Kconfig @@ -406,7 +406,7 @@ config ITCO_WDT ---help--- Hardware driver for the intel TCO timer based watchdog devices. These drivers are included in the Intel 82801 I/O Controller - Hub family (from ICH0 up to ICH10) and in the Intel 63xxESB + Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB controller hub. The TCO (Total Cost of Ownership) timer is a watchdog timer diff --git a/trunk/drivers/watchdog/at91rm9200_wdt.c b/trunk/drivers/watchdog/at91rm9200_wdt.c index e35d54589232..5531691f46ea 100644 --- a/trunk/drivers/watchdog/at91rm9200_wdt.c +++ b/trunk/drivers/watchdog/at91rm9200_wdt.c @@ -107,10 +107,10 @@ static int at91_wdt_close(struct inode *inode, struct file *file) static int at91_wdt_settimeout(int new_time) { /* - * All counting occurs at SLOW_CLOCK / 128 = 256 Hz + * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz * * Since WDV is a 16-bit counter, the maximum period is - * 65536 / 256 = 256 seconds. + * 65536 / 0.256 = 256 seconds. */ if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) return -EINVAL; diff --git a/trunk/drivers/watchdog/at91sam9_wdt.c b/trunk/drivers/watchdog/at91sam9_wdt.c index a56ac84381b1..b1da287f90ec 100644 --- a/trunk/drivers/watchdog/at91sam9_wdt.c +++ b/trunk/drivers/watchdog/at91sam9_wdt.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/watchdog/iTCO_vendor_support.c b/trunk/drivers/watchdog/iTCO_vendor_support.c index d8264ad0be41..2474ebca88f6 100644 --- a/trunk/drivers/watchdog/iTCO_vendor_support.c +++ b/trunk/drivers/watchdog/iTCO_vendor_support.c @@ -1,7 +1,7 @@ /* * intel TCO vendor specific watchdog driver support * - * (c) Copyright 2006-2009 Wim Van Sebroeck . + * (c) Copyright 2006-2008 Wim Van Sebroeck . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,7 +19,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_vendor_support" -#define DRV_VERSION "1.03" +#define DRV_VERSION "1.02" #define PFX DRV_NAME ": " /* Includes */ @@ -77,26 +77,6 @@ MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (n * 20.6 seconds. */ -static void supermicro_old_pre_start(unsigned long acpibase) -{ - unsigned long val32; - - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ - val32 = inl(SMI_EN); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ - outl(val32, SMI_EN); /* Needed to activate watchdog */ -} - -static void supermicro_old_pre_stop(unsigned long acpibase) -{ - unsigned long val32; - - /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ - val32 = inl(SMI_EN); - val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ - outl(val32, SMI_EN); /* Needed to deactivate watchdog */ -} - static void supermicro_old_pre_keepalive(unsigned long acpibase) { /* Reload TCO Timer (done in iTCO_wdt_keepalive) + */ @@ -248,18 +228,14 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat) void iTCO_vendor_pre_start(unsigned long acpibase, unsigned int heartbeat) { - if (vendorsupport == SUPERMICRO_OLD_BOARD) - supermicro_old_pre_start(acpibase); - else if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_start(heartbeat); } EXPORT_SYMBOL(iTCO_vendor_pre_start); void iTCO_vendor_pre_stop(unsigned long acpibase) { - if (vendorsupport == SUPERMICRO_OLD_BOARD) - supermicro_old_pre_stop(acpibase); - else if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_stop(); } EXPORT_SYMBOL(iTCO_vendor_pre_stop); diff --git a/trunk/drivers/watchdog/iTCO_wdt.c b/trunk/drivers/watchdog/iTCO_wdt.c index 352334947ea3..5b395a4ddfdf 100644 --- a/trunk/drivers/watchdog/iTCO_wdt.c +++ b/trunk/drivers/watchdog/iTCO_wdt.c @@ -1,7 +1,7 @@ /* - * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets) + * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets) * - * (c) Copyright 2006-2009 Wim Van Sebroeck . + * (c) Copyright 2006-2008 Wim Van Sebroeck . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -63,7 +63,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_wdt" -#define DRV_VERSION "1.05" +#define DRV_VERSION "1.04" #define PFX DRV_NAME ": " /* Includes */ @@ -236,16 +236,16 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); /* Address definitions for the TCO */ /* TCO base address */ -#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 +#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 /* SMI Control and Enable Register */ -#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 +#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ -#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ -#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ -#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ -#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ +#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ +#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ +#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ +#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ #define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */ #define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */ #define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */ @@ -338,6 +338,7 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void) static int iTCO_wdt_start(void) { unsigned int val; + unsigned long val32; spin_lock(&iTCO_wdt_private.io_lock); @@ -350,6 +351,11 @@ static int iTCO_wdt_start(void) return -EIO; } + /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ + val32 = inl(SMI_EN); + val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ + outl(val32, SMI_EN); + /* Force the timer to its reload value by writing to the TCO_RLD register */ if (iTCO_wdt_private.iTCO_version == 2) @@ -372,6 +378,7 @@ static int iTCO_wdt_start(void) static int iTCO_wdt_stop(void) { unsigned int val; + unsigned long val32; spin_lock(&iTCO_wdt_private.io_lock); @@ -383,6 +390,11 @@ static int iTCO_wdt_stop(void) outw(val, TCO1_CNT); val = inw(TCO1_CNT); + /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ + val32 = inl(SMI_EN); + val32 |= 0x00002000; + outl(val32, SMI_EN); + /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ iTCO_wdt_set_NO_REBOOT_bit(); @@ -637,7 +649,6 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, int ret; u32 base_address; unsigned long RCBA; - unsigned long val32; /* * Find the ACPI/PM base I/O address which is the base @@ -684,10 +695,6 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, ret = -EIO; goto out; } - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ - val32 = inl(SMI_EN); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ - outl(val32, SMI_EN); /* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */ diff --git a/trunk/drivers/xen/manage.c b/trunk/drivers/xen/manage.c index 56892a142ee2..9b91617b9582 100644 --- a/trunk/drivers/xen/manage.c +++ b/trunk/drivers/xen/manage.c @@ -45,13 +45,6 @@ static int xen_suspend(void *data) err); return err; } - err = sysdev_suspend(PMSG_SUSPEND); - if (err) { - printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", - err); - device_power_up(PMSG_RESUME); - return err; - } xen_mm_pin_all(); gnttab_suspend(); @@ -68,7 +61,6 @@ static int xen_suspend(void *data) gnttab_resume(); xen_mm_unpin_all(); - sysdev_resume(); device_power_up(PMSG_RESUME); if (!*cancelled) { diff --git a/trunk/fs/Makefile b/trunk/fs/Makefile index dc20db348679..38bc735c67ad 100644 --- a/trunk/fs/Makefile +++ b/trunk/fs/Makefile @@ -69,12 +69,10 @@ obj-$(CONFIG_DLM) += dlm/ # Do not add any filesystems before this line obj-$(CONFIG_REISERFS_FS) += reiserfs/ obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 -obj-$(CONFIG_EXT2_FS) += ext2/ -# We place ext4 after ext2 so plain ext2 root fs's are mounted using ext2 -# unless explicitly requested by rootfstype -obj-$(CONFIG_EXT4_FS) += ext4/ +obj-$(CONFIG_EXT4_FS) += ext4/ # Before ext2 so root fs can be ext4 obj-$(CONFIG_JBD) += jbd/ obj-$(CONFIG_JBD2) += jbd2/ +obj-$(CONFIG_EXT2_FS) += ext2/ obj-$(CONFIG_CRAMFS) += cramfs/ obj-$(CONFIG_SQUASHFS) += squashfs/ obj-y += ramfs/ diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index 33b7235f853b..e3ff2b9e602f 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -1208,11 +1208,9 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, * check for an ELF header. If we find one, dump the first page to * aid in determining what was mapped here. */ - if (FILTER(ELF_HEADERS) && - vma->vm_pgoff == 0 && (vma->vm_flags & VM_READ)) { + if (FILTER(ELF_HEADERS) && vma->vm_file != NULL && vma->vm_pgoff == 0) { u32 __user *header = (u32 __user *) vma->vm_start; u32 word; - mm_segment_t fs = get_fs(); /* * Doing it this way gets the constant folded by GCC. */ @@ -1225,15 +1223,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, magic.elfmag[EI_MAG1] = ELFMAG1; magic.elfmag[EI_MAG2] = ELFMAG2; magic.elfmag[EI_MAG3] = ELFMAG3; - /* - * Switch to the user "segment" for get_user(), - * then put back what elf_core_dump() had in place. - */ - set_fs(USER_DS); - if (unlikely(get_user(word, header))) - word = 0; - set_fs(fs); - if (word == magic.cmp) + if (get_user(word, header) == 0 && word == magic.cmp) return PAGE_SIZE; } diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 124b95c4d582..062299acbccd 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -302,10 +302,9 @@ void bio_init(struct bio *bio) struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) { struct bio *bio = NULL; - void *uninitialized_var(p); if (bs) { - p = mempool_alloc(bs->bio_pool, gfp_mask); + void *p = mempool_alloc(bs->bio_pool, gfp_mask); if (p) bio = p + bs->front_pad; @@ -330,7 +329,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) } if (unlikely(!bvl)) { if (bs) - mempool_free(p, bs->bio_pool); + mempool_free(bio, bs->bio_pool); else kfree(bio); bio = NULL; diff --git a/trunk/fs/btrfs/Kconfig b/trunk/fs/btrfs/Kconfig index 7bb3c020e570..f8fcf999ea1b 100644 --- a/trunk/fs/btrfs/Kconfig +++ b/trunk/fs/btrfs/Kconfig @@ -16,16 +16,3 @@ config BTRFS_FS module will be called btrfs. If unsure, say N. - -config BTRFS_FS_POSIX_ACL - bool "Btrfs POSIX Access Control Lists" - depends on BTRFS_FS - select FS_POSIX_ACL - help - POSIX Access Control Lists (ACLs) support permissions for users and - groups beyond the owner/group/world scheme. - - To learn more about Access Control Lists, visit the POSIX ACLs for - Linux website . - - If you don't know what Access Control Lists are, say N diff --git a/trunk/fs/btrfs/async-thread.c b/trunk/fs/btrfs/async-thread.c index c84ca1f5259a..8e2fec05dbe0 100644 --- a/trunk/fs/btrfs/async-thread.c +++ b/trunk/fs/btrfs/async-thread.c @@ -16,11 +16,11 @@ * Boston, MA 021110-1307, USA. */ +#include #include #include #include -#include -#include +# include #include "async-thread.h" #define WORK_QUEUED_BIT 0 @@ -143,7 +143,6 @@ static int worker_loop(void *arg) struct btrfs_work *work; do { spin_lock_irq(&worker->lock); -again_locked: while (!list_empty(&worker->pending)) { cur = worker->pending.next; work = list_entry(cur, struct btrfs_work, list); @@ -166,50 +165,14 @@ static int worker_loop(void *arg) check_idle_worker(worker); } + worker->working = 0; if (freezing(current)) { - worker->working = 0; - spin_unlock_irq(&worker->lock); refrigerator(); } else { + set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irq(&worker->lock); - if (!kthread_should_stop()) { - cpu_relax(); - /* - * we've dropped the lock, did someone else - * jump_in? - */ - smp_mb(); - if (!list_empty(&worker->pending)) - continue; - - /* - * this short schedule allows more work to - * come in without the queue functions - * needing to go through wake_up_process() - * - * worker->working is still 1, so nobody - * is going to try and wake us up - */ - schedule_timeout(1); - smp_mb(); - if (!list_empty(&worker->pending)) - continue; - - /* still no more work?, sleep for real */ - spin_lock_irq(&worker->lock); - set_current_state(TASK_INTERRUPTIBLE); - if (!list_empty(&worker->pending)) - goto again_locked; - - /* - * this makes sure we get a wakeup when someone - * adds something new to the queue - */ - worker->working = 0; - spin_unlock_irq(&worker->lock); - + if (!kthread_should_stop()) schedule(); - } __set_current_state(TASK_RUNNING); } } while (!kthread_should_stop()); @@ -387,14 +350,13 @@ int btrfs_requeue_work(struct btrfs_work *work) { struct btrfs_worker_thread *worker = work->worker; unsigned long flags; - int wake = 0; if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags)) goto out; spin_lock_irqsave(&worker->lock, flags); - list_add_tail(&work->list, &worker->pending); atomic_inc(&worker->num_pending); + list_add_tail(&work->list, &worker->pending); /* by definition we're busy, take ourselves off the idle * list @@ -406,16 +368,10 @@ int btrfs_requeue_work(struct btrfs_work *work) &worker->workers->worker_list); spin_unlock_irqrestore(&worker->workers->lock, flags); } - if (!worker->working) { - wake = 1; - worker->working = 1; - } spin_unlock_irqrestore(&worker->lock, flags); - if (wake) - wake_up_process(worker->task); -out: +out: return 0; } @@ -442,10 +398,9 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work) } spin_lock_irqsave(&worker->lock, flags); - - list_add_tail(&work->list, &worker->pending); atomic_inc(&worker->num_pending); check_busy_worker(worker); + list_add_tail(&work->list, &worker->pending); /* * avoid calling into wake_up_process if this thread has already diff --git a/trunk/fs/btrfs/btrfs_inode.h b/trunk/fs/btrfs/btrfs_inode.h index 72677ce2b74f..a8c9693b75ac 100644 --- a/trunk/fs/btrfs/btrfs_inode.h +++ b/trunk/fs/btrfs/btrfs_inode.h @@ -66,9 +66,6 @@ struct btrfs_inode { */ struct list_head delalloc_inodes; - /* the space_info for where this inode's data allocations are done */ - struct btrfs_space_info *space_info; - /* full 64 bit generation number, struct vfs_inode doesn't have a big * enough field for this. */ @@ -97,11 +94,6 @@ struct btrfs_inode { */ u64 delalloc_bytes; - /* total number of bytes that may be used for this inode for - * delalloc - */ - u64 reserved_bytes; - /* * the size of the file stored in the metadata on disk. data=ordered * means the in-memory i_size might be larger than the size on disk diff --git a/trunk/fs/btrfs/compression.c b/trunk/fs/btrfs/compression.c index ab07627084f1..ee848d8585d9 100644 --- a/trunk/fs/btrfs/compression.c +++ b/trunk/fs/btrfs/compression.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "compat.h" #include "ctree.h" diff --git a/trunk/fs/btrfs/ctree.c b/trunk/fs/btrfs/ctree.c index 42491d728e99..9e46c0776816 100644 --- a/trunk/fs/btrfs/ctree.c +++ b/trunk/fs/btrfs/ctree.c @@ -38,62 +38,20 @@ static int balance_node_right(struct btrfs_trans_handle *trans, static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level, int slot); -struct btrfs_path *btrfs_alloc_path(void) +inline void btrfs_init_path(struct btrfs_path *p) { - struct btrfs_path *path; - path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS); - if (path) - path->reada = 1; - return path; + memset(p, 0, sizeof(*p)); } -/* - * set all locked nodes in the path to blocking locks. This should - * be done before scheduling - */ -noinline void btrfs_set_path_blocking(struct btrfs_path *p) -{ - int i; - for (i = 0; i < BTRFS_MAX_LEVEL; i++) { - if (p->nodes[i] && p->locks[i]) - btrfs_set_lock_blocking(p->nodes[i]); - } -} - -/* - * reset all the locked nodes in the patch to spinning locks. - * - * held is used to keep lockdep happy, when lockdep is enabled - * we set held to a blocking lock before we go around and - * retake all the spinlocks in the path. You can safely use NULL - * for held - */ -noinline void btrfs_clear_path_blocking(struct btrfs_path *p, - struct extent_buffer *held) +struct btrfs_path *btrfs_alloc_path(void) { - int i; - -#ifdef CONFIG_DEBUG_LOCK_ALLOC - /* lockdep really cares that we take all of these spinlocks - * in the right order. If any of the locks in the path are not - * currently blocking, it is going to complain. So, make really - * really sure by forcing the path to blocking before we clear - * the path blocking. - */ - if (held) - btrfs_set_lock_blocking(held); - btrfs_set_path_blocking(p); -#endif - - for (i = BTRFS_MAX_LEVEL - 1; i >= 0; i--) { - if (p->nodes[i] && p->locks[i]) - btrfs_clear_lock_blocking(p->nodes[i]); + struct btrfs_path *path; + path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); + if (path) { + btrfs_init_path(path); + path->reada = 1; } - -#ifdef CONFIG_DEBUG_LOCK_ALLOC - if (held) - btrfs_clear_lock_blocking(held); -#endif + return path; } /* this also releases the path */ @@ -303,7 +261,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, trans->transid, level, &ins); BUG_ON(ret); cow = btrfs_init_new_buffer(trans, root, prealloc_dest, - buf->len, level); + buf->len); } else { cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start, @@ -314,8 +272,6 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, if (IS_ERR(cow)) return PTR_ERR(cow); - /* cow is set to blocking by btrfs_init_new_buffer */ - copy_extent_buffer(cow, buf, 0, 0, cow->len); btrfs_set_header_bytenr(cow, cow->start); btrfs_set_header_generation(cow, trans->transid); @@ -432,20 +388,17 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, WARN_ON(1); } + spin_lock(&root->fs_info->hash_lock); if (btrfs_header_generation(buf) == trans->transid && btrfs_header_owner(buf) == root->root_key.objectid && !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { *cow_ret = buf; + spin_unlock(&root->fs_info->hash_lock); WARN_ON(prealloc_dest); return 0; } - + spin_unlock(&root->fs_info->hash_lock); search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1); - - if (parent) - btrfs_set_lock_blocking(parent); - btrfs_set_lock_blocking(buf); - ret = __btrfs_cow_block(trans, root, buf, parent, parent_slot, cow_ret, search_start, 0, prealloc_dest); @@ -551,8 +504,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, if (parent_nritems == 1) return 0; - btrfs_set_lock_blocking(parent); - for (i = start_slot; i < end_slot; i++) { int close = 1; @@ -613,7 +564,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, search_start = last_block; btrfs_tree_lock(cur); - btrfs_set_lock_blocking(cur); err = __btrfs_cow_block(trans, root, cur, parent, i, &cur, search_start, min(16 * blocksize, @@ -912,7 +862,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, return 0; mid = path->nodes[level]; - WARN_ON(!path->locks[level]); WARN_ON(btrfs_header_generation(mid) != trans->transid); @@ -934,9 +883,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, /* promote the child to a root */ child = read_node_slot(root, mid, 0); - BUG_ON(!child); btrfs_tree_lock(child); - btrfs_set_lock_blocking(child); + BUG_ON(!child); ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); BUG_ON(ret); @@ -952,7 +900,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, add_root_to_dirty_list(root); btrfs_tree_unlock(child); - path->locks[level] = 0; path->nodes[level] = NULL; clean_tree_block(trans, root, mid); @@ -977,7 +924,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, left = read_node_slot(root, parent, pslot - 1); if (left) { btrfs_tree_lock(left); - btrfs_set_lock_blocking(left); wret = btrfs_cow_block(trans, root, left, parent, pslot - 1, &left, 0); if (wret) { @@ -988,7 +934,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, right = read_node_slot(root, parent, pslot + 1); if (right) { btrfs_tree_lock(right); - btrfs_set_lock_blocking(right); wret = btrfs_cow_block(trans, root, right, parent, pslot + 1, &right, 0); if (wret) { @@ -1164,8 +1109,6 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, u32 left_nr; btrfs_tree_lock(left); - btrfs_set_lock_blocking(left); - left_nr = btrfs_header_nritems(left); if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { wret = 1; @@ -1212,10 +1155,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, */ if (right) { u32 right_nr; - btrfs_tree_lock(right); - btrfs_set_lock_blocking(right); - right_nr = btrfs_header_nritems(right); if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { wret = 1; @@ -1270,7 +1210,8 @@ static noinline void reada_for_search(struct btrfs_root *root, struct btrfs_disk_key disk_key; u32 nritems; u64 search; - u64 target; + u64 lowest_read; + u64 highest_read; u64 nread = 0; int direction = path->reada; struct extent_buffer *eb; @@ -1294,7 +1235,8 @@ static noinline void reada_for_search(struct btrfs_root *root, return; } - target = search; + highest_read = search; + lowest_read = search; nritems = btrfs_header_nritems(node); nr = slot; @@ -1314,80 +1256,27 @@ static noinline void reada_for_search(struct btrfs_root *root, break; } search = btrfs_node_blockptr(node, nr); - if ((search <= target && target - search <= 65536) || - (search > target && search - target <= 65536)) { + if ((search >= lowest_read && search <= highest_read) || + (search < lowest_read && lowest_read - search <= 16384) || + (search > highest_read && search - highest_read <= 16384)) { readahead_tree_block(root, search, blocksize, btrfs_node_ptr_generation(node, nr)); nread += blocksize; } nscan++; - if ((nread > 65536 || nscan > 32)) + if (path->reada < 2 && (nread > (64 * 1024) || nscan > 32)) break; - } -} -/* - * returns -EAGAIN if it had to drop the path, or zero if everything was in - * cache - */ -static noinline int reada_for_balance(struct btrfs_root *root, - struct btrfs_path *path, int level) -{ - int slot; - int nritems; - struct extent_buffer *parent; - struct extent_buffer *eb; - u64 gen; - u64 block1 = 0; - u64 block2 = 0; - int ret = 0; - int blocksize; - - parent = path->nodes[level - 1]; - if (!parent) - return 0; - - nritems = btrfs_header_nritems(parent); - slot = path->slots[level]; - blocksize = btrfs_level_size(root, level); + if (nread > (256 * 1024) || nscan > 128) + break; - if (slot > 0) { - block1 = btrfs_node_blockptr(parent, slot - 1); - gen = btrfs_node_ptr_generation(parent, slot - 1); - eb = btrfs_find_tree_block(root, block1, blocksize); - if (eb && btrfs_buffer_uptodate(eb, gen)) - block1 = 0; - free_extent_buffer(eb); - } - if (slot < nritems) { - block2 = btrfs_node_blockptr(parent, slot + 1); - gen = btrfs_node_ptr_generation(parent, slot + 1); - eb = btrfs_find_tree_block(root, block2, blocksize); - if (eb && btrfs_buffer_uptodate(eb, gen)) - block2 = 0; - free_extent_buffer(eb); + if (search < lowest_read) + lowest_read = search; + if (search > highest_read) + highest_read = search; } - if (block1 || block2) { - ret = -EAGAIN; - btrfs_release_path(root, path); - if (block1) - readahead_tree_block(root, block1, blocksize, 0); - if (block2) - readahead_tree_block(root, block2, blocksize, 0); - - if (block1) { - eb = read_tree_block(root, block1, blocksize, 0); - free_extent_buffer(eb); - } - if (block1) { - eb = read_tree_block(root, block2, blocksize, 0); - free_extent_buffer(eb); - } - } - return ret; } - /* * when we walk down the tree, it is usually safe to unlock the higher layers * in the tree. The exceptions are when our path goes through slot 0, because @@ -1438,32 +1327,6 @@ static noinline void unlock_up(struct btrfs_path *path, int level, } } -/* - * This releases any locks held in the path starting at level and - * going all the way up to the root. - * - * btrfs_search_slot will keep the lock held on higher nodes in a few - * corner cases, such as COW of the block at slot zero in the node. This - * ignores those rules, and it should only be called when there are no - * more updates to be done higher up in the tree. - */ -noinline void btrfs_unlock_up_safe(struct btrfs_path *path, int level) -{ - int i; - - if (path->keep_locks || path->lowest_level) - return; - - for (i = level; i < BTRFS_MAX_LEVEL; i++) { - if (!path->nodes[i]) - continue; - if (!path->locks[i]) - continue; - btrfs_tree_unlock(path->nodes[i]); - path->locks[i] = 0; - } -} - /* * look for key in the tree. path is filled in with nodes along the way * if key is found, we return zero and you can find the item in the leaf @@ -1524,30 +1387,32 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root int wret; /* is a cow on this block not required */ + spin_lock(&root->fs_info->hash_lock); if (btrfs_header_generation(b) == trans->transid && btrfs_header_owner(b) == root->root_key.objectid && !btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) { + spin_unlock(&root->fs_info->hash_lock); goto cow_done; } + spin_unlock(&root->fs_info->hash_lock); /* ok, we have to cow, is our old prealloc the right * size? */ if (prealloc_block.objectid && prealloc_block.offset != b->len) { - btrfs_release_path(root, p); btrfs_free_reserved_extent(root, prealloc_block.objectid, prealloc_block.offset); prealloc_block.objectid = 0; - goto again; } /* * for higher level blocks, try not to allocate blocks * with the block and the parent locks held. */ - if (level > 0 && !prealloc_block.objectid) { + if (level > 1 && !prealloc_block.objectid && + btrfs_path_lock_waiting(p, level)) { u32 size = b->len; u64 hint = b->start; @@ -1560,8 +1425,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root goto again; } - btrfs_set_path_blocking(p); - wret = btrfs_cow_block(trans, root, b, p->nodes[level + 1], p->slots[level + 1], @@ -1583,22 +1446,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root if (!p->skip_locking) p->locks[level] = 1; - btrfs_clear_path_blocking(p, NULL); - - /* - * we have a lock on b and as long as we aren't changing - * the tree, there is no way to for the items in b to change. - * It is safe to drop the lock on our parent before we - * go through the expensive btree search on b. - * - * If cow is true, then we might be changing slot zero, - * which may require changing the parent. So, we can't - * drop the lock until after we know which slot we're - * operating on. - */ - if (!cow) - btrfs_unlock_up_safe(p, level + 1); - ret = check_block(root, p, level); if (ret) { ret = -1; @@ -1606,7 +1453,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root } ret = bin_search(b, key, level, &slot); - if (level != 0) { if (ret && slot > 0) slot -= 1; @@ -1614,16 +1460,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root if ((p->search_for_split || ins_len > 0) && btrfs_header_nritems(b) >= BTRFS_NODEPTRS_PER_BLOCK(root) - 3) { - int sret; - - sret = reada_for_balance(root, p, level); - if (sret) - goto again; - - btrfs_set_path_blocking(p); - sret = split_node(trans, root, p, level); - btrfs_clear_path_blocking(p, NULL); - + int sret = split_node(trans, root, p, level); BUG_ON(sret > 0); if (sret) { ret = sret; @@ -1631,19 +1468,9 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root } b = p->nodes[level]; slot = p->slots[level]; - } else if (ins_len < 0 && - btrfs_header_nritems(b) < - BTRFS_NODEPTRS_PER_BLOCK(root) / 4) { - int sret; - - sret = reada_for_balance(root, p, level); - if (sret) - goto again; - - btrfs_set_path_blocking(p); - sret = balance_level(trans, root, p, level); - btrfs_clear_path_blocking(p, NULL); - + } else if (ins_len < 0) { + int sret = balance_level(trans, root, p, + level); if (sret) { ret = sret; goto done; @@ -1677,7 +1504,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root * of the btree by dropping locks before * we read. */ - if (level > 0) { + if (level > 1) { btrfs_release_path(NULL, p); if (tmp) free_extent_buffer(tmp); @@ -1692,7 +1519,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root free_extent_buffer(tmp); goto again; } else { - btrfs_set_path_blocking(p); if (tmp) free_extent_buffer(tmp); if (should_reada) @@ -1702,29 +1528,14 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root b = read_node_slot(root, b, slot); } } - if (!p->skip_locking) { - int lret; - - btrfs_clear_path_blocking(p, NULL); - lret = btrfs_try_spin_lock(b); - - if (!lret) { - btrfs_set_path_blocking(p); - btrfs_tree_lock(b); - btrfs_clear_path_blocking(p, b); - } - } + if (!p->skip_locking) + btrfs_tree_lock(b); } else { p->slots[level] = slot; if (ins_len > 0 && btrfs_leaf_free_space(root, b) < ins_len) { - int sret; - - btrfs_set_path_blocking(p); - sret = split_leaf(trans, root, key, + int sret = split_leaf(trans, root, key, p, ins_len, ret == 0); - btrfs_clear_path_blocking(p, NULL); - BUG_ON(sret > 0); if (sret) { ret = sret; @@ -1738,16 +1549,12 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root } ret = 1; done: - /* - * we don't really know what they plan on doing with the path - * from here on, so for now just mark it as blocking - */ - btrfs_set_path_blocking(p); if (prealloc_block.objectid) { btrfs_free_reserved_extent(root, prealloc_block.objectid, prealloc_block.offset); } + return ret; } @@ -1771,8 +1578,6 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, ret = btrfs_cow_block(trans, root, eb, NULL, 0, &eb, 0); BUG_ON(ret); - btrfs_set_lock_blocking(eb); - parent = eb; while (1) { level = btrfs_header_level(parent); @@ -1797,7 +1602,6 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, eb = read_tree_block(root, bytenr, blocksize, generation); btrfs_tree_lock(eb); - btrfs_set_lock_blocking(eb); } /* @@ -1822,7 +1626,6 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, eb = read_tree_block(root, bytenr, blocksize, generation); btrfs_tree_lock(eb); - btrfs_set_lock_blocking(eb); } ret = btrfs_cow_block(trans, root, eb, parent, slot, @@ -2369,8 +2172,6 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root right = read_node_slot(root, upper, slot + 1); btrfs_tree_lock(right); - btrfs_set_lock_blocking(right); - free_space = btrfs_leaf_free_space(root, right); if (free_space < data_size) goto out_unlock; @@ -2566,8 +2367,6 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root left = read_node_slot(root, path->nodes[1], slot - 1); btrfs_tree_lock(left); - btrfs_set_lock_blocking(left); - free_space = btrfs_leaf_free_space(root, left); if (free_space < data_size) { ret = 1; @@ -3026,12 +2825,6 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, path->keep_locks = 0; BUG_ON(ret); - /* - * make sure any changes to the path from split_leaf leave it - * in a blocking state - */ - btrfs_set_path_blocking(path); - leaf = path->nodes[0]; BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); @@ -3561,7 +3354,6 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, BUG(); } out: - btrfs_unlock_up_safe(path, 1); return ret; } @@ -3649,22 +3441,15 @@ noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, { int ret; u64 root_gen = btrfs_header_generation(path->nodes[1]); - u64 parent_start = path->nodes[1]->start; - u64 parent_owner = btrfs_header_owner(path->nodes[1]); ret = del_ptr(trans, root, path, 1, path->slots[1]); if (ret) return ret; - /* - * btrfs_free_extent is expensive, we want to make sure we - * aren't holding any locks when we call it - */ - btrfs_unlock_up_safe(path, 0); - ret = btrfs_free_extent(trans, root, bytenr, btrfs_level_size(root, 0), - parent_start, parent_owner, + path->nodes[1]->start, + btrfs_header_owner(path->nodes[1]), root_gen, 0, 1); return ret; } @@ -3936,7 +3721,6 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, */ if (slot >= nritems) { path->slots[level] = slot; - btrfs_set_path_blocking(path); sret = btrfs_find_next_key(root, path, min_key, level, cache_only, min_trans); if (sret == 0) { @@ -3954,20 +3738,16 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, unlock_up(path, level, 1); goto out; } - btrfs_set_path_blocking(path); cur = read_node_slot(root, cur, slot); btrfs_tree_lock(cur); - path->locks[level - 1] = 1; path->nodes[level - 1] = cur; unlock_up(path, level, 1); - btrfs_clear_path_blocking(path, NULL); } out: if (ret == 0) memcpy(min_key, &found_key, sizeof(found_key)); - btrfs_set_path_blocking(path); return ret; } @@ -4063,7 +3843,6 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) if (ret < 0) return ret; - btrfs_set_path_blocking(path); nritems = btrfs_header_nritems(path->nodes[0]); /* * by releasing the path above we dropped all our locks. A balance @@ -4094,7 +3873,6 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) free_extent_buffer(next); } - /* the path was set to blocking above */ if (level == 1 && (path->locks[1] || path->skip_locking) && path->reada) reada_for_search(root, path, level, slot, 0); @@ -4103,7 +3881,6 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) if (!path->skip_locking) { WARN_ON(!btrfs_tree_locked(c)); btrfs_tree_lock(next); - btrfs_set_lock_blocking(next); } break; } @@ -4120,15 +3897,12 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) path->locks[level] = 1; if (!level) break; - - btrfs_set_path_blocking(path); if (level == 1 && path->locks[1] && path->reada) reada_for_search(root, path, level, slot, 0); next = read_node_slot(root, next, 0); if (!path->skip_locking) { WARN_ON(!btrfs_tree_locked(path->nodes[level])); btrfs_tree_lock(next); - btrfs_set_lock_blocking(next); } } done: @@ -4153,7 +3927,6 @@ int btrfs_previous_item(struct btrfs_root *root, while (1) { if (path->slots[0] == 0) { - btrfs_set_path_blocking(path); ret = btrfs_prev_leaf(root, path); if (ret != 0) return ret; diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index 82491ba8fa40..eee060f88113 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -43,7 +43,11 @@ struct btrfs_ordered_sum; #define BTRFS_ACL_NOT_CACHED ((void *)-1) -#define BTRFS_MAX_LEVEL 8 +#ifdef CONFIG_LOCKDEP +# define BTRFS_MAX_LEVEL 7 +#else +# define BTRFS_MAX_LEVEL 8 +#endif /* holds pointers to all of the tree roots */ #define BTRFS_ROOT_TREE_OBJECTID 1ULL @@ -450,11 +454,17 @@ struct btrfs_timespec { __le32 nsec; } __attribute__ ((__packed__)); -enum btrfs_compression_type { +typedef enum { BTRFS_COMPRESS_NONE = 0, BTRFS_COMPRESS_ZLIB = 1, BTRFS_COMPRESS_LAST = 2, -}; +} btrfs_compression_type; + +/* we don't understand any encryption methods right now */ +typedef enum { + BTRFS_ENCRYPTION_NONE = 0, + BTRFS_ENCRYPTION_LAST = 1, +} btrfs_encryption_type; struct btrfs_inode_item { /* nfs style generation number */ @@ -596,27 +606,13 @@ struct btrfs_block_group_item { struct btrfs_space_info { u64 flags; - - u64 total_bytes; /* total bytes in the space */ - u64 bytes_used; /* total bytes used on disk */ - u64 bytes_pinned; /* total bytes pinned, will be freed when the - transaction finishes */ - u64 bytes_reserved; /* total bytes the allocator has reserved for - current allocations */ - u64 bytes_readonly; /* total bytes that are read only */ - - /* delalloc accounting */ - u64 bytes_delalloc; /* number of bytes reserved for allocation, - this space is not necessarily reserved yet - by the allocator */ - u64 bytes_may_use; /* number of bytes that may be used for - delalloc */ - - int full; /* indicates that we cannot allocate any more - chunks for this space */ - int force_alloc; /* set if we need to force a chunk alloc for - this space */ - + u64 total_bytes; + u64 bytes_used; + u64 bytes_pinned; + u64 bytes_reserved; + u64 bytes_readonly; + int full; + int force_alloc; struct list_head list; /* for block groups in our same type */ @@ -705,7 +701,9 @@ struct btrfs_fs_info { struct btrfs_transaction *running_transaction; wait_queue_head_t transaction_throttle; wait_queue_head_t transaction_wait; + wait_queue_head_t async_submit_wait; + wait_queue_head_t tree_log_wait; struct btrfs_super_block super_copy; struct btrfs_super_block super_for_commit; @@ -713,6 +711,7 @@ struct btrfs_fs_info { struct super_block *sb; struct inode *btree_inode; struct backing_dev_info bdi; + spinlock_t hash_lock; struct mutex trans_mutex; struct mutex tree_log_mutex; struct mutex transaction_kthread_mutex; @@ -731,6 +730,10 @@ struct btrfs_fs_info { atomic_t async_submit_draining; atomic_t nr_async_bios; atomic_t async_delalloc_pages; + atomic_t tree_log_writers; + atomic_t tree_log_commit; + unsigned long tree_log_batch; + u64 tree_log_transid; /* * this is used by the balancing code to wait for all the pending @@ -830,14 +833,7 @@ struct btrfs_root { struct kobject root_kobj; struct completion kobj_unregister; struct mutex objectid_mutex; - struct mutex log_mutex; - wait_queue_head_t log_writer_wait; - wait_queue_head_t log_commit_wait[2]; - atomic_t log_writers; - atomic_t log_commit[2]; - unsigned long log_transid; - unsigned long log_batch; u64 objectid; u64 last_trans; @@ -1725,8 +1721,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, u64 empty_size); struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, - u64 bytenr, u32 blocksize, - int level); + u64 bytenr, u32 blocksize); int btrfs_alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 num_bytes, u64 parent, u64 min_bytes, @@ -1796,16 +1791,6 @@ int btrfs_add_dead_reloc_root(struct btrfs_root *root); int btrfs_cleanup_reloc_trees(struct btrfs_root *root); int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); -void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde); -int btrfs_check_metadata_free_space(struct btrfs_root *root); -int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, - u64 bytes); -void btrfs_free_reserved_data_space(struct btrfs_root *root, - struct inode *inode, u64 bytes); -void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, - u64 bytes); -void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, - u64 bytes); /* ctree.c */ int btrfs_previous_item(struct btrfs_root *root, struct btrfs_path *path, u64 min_objectid, @@ -1855,9 +1840,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); struct btrfs_path *btrfs_alloc_path(void); void btrfs_free_path(struct btrfs_path *p); -void btrfs_set_path_blocking(struct btrfs_path *p); -void btrfs_unlock_up_safe(struct btrfs_path *p, int level); - +void btrfs_init_path(struct btrfs_path *p); int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int slot, int nr); int btrfs_del_leaf(struct btrfs_trans_handle *trans, @@ -2051,6 +2034,8 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset, unsigned long btrfs_force_ra(struct address_space *mapping, struct file_ra_state *ra, struct file *file, pgoff_t offset, pgoff_t last_index); +int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, + int for_del); int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page); int btrfs_readpage(struct file *file, struct page *page); void btrfs_delete_inode(struct inode *inode); diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index adda739a0215..81a313874ae5 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -16,6 +16,7 @@ * Boston, MA 021110-1307, USA. */ +#include #include #include #include @@ -75,40 +76,6 @@ struct async_submit_bio { struct btrfs_work work; }; -/* These are used to set the lockdep class on the extent buffer locks. - * The class is set by the readpage_end_io_hook after the buffer has - * passed csum validation but before the pages are unlocked. - * - * The lockdep class is also set by btrfs_init_new_buffer on freshly - * allocated blocks. - * - * The class is based on the level in the tree block, which allows lockdep - * to know that lower nodes nest inside the locks of higher nodes. - * - * We also add a check to make sure the highest level of the tree is - * the same as our lockdep setup here. If BTRFS_MAX_LEVEL changes, this - * code needs update as well. - */ -#ifdef CONFIG_DEBUG_LOCK_ALLOC -# if BTRFS_MAX_LEVEL != 8 -# error -# endif -static struct lock_class_key btrfs_eb_class[BTRFS_MAX_LEVEL + 1]; -static const char *btrfs_eb_name[BTRFS_MAX_LEVEL + 1] = { - /* leaf */ - "btrfs-extent-00", - "btrfs-extent-01", - "btrfs-extent-02", - "btrfs-extent-03", - "btrfs-extent-04", - "btrfs-extent-05", - "btrfs-extent-06", - "btrfs-extent-07", - /* highest possible level */ - "btrfs-extent-08", -}; -#endif - /* * extents on the btree inode are pretty simple, there's one extent * that covers the entire device @@ -381,15 +348,6 @@ static int check_tree_block_fsid(struct btrfs_root *root, return ret; } -#ifdef CONFIG_DEBUG_LOCK_ALLOC -void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level) -{ - lockdep_set_class_and_name(&eb->lock, - &btrfs_eb_class[level], - btrfs_eb_name[level]); -} -#endif - static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, struct extent_state *state) { @@ -435,8 +393,6 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, } found_level = btrfs_header_level(eb); - btrfs_set_buffer_lockdep_class(eb, found_level); - ret = csum_tree_block(root, eb, 1); if (ret) ret = -EIO; @@ -844,7 +800,7 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); if (ret == 0) - set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); + buf->flags |= EXTENT_UPTODATE; else WARN_ON(1); return buf; @@ -858,10 +814,6 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, if (btrfs_header_generation(buf) == root->fs_info->running_transaction->transid) { WARN_ON(!btrfs_tree_locked(buf)); - - /* ugh, clear_extent_buffer_dirty can be expensive */ - btrfs_set_lock_blocking(buf); - clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, buf); } @@ -898,14 +850,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, spin_lock_init(&root->list_lock); mutex_init(&root->objectid_mutex); mutex_init(&root->log_mutex); - init_waitqueue_head(&root->log_writer_wait); - init_waitqueue_head(&root->log_commit_wait[0]); - init_waitqueue_head(&root->log_commit_wait[1]); - atomic_set(&root->log_commit[0], 0); - atomic_set(&root->log_commit[1], 0); - atomic_set(&root->log_writers, 0); - root->log_batch = 0; - root->log_transid = 0; extent_io_tree_init(&root->dirty_log_pages, fs_info->btree_inode->i_mapping, GFP_NOFS); @@ -990,16 +934,15 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, return 0; } -static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info) +int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info) { struct btrfs_root *root; struct btrfs_root *tree_root = fs_info->tree_root; - struct extent_buffer *leaf; root = kzalloc(sizeof(*root), GFP_NOFS); if (!root) - return ERR_PTR(-ENOMEM); + return -ENOMEM; __setup_root(tree_root->nodesize, tree_root->leafsize, tree_root->sectorsize, tree_root->stripesize, @@ -1008,23 +951,12 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; root->root_key.type = BTRFS_ROOT_ITEM_KEY; root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; - /* - * log trees do not get reference counted because they go away - * before a real commit is actually done. They do store pointers - * to file data extents, and those reference counts still get - * updated (along with back refs to the log tree). - */ root->ref_cows = 0; - leaf = btrfs_alloc_free_block(trans, root, root->leafsize, - 0, BTRFS_TREE_LOG_OBJECTID, - trans->transid, 0, 0, 0); - if (IS_ERR(leaf)) { - kfree(root); - return ERR_CAST(leaf); - } + root->node = btrfs_alloc_free_block(trans, root, root->leafsize, + 0, BTRFS_TREE_LOG_OBJECTID, + trans->transid, 0, 0, 0); - root->node = leaf; btrfs_set_header_nritems(root->node, 0); btrfs_set_header_level(root->node, 0); btrfs_set_header_bytenr(root->node, root->node->start); @@ -1036,48 +968,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, BTRFS_FSID_SIZE); btrfs_mark_buffer_dirty(root->node); btrfs_tree_unlock(root->node); - return root; -} - -int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info) -{ - struct btrfs_root *log_root; - - log_root = alloc_log_tree(trans, fs_info); - if (IS_ERR(log_root)) - return PTR_ERR(log_root); - WARN_ON(fs_info->log_root_tree); - fs_info->log_root_tree = log_root; - return 0; -} - -int btrfs_add_log_tree(struct btrfs_trans_handle *trans, - struct btrfs_root *root) -{ - struct btrfs_root *log_root; - struct btrfs_inode_item *inode_item; - - log_root = alloc_log_tree(trans, root->fs_info); - if (IS_ERR(log_root)) - return PTR_ERR(log_root); - - log_root->last_trans = trans->transid; - log_root->root_key.offset = root->root_key.objectid; - - inode_item = &log_root->root_item.inode; - inode_item->generation = cpu_to_le64(1); - inode_item->size = cpu_to_le64(3); - inode_item->nlink = cpu_to_le32(1); - inode_item->nbytes = cpu_to_le64(root->leafsize); - inode_item->mode = cpu_to_le32(S_IFDIR | 0755); - - btrfs_set_root_bytenr(&log_root->root_item, log_root->node->start); - btrfs_set_root_generation(&log_root->root_item, trans->transid); - - WARN_ON(root->log_root); - root->log_root = log_root; - root->log_transid = 0; + fs_info->log_root_tree = root; return 0; } @@ -1245,6 +1136,7 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) { struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; int ret = 0; + struct list_head *cur; struct btrfs_device *device; struct backing_dev_info *bdi; #if 0 @@ -1252,7 +1144,8 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) btrfs_congested_async(info, 0)) return 1; #endif - list_for_each_entry(device, &info->fs_devices->devices, dev_list) { + list_for_each(cur, &info->fs_devices->devices) { + device = list_entry(cur, struct btrfs_device, dev_list); if (!device->bdev) continue; bdi = blk_get_backing_dev_info(device->bdev); @@ -1270,11 +1163,13 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) */ static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) { + struct list_head *cur; struct btrfs_device *device; struct btrfs_fs_info *info; info = (struct btrfs_fs_info *)bdi->unplug_io_data; - list_for_each_entry(device, &info->fs_devices->devices, dev_list) { + list_for_each(cur, &info->fs_devices->devices) { + device = list_entry(cur, struct btrfs_device, dev_list); if (!device->bdev) continue; @@ -1552,6 +1447,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, INIT_LIST_HEAD(&fs_info->dead_roots); INIT_LIST_HEAD(&fs_info->hashers); INIT_LIST_HEAD(&fs_info->delalloc_inodes); + spin_lock_init(&fs_info->hash_lock); spin_lock_init(&fs_info->delalloc_lock); spin_lock_init(&fs_info->new_trans_lock); spin_lock_init(&fs_info->ref_cache_lock); @@ -1639,6 +1535,10 @@ struct btrfs_root *open_ctree(struct super_block *sb, init_waitqueue_head(&fs_info->transaction_throttle); init_waitqueue_head(&fs_info->transaction_wait); init_waitqueue_head(&fs_info->async_submit_wait); + init_waitqueue_head(&fs_info->tree_log_wait); + atomic_set(&fs_info->tree_log_commit, 0); + atomic_set(&fs_info->tree_log_writers, 0); + fs_info->tree_log_transid = 0; __setup_root(4096, 4096, 4096, 4096, tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID); @@ -1727,8 +1627,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, * low idle thresh */ fs_info->endio_workers.idle_thresh = 4; - fs_info->endio_meta_workers.idle_thresh = 4; - fs_info->endio_write_workers.idle_thresh = 64; fs_info->endio_meta_write_workers.idle_thresh = 64; @@ -1822,6 +1720,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, ret = find_and_setup_root(tree_root, fs_info, BTRFS_DEV_TREE_OBJECTID, dev_root); dev_root->track_dirty = 1; + if (ret) goto fail_extent_root; @@ -1841,13 +1740,13 @@ struct btrfs_root *open_ctree(struct super_block *sb, fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, "btrfs-cleaner"); - if (IS_ERR(fs_info->cleaner_kthread)) + if (!fs_info->cleaner_kthread) goto fail_csum_root; fs_info->transaction_kthread = kthread_run(transaction_kthread, tree_root, "btrfs-transaction"); - if (IS_ERR(fs_info->transaction_kthread)) + if (!fs_info->transaction_kthread) goto fail_cleaner; if (btrfs_super_log_root(disk_super) != 0) { @@ -1929,14 +1828,13 @@ struct btrfs_root *open_ctree(struct super_block *sb, fail_iput: invalidate_inode_pages2(fs_info->btree_inode->i_mapping); iput(fs_info->btree_inode); - +fail: btrfs_close_devices(fs_info->fs_devices); btrfs_mapping_tree_free(&fs_info->mapping_tree); - bdi_destroy(&fs_info->bdi); -fail: kfree(extent_root); kfree(tree_root); + bdi_destroy(&fs_info->bdi); kfree(fs_info); kfree(chunk_root); kfree(dev_root); @@ -2097,6 +1995,7 @@ static int write_dev_supers(struct btrfs_device *device, int write_all_supers(struct btrfs_root *root, int max_mirrors) { + struct list_head *cur; struct list_head *head = &root->fs_info->fs_devices->devices; struct btrfs_device *dev; struct btrfs_super_block *sb; @@ -2112,7 +2011,8 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) sb = &root->fs_info->super_for_commit; dev_item = &sb->dev_item; - list_for_each_entry(dev, head, dev_list) { + list_for_each(cur, head) { + dev = list_entry(cur, struct btrfs_device, dev_list); if (!dev->bdev) { total_errors++; continue; @@ -2145,7 +2045,8 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) } total_errors = 0; - list_for_each_entry(dev, head, dev_list) { + list_for_each(cur, head) { + dev = list_entry(cur, struct btrfs_device, dev_list); if (!dev->bdev) continue; if (!dev->in_fs_metadata || !dev->writeable) @@ -2359,8 +2260,6 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) u64 transid = btrfs_header_generation(buf); struct inode *btree_inode = root->fs_info->btree_inode; - btrfs_set_lock_blocking(buf); - WARN_ON(!btrfs_tree_locked(buf)); if (transid != root->fs_info->generation) { printk(KERN_CRIT "btrfs transid mismatch buffer %llu, " @@ -2403,13 +2302,14 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) int ret; ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); if (ret == 0) - set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); + buf->flags |= EXTENT_UPTODATE; return ret; } int btree_lock_page_hook(struct page *page) { struct inode *inode = page->mapping->host; + struct btrfs_root *root = BTRFS_I(inode)->root; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct extent_buffer *eb; unsigned long len; @@ -2424,7 +2324,9 @@ int btree_lock_page_hook(struct page *page) goto out; btrfs_tree_lock(eb); + spin_lock(&root->fs_info->hash_lock); btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); + spin_unlock(&root->fs_info->hash_lock); btrfs_tree_unlock(eb); free_extent_buffer(eb); out: diff --git a/trunk/fs/btrfs/disk-io.h b/trunk/fs/btrfs/disk-io.h index 95029db227be..c0ff404c31b7 100644 --- a/trunk/fs/btrfs/disk-io.h +++ b/trunk/fs/btrfs/disk-io.h @@ -98,17 +98,5 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); -int btrfs_add_log_tree(struct btrfs_trans_handle *trans, - struct btrfs_root *root); int btree_lock_page_hook(struct page *page); - - -#ifdef CONFIG_DEBUG_LOCK_ALLOC -void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level); -#else -static inline void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, - int level) -{ -} -#endif #endif diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 6b5966aacf44..293da650873f 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "compat.h" #include "hash.h" #include "crc32c.h" @@ -30,6 +30,7 @@ #include "volumes.h" #include "locking.h" #include "ref-cache.h" +#include "compat.h" #define PENDING_EXTENT_INSERT 0 #define PENDING_EXTENT_DELETE 1 @@ -60,10 +61,6 @@ static int update_block_group(struct btrfs_trans_handle *trans, u64 bytenr, u64 num_bytes, int alloc, int mark_free); -static int do_chunk_alloc(struct btrfs_trans_handle *trans, - struct btrfs_root *extent_root, u64 alloc_bytes, - u64 flags, int force); - static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) { return (cache->flags & bits) == bits; @@ -329,8 +326,10 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, u64 flags) { struct list_head *head = &info->space_info; + struct list_head *cur; struct btrfs_space_info *found; - list_for_each_entry(found, head, list) { + list_for_each(cur, head) { + found = list_entry(cur, struct btrfs_space_info, list); if (found->flags == flags) return found; } @@ -1327,25 +1326,8 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, int btrfs_extent_post_op(struct btrfs_trans_handle *trans, struct btrfs_root *root) { - u64 start; - u64 end; - int ret; - - while(1) { - finish_current_insert(trans, root->fs_info->extent_root, 1); - del_pending_extents(trans, root->fs_info->extent_root, 1); - - /* is there more work to do? */ - ret = find_first_extent_bit(&root->fs_info->pending_del, - 0, &start, &end, EXTENT_WRITEBACK); - if (!ret) - continue; - ret = find_first_extent_bit(&root->fs_info->extent_ins, - 0, &start, &end, EXTENT_WRITEBACK); - if (!ret) - continue; - break; - } + finish_current_insert(trans, root->fs_info->extent_root, 1); + del_pending_extents(trans, root->fs_info->extent_root, 1); return 0; } @@ -1543,55 +1525,15 @@ int btrfs_cache_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, return ret; } -/* when a block goes through cow, we update the reference counts of - * everything that block points to. The internal pointers of the block - * can be in just about any order, and it is likely to have clusters of - * things that are close together and clusters of things that are not. - * - * To help reduce the seeks that come with updating all of these reference - * counts, sort them by byte number before actual updates are done. - * - * struct refsort is used to match byte number to slot in the btree block. - * we sort based on the byte number and then use the slot to actually - * find the item. - * - * struct refsort is smaller than strcut btrfs_item and smaller than - * struct btrfs_key_ptr. Since we're currently limited to the page size - * for a btree block, there's no way for a kmalloc of refsorts for a - * single node to be bigger than a page. - */ -struct refsort { - u64 bytenr; - u32 slot; -}; - -/* - * for passing into sort() - */ -static int refsort_cmp(const void *a_void, const void *b_void) -{ - const struct refsort *a = a_void; - const struct refsort *b = b_void; - - if (a->bytenr < b->bytenr) - return -1; - if (a->bytenr > b->bytenr) - return 1; - return 0; -} - - -noinline int btrfs_inc_ref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct extent_buffer *orig_buf, - struct extent_buffer *buf, u32 *nr_extents) +int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct extent_buffer *orig_buf, struct extent_buffer *buf, + u32 *nr_extents) { u64 bytenr; u64 ref_root; u64 orig_root; u64 ref_generation; u64 orig_generation; - struct refsort *sorted; u32 nritems; u32 nr_file_extents = 0; struct btrfs_key key; @@ -1600,8 +1542,6 @@ noinline int btrfs_inc_ref(struct btrfs_trans_handle *trans, int level; int ret = 0; int faili = 0; - int refi = 0; - int slot; int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, u64, u64, u64, u64, u64, u64, u64, u64); @@ -1613,9 +1553,6 @@ noinline int btrfs_inc_ref(struct btrfs_trans_handle *trans, nritems = btrfs_header_nritems(buf); level = btrfs_header_level(buf); - sorted = kmalloc(sizeof(struct refsort) * nritems, GFP_NOFS); - BUG_ON(!sorted); - if (root->ref_cows) { process_func = __btrfs_inc_extent_ref; } else { @@ -1628,11 +1565,6 @@ noinline int btrfs_inc_ref(struct btrfs_trans_handle *trans, process_func = __btrfs_update_extent_ref; } - /* - * we make two passes through the items. In the first pass we - * only record the byte number and slot. Then we sort based on - * byte number and do the actual work based on the sorted results - */ for (i = 0; i < nritems; i++) { cond_resched(); if (level == 0) { @@ -1649,32 +1581,6 @@ noinline int btrfs_inc_ref(struct btrfs_trans_handle *trans, continue; nr_file_extents++; - sorted[refi].bytenr = bytenr; - sorted[refi].slot = i; - refi++; - } else { - bytenr = btrfs_node_blockptr(buf, i); - sorted[refi].bytenr = bytenr; - sorted[refi].slot = i; - refi++; - } - } - /* - * if refi == 0, we didn't actually put anything into the sorted - * array and we're done - */ - if (refi == 0) - goto out; - - sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); - - for (i = 0; i < refi; i++) { - cond_resched(); - slot = sorted[i].slot; - bytenr = sorted[i].bytenr; - - if (level == 0) { - btrfs_item_key_to_cpu(buf, &key, slot); ret = process_func(trans, root, bytenr, orig_buf->start, buf->start, @@ -1683,25 +1589,25 @@ noinline int btrfs_inc_ref(struct btrfs_trans_handle *trans, key.objectid); if (ret) { - faili = slot; + faili = i; WARN_ON(1); goto fail; } } else { + bytenr = btrfs_node_blockptr(buf, i); ret = process_func(trans, root, bytenr, orig_buf->start, buf->start, orig_root, ref_root, orig_generation, ref_generation, level - 1); if (ret) { - faili = slot; + faili = i; WARN_ON(1); goto fail; } } } out: - kfree(sorted); if (nr_extents) { if (level == 0) *nr_extents = nr_file_extents; @@ -1710,7 +1616,6 @@ noinline int btrfs_inc_ref(struct btrfs_trans_handle *trans, } return 0; fail: - kfree(sorted); WARN_ON(1); return ret; } @@ -1913,7 +1818,6 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, found->bytes_pinned = 0; found->bytes_reserved = 0; found->bytes_readonly = 0; - found->bytes_delalloc = 0; found->full = 0; found->force_alloc = 0; *space_info = found; @@ -1977,233 +1881,6 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) return flags; } -static u64 btrfs_get_alloc_profile(struct btrfs_root *root, u64 data) -{ - struct btrfs_fs_info *info = root->fs_info; - u64 alloc_profile; - - if (data) { - alloc_profile = info->avail_data_alloc_bits & - info->data_alloc_profile; - data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; - } else if (root == root->fs_info->chunk_root) { - alloc_profile = info->avail_system_alloc_bits & - info->system_alloc_profile; - data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; - } else { - alloc_profile = info->avail_metadata_alloc_bits & - info->metadata_alloc_profile; - data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; - } - - return btrfs_reduce_alloc_profile(root, data); -} - -void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *inode) -{ - u64 alloc_target; - - alloc_target = btrfs_get_alloc_profile(root, 1); - BTRFS_I(inode)->space_info = __find_space_info(root->fs_info, - alloc_target); -} - -/* - * for now this just makes sure we have at least 5% of our metadata space free - * for use. - */ -int btrfs_check_metadata_free_space(struct btrfs_root *root) -{ - struct btrfs_fs_info *info = root->fs_info; - struct btrfs_space_info *meta_sinfo; - u64 alloc_target, thresh; - int committed = 0, ret; - - /* get the space info for where the metadata will live */ - alloc_target = btrfs_get_alloc_profile(root, 0); - meta_sinfo = __find_space_info(info, alloc_target); - -again: - spin_lock(&meta_sinfo->lock); - if (!meta_sinfo->full) - thresh = meta_sinfo->total_bytes * 80; - else - thresh = meta_sinfo->total_bytes * 95; - - do_div(thresh, 100); - - if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved + - meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly > thresh) { - struct btrfs_trans_handle *trans; - if (!meta_sinfo->full) { - meta_sinfo->force_alloc = 1; - spin_unlock(&meta_sinfo->lock); - - trans = btrfs_start_transaction(root, 1); - if (!trans) - return -ENOMEM; - - ret = do_chunk_alloc(trans, root->fs_info->extent_root, - 2 * 1024 * 1024, alloc_target, 0); - btrfs_end_transaction(trans, root); - goto again; - } - spin_unlock(&meta_sinfo->lock); - - if (!committed) { - committed = 1; - trans = btrfs_join_transaction(root, 1); - if (!trans) - return -ENOMEM; - ret = btrfs_commit_transaction(trans, root); - if (ret) - return ret; - goto again; - } - return -ENOSPC; - } - spin_unlock(&meta_sinfo->lock); - - return 0; -} - -/* - * This will check the space that the inode allocates from to make sure we have - * enough space for bytes. - */ -int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, - u64 bytes) -{ - struct btrfs_space_info *data_sinfo; - int ret = 0, committed = 0; - - /* make sure bytes are sectorsize aligned */ - bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); - - data_sinfo = BTRFS_I(inode)->space_info; -again: - /* make sure we have enough space to handle the data first */ - spin_lock(&data_sinfo->lock); - if (data_sinfo->total_bytes - data_sinfo->bytes_used - - data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved - - data_sinfo->bytes_pinned - data_sinfo->bytes_readonly - - data_sinfo->bytes_may_use < bytes) { - struct btrfs_trans_handle *trans; - - /* - * if we don't have enough free bytes in this space then we need - * to alloc a new chunk. - */ - if (!data_sinfo->full) { - u64 alloc_target; - - data_sinfo->force_alloc = 1; - spin_unlock(&data_sinfo->lock); - - alloc_target = btrfs_get_alloc_profile(root, 1); - trans = btrfs_start_transaction(root, 1); - if (!trans) - return -ENOMEM; - - ret = do_chunk_alloc(trans, root->fs_info->extent_root, - bytes + 2 * 1024 * 1024, - alloc_target, 0); - btrfs_end_transaction(trans, root); - if (ret) - return ret; - goto again; - } - spin_unlock(&data_sinfo->lock); - - /* commit the current transaction and try again */ - if (!committed) { - committed = 1; - trans = btrfs_join_transaction(root, 1); - if (!trans) - return -ENOMEM; - ret = btrfs_commit_transaction(trans, root); - if (ret) - return ret; - goto again; - } - - printk(KERN_ERR "no space left, need %llu, %llu delalloc bytes" - ", %llu bytes_used, %llu bytes_reserved, " - "%llu bytes_pinned, %llu bytes_readonly, %llu may use" - "%llu total\n", bytes, data_sinfo->bytes_delalloc, - data_sinfo->bytes_used, data_sinfo->bytes_reserved, - data_sinfo->bytes_pinned, data_sinfo->bytes_readonly, - data_sinfo->bytes_may_use, data_sinfo->total_bytes); - return -ENOSPC; - } - data_sinfo->bytes_may_use += bytes; - BTRFS_I(inode)->reserved_bytes += bytes; - spin_unlock(&data_sinfo->lock); - - return btrfs_check_metadata_free_space(root); -} - -/* - * if there was an error for whatever reason after calling - * btrfs_check_data_free_space, call this so we can cleanup the counters. - */ -void btrfs_free_reserved_data_space(struct btrfs_root *root, - struct inode *inode, u64 bytes) -{ - struct btrfs_space_info *data_sinfo; - - /* make sure bytes are sectorsize aligned */ - bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); - - data_sinfo = BTRFS_I(inode)->space_info; - spin_lock(&data_sinfo->lock); - data_sinfo->bytes_may_use -= bytes; - BTRFS_I(inode)->reserved_bytes -= bytes; - spin_unlock(&data_sinfo->lock); -} - -/* called when we are adding a delalloc extent to the inode's io_tree */ -void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, - u64 bytes) -{ - struct btrfs_space_info *data_sinfo; - - /* get the space info for where this inode will be storing its data */ - data_sinfo = BTRFS_I(inode)->space_info; - - /* make sure we have enough space to handle the data first */ - spin_lock(&data_sinfo->lock); - data_sinfo->bytes_delalloc += bytes; - - /* - * we are adding a delalloc extent without calling - * btrfs_check_data_free_space first. This happens on a weird - * writepage condition, but shouldn't hurt our accounting - */ - if (unlikely(bytes > BTRFS_I(inode)->reserved_bytes)) { - data_sinfo->bytes_may_use -= BTRFS_I(inode)->reserved_bytes; - BTRFS_I(inode)->reserved_bytes = 0; - } else { - data_sinfo->bytes_may_use -= bytes; - BTRFS_I(inode)->reserved_bytes -= bytes; - } - - spin_unlock(&data_sinfo->lock); -} - -/* called when we are clearing an delalloc extent from the inode's io_tree */ -void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, - u64 bytes) -{ - struct btrfs_space_info *info; - - info = BTRFS_I(inode)->space_info; - - spin_lock(&info->lock); - info->bytes_delalloc -= bytes; - spin_unlock(&info->lock); -} - static int do_chunk_alloc(struct btrfs_trans_handle *trans, struct btrfs_root *extent_root, u64 alloc_bytes, u64 flags, int force) @@ -2460,12 +2137,13 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, u64 end; u64 priv; u64 search = 0; + u64 skipped = 0; struct btrfs_fs_info *info = extent_root->fs_info; struct btrfs_path *path; struct pending_extent_op *extent_op, *tmp; struct list_head insert_list, update_list; int ret; - int num_inserts = 0, max_inserts, restart = 0; + int num_inserts = 0, max_inserts; path = btrfs_alloc_path(); INIT_LIST_HEAD(&insert_list); @@ -2481,19 +2159,18 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, ret = find_first_extent_bit(&info->extent_ins, search, &start, &end, EXTENT_WRITEBACK); if (ret) { - if (restart && !num_inserts && - list_empty(&update_list)) { - restart = 0; + if (skipped && all && !num_inserts) { + skipped = 0; search = 0; continue; } + mutex_unlock(&info->extent_ins_mutex); break; } ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); if (!ret) { - if (all) - restart = 1; + skipped = 1; search = end + 1; if (need_resched()) { mutex_unlock(&info->extent_ins_mutex); @@ -2512,7 +2189,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, list_add_tail(&extent_op->list, &insert_list); search = end + 1; if (num_inserts == max_inserts) { - restart = 1; + mutex_unlock(&info->extent_ins_mutex); break; } } else if (extent_op->type == PENDING_BACKREF_UPDATE) { @@ -2528,6 +2205,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, * somebody marked this thing for deletion then just unlock it and be * done, the free_extents will handle it */ + mutex_lock(&info->extent_ins_mutex); list_for_each_entry_safe(extent_op, tmp, &update_list, list) { clear_extent_bits(&info->extent_ins, extent_op->bytenr, extent_op->bytenr + extent_op->num_bytes - 1, @@ -2549,10 +2227,6 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, if (!list_empty(&update_list)) { ret = update_backrefs(trans, extent_root, path, &update_list); BUG_ON(ret); - - /* we may have COW'ed new blocks, so lets start over */ - if (all) - restart = 1; } /* @@ -2560,9 +2234,9 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, * need to make sure everything is cleaned then reset everything and * go back to the beginning */ - if (!num_inserts && restart) { + if (!num_inserts && all && skipped) { search = 0; - restart = 0; + skipped = 0; INIT_LIST_HEAD(&update_list); INIT_LIST_HEAD(&insert_list); goto again; @@ -2619,19 +2293,27 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, BUG_ON(ret); /* - * if restart is set for whatever reason we need to go back and start - * searching through the pending list again. - * - * We just inserted some extents, which could have resulted in new - * blocks being allocated, which would result in new blocks needing - * updates, so if all is set we _must_ restart to get the updated - * blocks. + * if we broke out of the loop in order to insert stuff because we hit + * the maximum number of inserts at a time we can handle, then loop + * back and pick up where we left off + */ + if (num_inserts == max_inserts) { + INIT_LIST_HEAD(&insert_list); + INIT_LIST_HEAD(&update_list); + num_inserts = 0; + goto again; + } + + /* + * again, if we need to make absolutely sure there are no more pending + * extent operations left and we know that we skipped some, go back to + * the beginning and do it all again */ - if (restart || all) { + if (all && skipped) { INIT_LIST_HEAD(&insert_list); INIT_LIST_HEAD(&update_list); search = 0; - restart = 0; + skipped = 0; num_inserts = 0; goto again; } @@ -2865,7 +2547,6 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, if (ret) { if (all && skipped && !nr) { search = 0; - skipped = 0; continue; } mutex_unlock(&info->extent_ins_mutex); @@ -2952,8 +2633,6 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, goto again; } - if (!err) - finish_current_insert(trans, extent_root, 0); return err; } @@ -3021,9 +2700,13 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, /* if metadata always pin */ if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID) { if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { - mutex_lock(&root->fs_info->pinned_mutex); - btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); - mutex_unlock(&root->fs_info->pinned_mutex); + struct btrfs_block_group_cache *cache; + + /* btrfs_free_reserved_extent */ + cache = btrfs_lookup_block_group(root->fs_info, bytenr); + BUG_ON(!cache); + btrfs_add_free_space(cache, bytenr, num_bytes); + put_block_group(cache); update_reserved_extents(root, bytenr, num_bytes, 0); return 0; } @@ -3104,8 +2787,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, if (data & BTRFS_BLOCK_GROUP_METADATA) { last_ptr = &root->fs_info->last_alloc; - if (!btrfs_test_opt(root, SSD)) - empty_cluster = 64 * 1024; + empty_cluster = 64 * 1024; } if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) @@ -3332,18 +3014,16 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, static void dump_space_info(struct btrfs_space_info *info, u64 bytes) { struct btrfs_block_group_cache *cache; + struct list_head *l; printk(KERN_INFO "space_info has %llu free, is %sfull\n", (unsigned long long)(info->total_bytes - info->bytes_used - info->bytes_pinned - info->bytes_reserved), (info->full) ? "" : "not "); - printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu," - " may_use=%llu, used=%llu\n", info->total_bytes, - info->bytes_pinned, info->bytes_delalloc, info->bytes_may_use, - info->bytes_used); down_read(&info->groups_sem); - list_for_each_entry(cache, &info->block_groups, list) { + list_for_each(l, &info->block_groups) { + cache = list_entry(l, struct btrfs_block_group_cache, list); spin_lock(&cache->lock); printk(KERN_INFO "block group %llu has %llu bytes, %llu used " "%llu pinned %llu reserved\n", @@ -3367,10 +3047,24 @@ static int __btrfs_reserve_extent(struct btrfs_trans_handle *trans, { int ret; u64 search_start = 0; + u64 alloc_profile; struct btrfs_fs_info *info = root->fs_info; - data = btrfs_get_alloc_profile(root, data); + if (data) { + alloc_profile = info->avail_data_alloc_bits & + info->data_alloc_profile; + data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; + } else if (root == root->fs_info->chunk_root) { + alloc_profile = info->avail_system_alloc_bits & + info->system_alloc_profile; + data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; + } else { + alloc_profile = info->avail_metadata_alloc_bits & + info->metadata_alloc_profile; + data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; + } again: + data = btrfs_reduce_alloc_profile(root, data); /* * the only place that sets empty_size is btrfs_realloc_node, which * is not called recursively on allocations @@ -3638,8 +3332,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, - u64 bytenr, u32 blocksize, - int level) + u64 bytenr, u32 blocksize) { struct extent_buffer *buf; @@ -3647,13 +3340,9 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, if (!buf) return ERR_PTR(-ENOMEM); btrfs_set_header_generation(buf, trans->transid); - btrfs_set_buffer_lockdep_class(buf, level); btrfs_tree_lock(buf); clean_tree_block(trans, root, buf); - - btrfs_set_lock_blocking(buf); btrfs_set_buffer_uptodate(buf); - if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { set_extent_dirty(&root->dirty_log_pages, buf->start, buf->start + buf->len - 1, GFP_NOFS); @@ -3662,7 +3351,6 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, buf->start + buf->len - 1, GFP_NOFS); } trans->blocks_used++; - /* this returns a buffer locked for blocking */ return buf; } @@ -3691,8 +3379,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, return ERR_PTR(ret); } - buf = btrfs_init_new_buffer(trans, root, ins.objectid, - blocksize, level); + buf = btrfs_init_new_buffer(trans, root, ins.objectid, blocksize); return buf; } @@ -3701,73 +3388,36 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, { u64 leaf_owner; u64 leaf_generation; - struct refsort *sorted; struct btrfs_key key; struct btrfs_file_extent_item *fi; int i; int nritems; int ret; - int refi = 0; - int slot; BUG_ON(!btrfs_is_leaf(leaf)); nritems = btrfs_header_nritems(leaf); leaf_owner = btrfs_header_owner(leaf); leaf_generation = btrfs_header_generation(leaf); - sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS); - /* we do this loop twice. The first time we build a list - * of the extents we have a reference on, then we sort the list - * by bytenr. The second time around we actually do the - * extent freeing. - */ for (i = 0; i < nritems; i++) { u64 disk_bytenr; cond_resched(); btrfs_item_key_to_cpu(leaf, &key, i); - - /* only extents have references, skip everything else */ if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) continue; - fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); - - /* inline extents live in the btree, they don't have refs */ if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) continue; - + /* + * FIXME make sure to insert a trans record that + * repeats the snapshot del on crash + */ disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); - - /* holes don't have refs */ if (disk_bytenr == 0) continue; - sorted[refi].bytenr = disk_bytenr; - sorted[refi].slot = i; - refi++; - } - - if (refi == 0) - goto out; - - sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); - - for (i = 0; i < refi; i++) { - u64 disk_bytenr; - - disk_bytenr = sorted[i].bytenr; - slot = sorted[i].slot; - - cond_resched(); - - btrfs_item_key_to_cpu(leaf, &key, slot); - if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) - continue; - - fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); - ret = __btrfs_free_extent(trans, root, disk_bytenr, btrfs_file_extent_disk_num_bytes(leaf, fi), leaf->start, leaf_owner, leaf_generation, @@ -3778,8 +3428,6 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, wake_up(&root->fs_info->transaction_throttle); cond_resched(); } -out: - kfree(sorted); return 0; } @@ -3789,25 +3437,9 @@ static noinline int cache_drop_leaf_ref(struct btrfs_trans_handle *trans, { int i; int ret; - struct btrfs_extent_info *info; - struct refsort *sorted; - - if (ref->nritems == 0) - return 0; + struct btrfs_extent_info *info = ref->extents; - sorted = kmalloc(sizeof(*sorted) * ref->nritems, GFP_NOFS); for (i = 0; i < ref->nritems; i++) { - sorted[i].bytenr = ref->extents[i].bytenr; - sorted[i].slot = i; - } - sort(sorted, ref->nritems, sizeof(struct refsort), refsort_cmp, NULL); - - /* - * the items in the ref were sorted when the ref was inserted - * into the ref cache, so this is already in order - */ - for (i = 0; i < ref->nritems; i++) { - info = ref->extents + sorted[i].slot; ret = __btrfs_free_extent(trans, root, info->bytenr, info->num_bytes, ref->bytenr, ref->owner, ref->generation, @@ -3821,7 +3453,6 @@ static noinline int cache_drop_leaf_ref(struct btrfs_trans_handle *trans, info++; } - kfree(sorted); return 0; } @@ -3865,152 +3496,6 @@ static int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, return ret; } -/* - * this is used while deleting old snapshots, and it drops the refs - * on a whole subtree starting from a level 1 node. - * - * The idea is to sort all the leaf pointers, and then drop the - * ref on all the leaves in order. Most of the time the leaves - * will have ref cache entries, so no leaf IOs will be required to - * find the extents they have references on. - * - * For each leaf, any references it has are also dropped in order - * - * This ends up dropping the references in something close to optimal - * order for reading and modifying the extent allocation tree. - */ -static noinline int drop_level_one_refs(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path) -{ - u64 bytenr; - u64 root_owner; - u64 root_gen; - struct extent_buffer *eb = path->nodes[1]; - struct extent_buffer *leaf; - struct btrfs_leaf_ref *ref; - struct refsort *sorted = NULL; - int nritems = btrfs_header_nritems(eb); - int ret; - int i; - int refi = 0; - int slot = path->slots[1]; - u32 blocksize = btrfs_level_size(root, 0); - u32 refs; - - if (nritems == 0) - goto out; - - root_owner = btrfs_header_owner(eb); - root_gen = btrfs_header_generation(eb); - sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS); - - /* - * step one, sort all the leaf pointers so we don't scribble - * randomly into the extent allocation tree - */ - for (i = slot; i < nritems; i++) { - sorted[refi].bytenr = btrfs_node_blockptr(eb, i); - sorted[refi].slot = i; - refi++; - } - - /* - * nritems won't be zero, but if we're picking up drop_snapshot - * after a crash, slot might be > 0, so double check things - * just in case. - */ - if (refi == 0) - goto out; - - sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); - - /* - * the first loop frees everything the leaves point to - */ - for (i = 0; i < refi; i++) { - u64 ptr_gen; - - bytenr = sorted[i].bytenr; - - /* - * check the reference count on this leaf. If it is > 1 - * we just decrement it below and don't update any - * of the refs the leaf points to. - */ - ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs); - BUG_ON(ret); - if (refs != 1) - continue; - - ptr_gen = btrfs_node_ptr_generation(eb, sorted[i].slot); - - /* - * the leaf only had one reference, which means the - * only thing pointing to this leaf is the snapshot - * we're deleting. It isn't possible for the reference - * count to increase again later - * - * The reference cache is checked for the leaf, - * and if found we'll be able to drop any refs held by - * the leaf without needing to read it in. - */ - ref = btrfs_lookup_leaf_ref(root, bytenr); - if (ref && ref->generation != ptr_gen) { - btrfs_free_leaf_ref(root, ref); - ref = NULL; - } - if (ref) { - ret = cache_drop_leaf_ref(trans, root, ref); - BUG_ON(ret); - btrfs_remove_leaf_ref(root, ref); - btrfs_free_leaf_ref(root, ref); - } else { - /* - * the leaf wasn't in the reference cache, so - * we have to read it. - */ - leaf = read_tree_block(root, bytenr, blocksize, - ptr_gen); - ret = btrfs_drop_leaf_ref(trans, root, leaf); - BUG_ON(ret); - free_extent_buffer(leaf); - } - atomic_inc(&root->fs_info->throttle_gen); - wake_up(&root->fs_info->transaction_throttle); - cond_resched(); - } - - /* - * run through the loop again to free the refs on the leaves. - * This is faster than doing it in the loop above because - * the leaves are likely to be clustered together. We end up - * working in nice chunks on the extent allocation tree. - */ - for (i = 0; i < refi; i++) { - bytenr = sorted[i].bytenr; - ret = __btrfs_free_extent(trans, root, bytenr, - blocksize, eb->start, - root_owner, root_gen, 0, 1); - BUG_ON(ret); - - atomic_inc(&root->fs_info->throttle_gen); - wake_up(&root->fs_info->transaction_throttle); - cond_resched(); - } -out: - kfree(sorted); - - /* - * update the path to show we've processed the entire level 1 - * node. This will get saved into the root's drop_snapshot_progress - * field so these drops are not repeated again if this transaction - * commits. - */ - path->slots[1] = nritems; - return 0; -} - /* * helper function for drop_snapshot, this walks down the tree dropping ref * counts as it goes. @@ -4026,6 +3511,7 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, struct extent_buffer *next; struct extent_buffer *cur; struct extent_buffer *parent; + struct btrfs_leaf_ref *ref; u32 blocksize; int ret; u32 refs; @@ -4052,46 +3538,17 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, if (path->slots[*level] >= btrfs_header_nritems(cur)) break; - - /* the new code goes down to level 1 and does all the - * leaves pointed to that node in bulk. So, this check - * for level 0 will always be false. - * - * But, the disk format allows the drop_snapshot_progress - * field in the root to leave things in a state where - * a leaf will need cleaning up here. If someone crashes - * with the old code and then boots with the new code, - * we might find a leaf here. - */ if (*level == 0) { ret = btrfs_drop_leaf_ref(trans, root, cur); BUG_ON(ret); break; } - - /* - * once we get to level one, process the whole node - * at once, including everything below it. - */ - if (*level == 1) { - ret = drop_level_one_refs(trans, root, path); - BUG_ON(ret); - break; - } - bytenr = btrfs_node_blockptr(cur, path->slots[*level]); ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); blocksize = btrfs_level_size(root, *level - 1); ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs); BUG_ON(ret); - - /* - * if there is more than one reference, we don't need - * to read that node to drop any references it has. We - * just drop the ref we hold on that node and move on to the - * next slot in this level. - */ if (refs != 1) { parent = path->nodes[*level]; root_owner = btrfs_header_owner(parent); @@ -4110,12 +3567,46 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, continue; } - /* - * we need to keep freeing things in the next level down. - * read the block and loop around to process it + * at this point, we have a single ref, and since the + * only place referencing this extent is a dead root + * the reference count should never go higher. + * So, we don't need to check it again */ - next = read_tree_block(root, bytenr, blocksize, ptr_gen); + if (*level == 1) { + ref = btrfs_lookup_leaf_ref(root, bytenr); + if (ref && ref->generation != ptr_gen) { + btrfs_free_leaf_ref(root, ref); + ref = NULL; + } + if (ref) { + ret = cache_drop_leaf_ref(trans, root, ref); + BUG_ON(ret); + btrfs_remove_leaf_ref(root, ref); + btrfs_free_leaf_ref(root, ref); + *level = 0; + break; + } + } + next = btrfs_find_tree_block(root, bytenr, blocksize); + if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { + free_extent_buffer(next); + + next = read_tree_block(root, bytenr, blocksize, + ptr_gen); + cond_resched(); +#if 0 + /* + * this is a debugging check and can go away + * the ref should never go all the way down to 1 + * at this point + */ + ret = lookup_extent_ref(NULL, root, bytenr, blocksize, + &refs); + BUG_ON(ret); + WARN_ON(refs != 1); +#endif + } WARN_ON(*level <= 0); if (path->nodes[*level-1]) free_extent_buffer(path->nodes[*level-1]); @@ -4140,16 +3631,11 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, root_owner = btrfs_header_owner(parent); root_gen = btrfs_header_generation(parent); - /* - * cleanup and free the reference on the last node - * we processed - */ ret = __btrfs_free_extent(trans, root, bytenr, blocksize, parent->start, root_owner, root_gen, *level, 1); free_extent_buffer(path->nodes[*level]); path->nodes[*level] = NULL; - *level += 1; BUG_ON(ret); @@ -4201,7 +3687,6 @@ static noinline int walk_down_subtree(struct btrfs_trans_handle *trans, next = read_tree_block(root, bytenr, blocksize, ptr_gen); btrfs_tree_lock(next); - btrfs_set_lock_blocking(next); ret = btrfs_lookup_extent_ref(trans, root, bytenr, blocksize, &refs); @@ -4269,13 +3754,6 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, if (slot < btrfs_header_nritems(path->nodes[i]) - 1) { struct extent_buffer *node; struct btrfs_disk_key disk_key; - - /* - * there is more work to do in this level. - * Update the drop_progress marker to reflect - * the work we've done so far, and then bump - * the slot number - */ node = path->nodes[i]; path->slots[i]++; *level = i; @@ -4287,11 +3765,6 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, return 0; } else { struct extent_buffer *parent; - - /* - * this whole node is done, free our reference - * on it and go up one level - */ if (path->nodes[*level] == root->node) parent = path->nodes[*level]; else @@ -4971,7 +4444,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans, u64 lock_end = 0; u64 num_bytes; u64 ext_offset; - u64 search_end = (u64)-1; + u64 first_pos; u32 nritems; int nr_scaned = 0; int extent_locked = 0; @@ -4979,6 +4452,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans, int ret; memcpy(&key, leaf_key, sizeof(key)); + first_pos = INT_LIMIT(loff_t) - extent_key->offset; if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { if (key.objectid < ref_path->owner_objectid || (key.objectid == ref_path->owner_objectid && @@ -5027,7 +4501,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans, if ((key.objectid > ref_path->owner_objectid) || (key.objectid == ref_path->owner_objectid && key.type > BTRFS_EXTENT_DATA_KEY) || - key.offset >= search_end) + (key.offset >= first_pos + extent_key->offset)) break; } @@ -5060,10 +4534,8 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans, num_bytes = btrfs_file_extent_num_bytes(leaf, fi); ext_offset = btrfs_file_extent_offset(leaf, fi); - if (search_end == (u64)-1) { - search_end = key.offset - ext_offset + - btrfs_file_extent_ram_bytes(leaf, fi); - } + if (first_pos > key.offset - ext_offset) + first_pos = key.offset - ext_offset; if (!extent_locked) { lock_start = key.offset; @@ -5252,7 +4724,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans, } skip: if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS && - key.offset >= search_end) + key.offset >= first_pos + extent_key->offset) break; cond_resched(); @@ -5306,7 +4778,6 @@ int btrfs_reloc_tree_cache_ref(struct btrfs_trans_handle *trans, ref->bytenr = buf->start; ref->owner = btrfs_header_owner(buf); ref->generation = btrfs_header_generation(buf); - ret = btrfs_add_leaf_ref(root, ref, 0); WARN_ON(ret); btrfs_free_leaf_ref(root, ref); @@ -5880,9 +5351,7 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root, prev_block = block_start; } - mutex_lock(&extent_root->fs_info->trans_mutex); btrfs_record_root_in_trans(found_root); - mutex_unlock(&extent_root->fs_info->trans_mutex); if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { /* * try to update data extent references while @@ -6488,11 +5957,9 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, path = btrfs_alloc_path(); BUG_ON(!path); - spin_lock(&root->fs_info->block_group_cache_lock); + btrfs_remove_free_space_cache(block_group); rb_erase(&block_group->cache_node, &root->fs_info->block_group_cache_tree); - spin_unlock(&root->fs_info->block_group_cache_lock); - btrfs_remove_free_space_cache(block_group); down_write(&block_group->space_info->groups_sem); list_del(&block_group->list); up_write(&block_group->space_info->groups_sem); diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index ebe6b29e6069..e086d407f1fa 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include "extent_io.h" @@ -30,7 +31,7 @@ static LIST_HEAD(buffers); static LIST_HEAD(states); #define LEAK_DEBUG 0 -#if LEAK_DEBUG +#ifdef LEAK_DEBUG static DEFINE_SPINLOCK(leak_lock); #endif @@ -119,7 +120,7 @@ void extent_io_tree_init(struct extent_io_tree *tree, static struct extent_state *alloc_extent_state(gfp_t mask) { struct extent_state *state; -#if LEAK_DEBUG +#ifdef LEAK_DEBUG unsigned long flags; #endif @@ -129,7 +130,7 @@ static struct extent_state *alloc_extent_state(gfp_t mask) state->state = 0; state->private = 0; state->tree = NULL; -#if LEAK_DEBUG +#ifdef LEAK_DEBUG spin_lock_irqsave(&leak_lock, flags); list_add(&state->leak_list, &states); spin_unlock_irqrestore(&leak_lock, flags); @@ -144,11 +145,11 @@ static void free_extent_state(struct extent_state *state) if (!state) return; if (atomic_dec_and_test(&state->refs)) { -#if LEAK_DEBUG +#ifdef LEAK_DEBUG unsigned long flags; #endif WARN_ON(state->tree); -#if LEAK_DEBUG +#ifdef LEAK_DEBUG spin_lock_irqsave(&leak_lock, flags); list_del(&state->leak_list); spin_unlock_irqrestore(&leak_lock, flags); @@ -415,6 +416,8 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, node = tree_insert(&tree->state, prealloc->end, &prealloc->rb_node); if (node) { + struct extent_state *found; + found = rb_entry(node, struct extent_state, rb_node); free_extent_state(prealloc); return -EEXIST; } @@ -2375,6 +2378,11 @@ static int extent_write_cache_pages(struct extent_io_tree *tree, int scanned = 0; int range_whole = 0; + if (wbc->nonblocking && bdi_write_congested(bdi)) { + wbc->encountered_congestion = 1; + return 0; + } + pagevec_init(&pvec, 0); if (wbc->range_cyclic) { index = mapping->writeback_index; /* Start from prev offset */ @@ -2847,98 +2855,6 @@ sector_t extent_bmap(struct address_space *mapping, sector_t iblock, return sector; } -int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, - __u64 start, __u64 len, get_extent_t *get_extent) -{ - int ret; - u64 off = start; - u64 max = start + len; - u32 flags = 0; - u64 disko = 0; - struct extent_map *em = NULL; - int end = 0; - u64 em_start = 0, em_len = 0; - unsigned long emflags; - ret = 0; - - if (len == 0) - return -EINVAL; - - lock_extent(&BTRFS_I(inode)->io_tree, start, start + len, - GFP_NOFS); - em = get_extent(inode, NULL, 0, off, max - off, 0); - if (!em) - goto out; - if (IS_ERR(em)) { - ret = PTR_ERR(em); - goto out; - } - while (!end) { - off = em->start + em->len; - if (off >= max) - end = 1; - - em_start = em->start; - em_len = em->len; - - disko = 0; - flags = 0; - - switch (em->block_start) { - case EXTENT_MAP_LAST_BYTE: - end = 1; - flags |= FIEMAP_EXTENT_LAST; - break; - case EXTENT_MAP_HOLE: - flags |= FIEMAP_EXTENT_UNWRITTEN; - break; - case EXTENT_MAP_INLINE: - flags |= (FIEMAP_EXTENT_DATA_INLINE | - FIEMAP_EXTENT_NOT_ALIGNED); - break; - case EXTENT_MAP_DELALLOC: - flags |= (FIEMAP_EXTENT_DELALLOC | - FIEMAP_EXTENT_UNKNOWN); - break; - default: - disko = em->block_start; - break; - } - if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) - flags |= FIEMAP_EXTENT_ENCODED; - - emflags = em->flags; - free_extent_map(em); - em = NULL; - - if (!end) { - em = get_extent(inode, NULL, 0, off, max - off, 0); - if (!em) - goto out; - if (IS_ERR(em)) { - ret = PTR_ERR(em); - goto out; - } - emflags = em->flags; - } - if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) { - flags |= FIEMAP_EXTENT_LAST; - end = 1; - } - - ret = fiemap_fill_next_extent(fieinfo, em_start, disko, - em_len, flags); - if (ret) - goto out_free; - } -out_free: - free_extent_map(em); -out: - unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len, - GFP_NOFS); - return ret; -} - static inline struct page *extent_buffer_page(struct extent_buffer *eb, unsigned long i) { @@ -2976,17 +2892,15 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, gfp_t mask) { struct extent_buffer *eb = NULL; -#if LEAK_DEBUG +#ifdef LEAK_DEBUG unsigned long flags; #endif eb = kmem_cache_zalloc(extent_buffer_cache, mask); eb->start = start; eb->len = len; - spin_lock_init(&eb->lock); - init_waitqueue_head(&eb->lock_wq); - -#if LEAK_DEBUG + mutex_init(&eb->mutex); +#ifdef LEAK_DEBUG spin_lock_irqsave(&leak_lock, flags); list_add(&eb->leak_list, &buffers); spin_unlock_irqrestore(&leak_lock, flags); @@ -2998,7 +2912,7 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, static void __free_extent_buffer(struct extent_buffer *eb) { -#if LEAK_DEBUG +#ifdef LEAK_DEBUG unsigned long flags; spin_lock_irqsave(&leak_lock, flags); list_del(&eb->leak_list); @@ -3066,7 +2980,8 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, unlock_page(p); } if (uptodate) - set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); + eb->flags |= EXTENT_UPTODATE; + eb->flags |= EXTENT_BUFFER_FILLED; spin_lock(&tree->buffer_lock); exists = buffer_tree_insert(tree, start, &eb->rb_node); @@ -3220,7 +3135,7 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree, unsigned long num_pages; num_pages = num_extent_pages(eb->start, eb->len); - clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); + eb->flags &= ~EXTENT_UPTODATE; clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, GFP_NOFS); @@ -3291,7 +3206,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree, struct page *page; int pg_uptodate = 1; - if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) + if (eb->flags & EXTENT_UPTODATE) return 1; ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, @@ -3327,7 +3242,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, struct bio *bio = NULL; unsigned long bio_flags = 0; - if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) + if (eb->flags & EXTENT_UPTODATE) return 0; if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, @@ -3358,7 +3273,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, } if (all_uptodate) { if (start_i == 0) - set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); + eb->flags |= EXTENT_UPTODATE; goto unlock_exit; } @@ -3394,7 +3309,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, } if (!ret) - set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); + eb->flags |= EXTENT_UPTODATE; return ret; unlock_exit: @@ -3491,6 +3406,7 @@ int map_extent_buffer(struct extent_buffer *eb, unsigned long start, unmap_extent_buffer(eb, eb->map_token, km); eb->map_token = NULL; save = 1; + WARN_ON(!mutex_is_locked(&eb->mutex)); } err = map_private_extent_buffer(eb, start, min_len, token, map, map_start, map_len, km); diff --git a/trunk/fs/btrfs/extent_io.h b/trunk/fs/btrfs/extent_io.h index 1f9df88afbf6..c5b483a79137 100644 --- a/trunk/fs/btrfs/extent_io.h +++ b/trunk/fs/btrfs/extent_io.h @@ -22,10 +22,6 @@ /* flags for bio submission */ #define EXTENT_BIO_COMPRESSED 1 -/* these are bit numbers for test/set bit */ -#define EXTENT_BUFFER_UPTODATE 0 -#define EXTENT_BUFFER_BLOCKING 1 - /* * page->private values. Every page that is controlled by the extent * map has page->private set to one. @@ -99,19 +95,11 @@ struct extent_buffer { unsigned long map_start; unsigned long map_len; struct page *first_page; - unsigned long bflags; atomic_t refs; + int flags; struct list_head leak_list; struct rb_node rb_node; - - /* the spinlock is used to protect most operations */ - spinlock_t lock; - - /* - * when we keep the lock held while blocking, waiters go onto - * the wq - */ - wait_queue_head_t lock_wq; + struct mutex mutex; }; struct extent_map_tree; @@ -205,8 +193,6 @@ int extent_commit_write(struct extent_io_tree *tree, unsigned from, unsigned to); sector_t extent_bmap(struct address_space *mapping, sector_t iblock, get_extent_t *get_extent); -int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, - __u64 start, __u64 len, get_extent_t *get_extent); int set_range_dirty(struct extent_io_tree *tree, u64 start, u64 end); int set_state_private(struct extent_io_tree *tree, u64 start, u64 private); int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private); diff --git a/trunk/fs/btrfs/extent_map.c b/trunk/fs/btrfs/extent_map.c index 50da69da20ce..4a83e33ada32 100644 --- a/trunk/fs/btrfs/extent_map.c +++ b/trunk/fs/btrfs/extent_map.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "extent_map.h" diff --git a/trunk/fs/btrfs/file.c b/trunk/fs/btrfs/file.c index dc78954861b3..90268334145e 100644 --- a/trunk/fs/btrfs/file.c +++ b/trunk/fs/btrfs/file.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "ctree.h" #include "disk-io.h" #include "transaction.h" @@ -1091,24 +1092,19 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, WARN_ON(num_pages > nrptrs); memset(pages, 0, sizeof(struct page *) * nrptrs); - ret = btrfs_check_data_free_space(root, inode, write_bytes); + ret = btrfs_check_free_space(root, write_bytes, 0); if (ret) goto out; ret = prepare_pages(root, file, pages, num_pages, pos, first_index, last_index, write_bytes); - if (ret) { - btrfs_free_reserved_data_space(root, inode, - write_bytes); + if (ret) goto out; - } ret = btrfs_copy_from_user(pos, num_pages, write_bytes, pages, buf); if (ret) { - btrfs_free_reserved_data_space(root, inode, - write_bytes); btrfs_drop_pages(pages, num_pages); goto out; } @@ -1116,11 +1112,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, ret = dirty_and_release_pages(NULL, root, file, pages, num_pages, pos, write_bytes); btrfs_drop_pages(pages, num_pages); - if (ret) { - btrfs_free_reserved_data_space(root, inode, - write_bytes); + if (ret) goto out; - } if (will_write) { btrfs_fdatawrite_range(inode->i_mapping, pos, @@ -1144,8 +1137,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, } out: mutex_unlock(&inode->i_mutex); - if (ret) - err = ret; out_nolock: kfree(pages); @@ -1224,15 +1215,15 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) } mutex_unlock(&root->fs_info->trans_mutex); - root->log_batch++; + root->fs_info->tree_log_batch++; filemap_fdatawrite(inode->i_mapping); btrfs_wait_ordered_range(inode, 0, (u64)-1); - root->log_batch++; + root->fs_info->tree_log_batch++; /* * ok we haven't committed the transaction yet, lets do a commit */ - if (file && file->private_data) + if (file->private_data) btrfs_ioctl_trans_end(file); trans = btrfs_start_transaction(root, 1); @@ -1241,7 +1232,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) goto out; } - ret = btrfs_log_dentry_safe(trans, root, dentry); + ret = btrfs_log_dentry_safe(trans, root, file->f_dentry); if (ret < 0) goto out; @@ -1255,7 +1246,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) * file again, but that will end up using the synchronization * inside btrfs_sync_log to keep things safe. */ - mutex_unlock(&dentry->d_inode->i_mutex); + mutex_unlock(&file->f_dentry->d_inode->i_mutex); if (ret > 0) { ret = btrfs_commit_transaction(trans, root); @@ -1263,7 +1254,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) btrfs_sync_log(trans, root); ret = btrfs_end_transaction(trans, root); } - mutex_lock(&dentry->d_inode->i_mutex); + mutex_lock(&file->f_dentry->d_inode->i_mutex); out: return ret > 0 ? EIO : ret; } diff --git a/trunk/fs/btrfs/inode-map.c b/trunk/fs/btrfs/inode-map.c index cc7334d833c9..2aa79873eb46 100644 --- a/trunk/fs/btrfs/inode-map.c +++ b/trunk/fs/btrfs/inode-map.c @@ -84,6 +84,7 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, search_key.type = 0; search_key.offset = 0; + btrfs_init_path(path); start_found = 0; ret = btrfs_search_slot(trans, root, &search_key, path, 0, 0); if (ret < 0) diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 7d4f948bc22a..8adfe059ab41 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -50,7 +51,6 @@ #include "tree-log.h" #include "ref-cache.h" #include "compression.h" -#include "locking.h" struct btrfs_iget_args { u64 ino; @@ -91,14 +91,32 @@ static noinline int cow_file_range(struct inode *inode, u64 start, u64 end, int *page_started, unsigned long *nr_written, int unlock); -static int btrfs_init_inode_security(struct inode *inode, struct inode *dir) +/* + * a very lame attempt at stopping writes when the FS is 85% full. There + * are countless ways this is incorrect, but it is better than nothing. + */ +int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, + int for_del) { - int err; + u64 total; + u64 used; + u64 thresh; + int ret = 0; - err = btrfs_init_acl(inode, dir); - if (!err) - err = btrfs_xattr_security_init(inode, dir); - return err; + spin_lock(&root->fs_info->delalloc_lock); + total = btrfs_super_total_bytes(&root->fs_info->super_copy); + used = btrfs_super_bytes_used(&root->fs_info->super_copy); + if (for_del) + thresh = total * 90; + else + thresh = total * 85; + + do_div(thresh, 100); + + if (used + root->fs_info->delalloc_bytes + num_required > thresh) + ret = -ENOSPC; + spin_unlock(&root->fs_info->delalloc_lock); + return ret; } /* @@ -332,19 +350,6 @@ static noinline int compress_file_range(struct inode *inode, nr_pages = (end >> PAGE_CACHE_SHIFT) - (start >> PAGE_CACHE_SHIFT) + 1; nr_pages = min(nr_pages, (128 * 1024UL) / PAGE_CACHE_SIZE); - /* - * we don't want to send crud past the end of i_size through - * compression, that's just a waste of CPU time. So, if the - * end of the file is before the start of our current - * requested range of bytes, we bail out to the uncompressed - * cleanup code that can deal with all of this. - * - * It isn't really the fastest way to fix things, but this is a - * very uncommon corner. - */ - if (actual_end <= start) - goto cleanup_and_bail_uncompressed; - total_compressed = actual_end - start; /* we want to make sure that amount of ram required to uncompress @@ -489,7 +494,6 @@ static noinline int compress_file_range(struct inode *inode, goto again; } } else { -cleanup_and_bail_uncompressed: /* * No compression, but we still need to write the pages in * the file we've been given so far. redirty the locked @@ -1162,7 +1166,6 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, */ if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { struct btrfs_root *root = BTRFS_I(inode)->root; - btrfs_delalloc_reserve_space(root, inode, end - start + 1); spin_lock(&root->fs_info->delalloc_lock); BTRFS_I(inode)->delalloc_bytes += end - start + 1; root->fs_info->delalloc_bytes += end - start + 1; @@ -1196,12 +1199,9 @@ static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, (unsigned long long)end - start + 1, (unsigned long long) root->fs_info->delalloc_bytes); - btrfs_delalloc_free_space(root, inode, (u64)-1); root->fs_info->delalloc_bytes = 0; BTRFS_I(inode)->delalloc_bytes = 0; } else { - btrfs_delalloc_free_space(root, inode, - end - start + 1); root->fs_info->delalloc_bytes -= end - start + 1; BTRFS_I(inode)->delalloc_bytes -= end - start + 1; } @@ -1324,11 +1324,12 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, struct inode *inode, u64 file_offset, struct list_head *list) { + struct list_head *cur; struct btrfs_ordered_sum *sum; btrfs_set_trans_block_group(trans, inode); - - list_for_each_entry(sum, list, list) { + list_for_each(cur, list) { + sum = list_entry(cur, struct btrfs_ordered_sum, list); btrfs_csum_file_blocks(trans, BTRFS_I(inode)->root->fs_info->csum_root, sum); } @@ -2012,7 +2013,6 @@ void btrfs_read_locked_inode(struct inode *inode) BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); alloc_group_block = btrfs_inode_block_group(leaf, inode_item); - BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0, alloc_group_block, 0); btrfs_free_path(path); @@ -2039,7 +2039,6 @@ void btrfs_read_locked_inode(struct inode *inode) inode->i_mapping->backing_dev_info = &root->fs_info->bdi; break; default: - inode->i_op = &btrfs_special_inode_operations; init_special_inode(inode, inode->i_mode, rdev); break; } @@ -2109,7 +2108,6 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans, goto failed; } - btrfs_unlock_up_safe(path, 1); leaf = path->nodes[0]; inode_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_inode_item); @@ -2221,6 +2219,10 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) root = BTRFS_I(dir)->root; + ret = btrfs_check_free_space(root, 1, 1); + if (ret) + goto fail; + trans = btrfs_start_transaction(root, 1); btrfs_set_trans_block_group(trans, dir); @@ -2233,6 +2235,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) nr = trans->blocks_used; btrfs_end_transaction_throttle(trans, root); +fail: btrfs_btree_balance_dirty(root, nr); return ret; } @@ -2255,6 +2258,10 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) return -ENOTEMPTY; } + ret = btrfs_check_free_space(root, 1, 1); + if (ret) + goto fail; + trans = btrfs_start_transaction(root, 1); btrfs_set_trans_block_group(trans, dir); @@ -2271,6 +2278,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) fail_trans: nr = trans->blocks_used; ret = btrfs_end_transaction_throttle(trans, root); +fail: btrfs_btree_balance_dirty(root, nr); if (ret && !err) @@ -2421,8 +2429,6 @@ static noinline int drop_csum_leaves(struct btrfs_trans_handle *trans, ref->generation = leaf_gen; ref->nritems = 0; - btrfs_sort_leaf_ref(ref); - ret = btrfs_add_leaf_ref(root, ref, 0); WARN_ON(ret); btrfs_free_leaf_ref(root, ref); @@ -2470,7 +2476,7 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, struct btrfs_path *path; struct btrfs_key key; struct btrfs_key found_key; - u32 found_type = (u8)-1; + u32 found_type; struct extent_buffer *leaf; struct btrfs_file_extent_item *fi; u64 extent_start = 0; @@ -2497,6 +2503,8 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, key.offset = (u64)-1; key.type = (u8)-1; + btrfs_init_path(path); + search_again: ret = btrfs_search_slot(trans, root, &key, path, -1, 1); if (ret < 0) @@ -2655,8 +2663,6 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, if (pending_del_nr) goto del_pending; btrfs_release_path(root, path); - if (found_type == BTRFS_INODE_ITEM_KEY) - break; goto search_again; } @@ -2673,8 +2679,6 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, BUG_ON(ret); pending_del_nr = 0; btrfs_release_path(root, path); - if (found_type == BTRFS_INODE_ITEM_KEY) - break; goto search_again; } } @@ -2784,7 +2788,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) if (size <= hole_start) return 0; - err = btrfs_check_metadata_free_space(root); + err = btrfs_check_free_space(root, 1, 0); if (err) return err; @@ -2980,7 +2984,6 @@ static noinline void init_btrfs_i(struct inode *inode) bi->last_trans = 0; bi->logged_trans = 0; bi->delalloc_bytes = 0; - bi->reserved_bytes = 0; bi->disk_i_size = 0; bi->flags = 0; bi->index_cnt = (u64)-1; @@ -3002,7 +3005,6 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) inode->i_ino = args->ino; init_btrfs_i(inode); BTRFS_I(inode)->root = args->root; - btrfs_set_inode_space_info(args->root, inode); return 0; } @@ -3263,7 +3265,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, /* Reached end of directory/root. Bump pos past the last item. */ if (key_type == BTRFS_DIR_INDEX_KEY) - filp->f_pos = INT_LIMIT(off_t); + filp->f_pos = INT_LIMIT(typeof(filp->f_pos)); else filp->f_pos++; nopos: @@ -3423,7 +3425,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, BTRFS_I(inode)->index_cnt = 2; BTRFS_I(inode)->root = root; BTRFS_I(inode)->generation = trans->transid; - btrfs_set_inode_space_info(root, inode); if (mode & S_IFDIR) owner = 0; @@ -3457,14 +3458,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, root->highest_inode = objectid; inode->i_uid = current_fsuid(); - - if (dir && (dir->i_mode & S_ISGID)) { - inode->i_gid = dir->i_gid; - if (S_ISDIR(mode)) - mode |= S_ISGID; - } else - inode->i_gid = current_fsgid(); - + inode->i_gid = current_fsgid(); inode->i_mode = mode; inode->i_ino = objectid; inode_set_bytes(inode, 0); @@ -3571,7 +3565,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, if (!new_valid_dev(rdev)) return -EINVAL; - err = btrfs_check_metadata_free_space(root); + err = btrfs_check_free_space(root, 1, 0); if (err) goto fail; @@ -3592,7 +3586,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) goto out_unlock; - err = btrfs_init_inode_security(inode, dir); + err = btrfs_init_acl(inode, dir); if (err) { drop_inode = 1; goto out_unlock; @@ -3634,7 +3628,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, u64 objectid; u64 index = 0; - err = btrfs_check_metadata_free_space(root); + err = btrfs_check_free_space(root, 1, 0); if (err) goto fail; trans = btrfs_start_transaction(root, 1); @@ -3655,7 +3649,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) goto out_unlock; - err = btrfs_init_inode_security(inode, dir); + err = btrfs_init_acl(inode, dir); if (err) { drop_inode = 1; goto out_unlock; @@ -3702,7 +3696,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, return -ENOENT; btrfs_inc_nlink(inode); - err = btrfs_check_metadata_free_space(root); + err = btrfs_check_free_space(root, 1, 0); if (err) goto fail; err = btrfs_set_inode_index(dir, &index); @@ -3748,7 +3742,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) u64 index = 0; unsigned long nr = 1; - err = btrfs_check_metadata_free_space(root); + err = btrfs_check_free_space(root, 1, 0); if (err) goto out_unlock; @@ -3778,7 +3772,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) drop_on_err = 1; - err = btrfs_init_inode_security(inode, dir); + err = btrfs_init_acl(inode, dir); if (err) goto out_fail; @@ -4164,10 +4158,9 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, return -EINVAL; } -static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, - __u64 start, __u64 len) +static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock) { - return extent_fiemap(inode, fieinfo, start, len, btrfs_get_extent); + return extent_bmap(mapping, iblock, btrfs_get_extent); } int btrfs_readpage(struct file *file, struct page *page) @@ -4230,7 +4223,7 @@ static int btrfs_releasepage(struct page *page, gfp_t gfp_flags) { if (PageWriteback(page) || PageDirty(page)) return 0; - return __btrfs_releasepage(page, gfp_flags & GFP_NOFS); + return __btrfs_releasepage(page, gfp_flags); } static void btrfs_invalidatepage(struct page *page, unsigned long offset) @@ -4305,7 +4298,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) u64 page_start; u64 page_end; - ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE); + ret = btrfs_check_free_space(root, PAGE_CACHE_SIZE, 0); if (ret) goto out; @@ -4318,7 +4311,6 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) if ((page->mapping != inode->i_mapping) || (page_start >= size)) { - btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); /* page got truncated out from underneath us */ goto out_unlock; } @@ -4601,7 +4593,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) return -EXDEV; - ret = btrfs_check_metadata_free_space(root); + ret = btrfs_check_free_space(root, 1, 0); if (ret) goto out_unlock; @@ -4719,7 +4711,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) return -ENAMETOOLONG; - err = btrfs_check_metadata_free_space(root); + err = btrfs_check_free_space(root, 1, 0); if (err) goto out_fail; @@ -4741,7 +4733,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) goto out_unlock; - err = btrfs_init_inode_security(inode, dir); + err = btrfs_init_acl(inode, dir); if (err) { drop_inode = 1; goto out_unlock; @@ -4995,24 +4987,13 @@ static struct extent_io_ops btrfs_extent_io_ops = { .clear_bit_hook = btrfs_clear_bit_hook, }; -/* - * btrfs doesn't support the bmap operation because swapfiles - * use bmap to make a mapping of extents in the file. They assume - * these extents won't change over the life of the file and they - * use the bmap result to do IO directly to the drive. - * - * the btrfs bmap call would return logical addresses that aren't - * suitable for IO and they also will change frequently as COW - * operations happen. So, swapfile + btrfs == corruption. - * - * For now we're avoiding this by dropping bmap. - */ static struct address_space_operations btrfs_aops = { .readpage = btrfs_readpage, .writepage = btrfs_writepage, .writepages = btrfs_writepages, .readpages = btrfs_readpages, .sync_page = block_sync_page, + .bmap = btrfs_bmap, .direct_IO = btrfs_direct_IO, .invalidatepage = btrfs_invalidatepage, .releasepage = btrfs_releasepage, @@ -5036,7 +5017,6 @@ static struct inode_operations btrfs_file_inode_operations = { .removexattr = btrfs_removexattr, .permission = btrfs_permission, .fallocate = btrfs_fallocate, - .fiemap = btrfs_fiemap, }; static struct inode_operations btrfs_special_inode_operations = { .getattr = btrfs_getattr, @@ -5052,8 +5032,4 @@ static struct inode_operations btrfs_symlink_inode_operations = { .follow_link = page_follow_link_light, .put_link = page_put_link, .permission = btrfs_permission, - .setxattr = btrfs_setxattr, - .getxattr = btrfs_getxattr, - .listxattr = btrfs_listxattr, - .removexattr = btrfs_removexattr, }; diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index bca729fc80c8..c2aa33e3feb5 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include "compat.h" @@ -70,7 +71,7 @@ static noinline int create_subvol(struct btrfs_root *root, u64 index = 0; unsigned long nr = 1; - ret = btrfs_check_metadata_free_space(root); + ret = btrfs_check_free_space(root, 1, 0); if (ret) goto fail_commit; @@ -203,7 +204,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, if (!root->ref_cows) return -EINVAL; - ret = btrfs_check_metadata_free_space(root); + ret = btrfs_check_free_space(root, 1, 0); if (ret) goto fail_unlock; @@ -374,7 +375,7 @@ static int btrfs_defrag_file(struct file *file) unsigned long i; int ret; - ret = btrfs_check_data_free_space(root, inode, inode->i_size); + ret = btrfs_check_free_space(root, inode->i_size, 0); if (ret) return -ENOSPC; diff --git a/trunk/fs/btrfs/locking.c b/trunk/fs/btrfs/locking.c index 85506c4a3af7..39bae7761db6 100644 --- a/trunk/fs/btrfs/locking.c +++ b/trunk/fs/btrfs/locking.c @@ -25,203 +25,64 @@ #include "extent_io.h" #include "locking.h" -static inline void spin_nested(struct extent_buffer *eb) -{ - spin_lock(&eb->lock); -} - -/* - * Setting a lock to blocking will drop the spinlock and set the - * flag that forces other procs who want the lock to wait. After - * this you can safely schedule with the lock held. - */ -void btrfs_set_lock_blocking(struct extent_buffer *eb) -{ - if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) { - set_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags); - spin_unlock(&eb->lock); - } - /* exit with the spin lock released and the bit set */ -} - /* - * clearing the blocking flag will take the spinlock again. - * After this you can't safely schedule - */ -void btrfs_clear_lock_blocking(struct extent_buffer *eb) -{ - if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) { - spin_nested(eb); - clear_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags); - smp_mb__after_clear_bit(); - } - /* exit with the spin lock held */ -} - -/* - * unfortunately, many of the places that currently set a lock to blocking - * don't end up blocking for every long, and often they don't block - * at all. For a dbench 50 run, if we don't spin one the blocking bit - * at all, the context switch rate can jump up to 400,000/sec or more. + * locks the per buffer mutex in an extent buffer. This uses adaptive locks + * and the spin is not tuned very extensively. The spinning does make a big + * difference in almost every workload, but spinning for the right amount of + * time needs some help. * - * So, we're still stuck with this crummy spin on the blocking bit, - * at least until the most common causes of the short blocks - * can be dealt with. + * In general, we want to spin as long as the lock holder is doing btree + * searches, and we should give up if they are in more expensive code. */ -static int btrfs_spin_on_block(struct extent_buffer *eb) + +int btrfs_tree_lock(struct extent_buffer *eb) { int i; + + if (mutex_trylock(&eb->mutex)) + return 0; for (i = 0; i < 512; i++) { cpu_relax(); - if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) - return 1; - if (need_resched()) - break; + if (mutex_trylock(&eb->mutex)) + return 0; } + cpu_relax(); + mutex_lock_nested(&eb->mutex, BTRFS_MAX_LEVEL - btrfs_header_level(eb)); return 0; } -/* - * This is somewhat different from trylock. It will take the - * spinlock but if it finds the lock is set to blocking, it will - * return without the lock held. - * - * returns 1 if it was able to take the lock and zero otherwise - * - * After this call, scheduling is not safe without first calling - * btrfs_set_lock_blocking() - */ -int btrfs_try_spin_lock(struct extent_buffer *eb) +int btrfs_try_tree_lock(struct extent_buffer *eb) { - int i; - - spin_nested(eb); - if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) - return 1; - spin_unlock(&eb->lock); - - /* spin for a bit on the BLOCKING flag */ - for (i = 0; i < 2; i++) { - if (!btrfs_spin_on_block(eb)) - break; - - spin_nested(eb); - if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) - return 1; - spin_unlock(&eb->lock); - } - return 0; + return mutex_trylock(&eb->mutex); } -/* - * the autoremove wake function will return 0 if it tried to wake up - * a process that was already awake, which means that process won't - * count as an exclusive wakeup. The waitq code will continue waking - * procs until it finds one that was actually sleeping. - * - * For btrfs, this isn't quite what we want. We want a single proc - * to be notified that the lock is ready for taking. If that proc - * already happen to be awake, great, it will loop around and try for - * the lock. - * - * So, btrfs_wake_function always returns 1, even when the proc that we - * tried to wake up was already awake. - */ -static int btrfs_wake_function(wait_queue_t *wait, unsigned mode, - int sync, void *key) +int btrfs_tree_unlock(struct extent_buffer *eb) { - autoremove_wake_function(wait, mode, sync, key); - return 1; + mutex_unlock(&eb->mutex); + return 0; } -/* - * returns with the extent buffer spinlocked. - * - * This will spin and/or wait as required to take the lock, and then - * return with the spinlock held. - * - * After this call, scheduling is not safe without first calling - * btrfs_set_lock_blocking() - */ -int btrfs_tree_lock(struct extent_buffer *eb) +int btrfs_tree_locked(struct extent_buffer *eb) { - DEFINE_WAIT(wait); - wait.func = btrfs_wake_function; - - while(1) { - spin_nested(eb); - - /* nobody is blocking, exit with the spinlock held */ - if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) - return 0; - - /* - * we have the spinlock, but the real owner is blocking. - * wait for them - */ - spin_unlock(&eb->lock); - - /* - * spin for a bit, and if the blocking flag goes away, - * loop around - */ - if (btrfs_spin_on_block(eb)) - continue; - - prepare_to_wait_exclusive(&eb->lock_wq, &wait, - TASK_UNINTERRUPTIBLE); - - if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) - schedule(); - - finish_wait(&eb->lock_wq, &wait); - } - return 0; + return mutex_is_locked(&eb->mutex); } /* - * Very quick trylock, this does not spin or schedule. It returns - * 1 with the spinlock held if it was able to take the lock, or it - * returns zero if it was unable to take the lock. - * - * After this call, scheduling is not safe without first calling - * btrfs_set_lock_blocking() + * btrfs_search_slot uses this to decide if it should drop its locks + * before doing something expensive like allocating free blocks for cow. */ -int btrfs_try_tree_lock(struct extent_buffer *eb) +int btrfs_path_lock_waiting(struct btrfs_path *path, int level) { - if (spin_trylock(&eb->lock)) { - if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) { - /* - * we've got the spinlock, but the real owner is - * blocking. Drop the spinlock and return failure - */ - spin_unlock(&eb->lock); - return 0; - } - return 1; + int i; + struct extent_buffer *eb; + for (i = level; i <= level + 1 && i < BTRFS_MAX_LEVEL; i++) { + eb = path->nodes[i]; + if (!eb) + break; + smp_mb(); + if (!list_empty(&eb->mutex.wait_list)) + return 1; } - /* someone else has the spinlock giveup */ return 0; } -int btrfs_tree_unlock(struct extent_buffer *eb) -{ - /* - * if we were a blocking owner, we don't have the spinlock held - * just clear the bit and look for waiters - */ - if (test_and_clear_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) - smp_mb__after_clear_bit(); - else - spin_unlock(&eb->lock); - - if (waitqueue_active(&eb->lock_wq)) - wake_up(&eb->lock_wq); - return 0; -} - -int btrfs_tree_locked(struct extent_buffer *eb) -{ - return test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags) || - spin_is_locked(&eb->lock); -} diff --git a/trunk/fs/btrfs/locking.h b/trunk/fs/btrfs/locking.h index 6bb0afbff928..bc1faef12519 100644 --- a/trunk/fs/btrfs/locking.h +++ b/trunk/fs/btrfs/locking.h @@ -22,10 +22,6 @@ int btrfs_tree_lock(struct extent_buffer *eb); int btrfs_tree_unlock(struct extent_buffer *eb); int btrfs_tree_locked(struct extent_buffer *eb); - int btrfs_try_tree_lock(struct extent_buffer *eb); -int btrfs_try_spin_lock(struct extent_buffer *eb); - -void btrfs_set_lock_blocking(struct extent_buffer *eb); -void btrfs_clear_lock_blocking(struct extent_buffer *eb); +int btrfs_path_lock_waiting(struct btrfs_path *path, int level); #endif diff --git a/trunk/fs/btrfs/ordered-data.c b/trunk/fs/btrfs/ordered-data.c index 77c2411a5f0f..a20940170274 100644 --- a/trunk/fs/btrfs/ordered-data.c +++ b/trunk/fs/btrfs/ordered-data.c @@ -613,6 +613,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, struct btrfs_sector_sum *sector_sums; struct btrfs_ordered_extent *ordered; struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree; + struct list_head *cur; unsigned long num_sectors; unsigned long i; u32 sectorsize = BTRFS_I(inode)->root->sectorsize; @@ -623,7 +624,8 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, return 1; mutex_lock(&tree->mutex); - list_for_each_entry_reverse(ordered_sum, &ordered->list, list) { + list_for_each_prev(cur, &ordered->list) { + ordered_sum = list_entry(cur, struct btrfs_ordered_sum, list); if (disk_bytenr >= ordered_sum->bytenr) { num_sectors = ordered_sum->len / sectorsize; sector_sums = ordered_sum->sums; diff --git a/trunk/fs/btrfs/ref-cache.c b/trunk/fs/btrfs/ref-cache.c index d0cc62bccb94..6f0acc4c9eab 100644 --- a/trunk/fs/btrfs/ref-cache.c +++ b/trunk/fs/btrfs/ref-cache.c @@ -17,7 +17,6 @@ */ #include -#include #include "ctree.h" #include "ref-cache.h" #include "transaction.h" diff --git a/trunk/fs/btrfs/ref-cache.h b/trunk/fs/btrfs/ref-cache.h index bc283ad2db73..16f3183d7c59 100644 --- a/trunk/fs/btrfs/ref-cache.h +++ b/trunk/fs/btrfs/ref-cache.h @@ -73,4 +73,5 @@ int btrfs_add_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref, int btrfs_remove_leaf_refs(struct btrfs_root *root, u64 max_root_gen, int shared); int btrfs_remove_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref); + #endif diff --git a/trunk/fs/btrfs/super.c b/trunk/fs/btrfs/super.c index 19a4daf03ccb..db9fb3bc1e33 100644 --- a/trunk/fs/btrfs/super.c +++ b/trunk/fs/btrfs/super.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "compat.h" #include "ctree.h" @@ -379,6 +380,7 @@ int btrfs_sync_fs(struct super_block *sb, int wait) btrfs_start_delalloc_inodes(root); btrfs_wait_ordered_extents(root, 0); + btrfs_clean_old_snapshots(root); trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); sb->s_dirt = 0; @@ -510,10 +512,6 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) struct btrfs_root *root = btrfs_sb(sb); int ret; - ret = btrfs_parse_options(root, data); - if (ret) - return -EINVAL; - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; @@ -585,18 +583,17 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, struct btrfs_ioctl_vol_args *vol; struct btrfs_fs_devices *fs_devices; int ret = -ENOTTY; + int len; if (!capable(CAP_SYS_ADMIN)) return -EPERM; vol = kmalloc(sizeof(*vol), GFP_KERNEL); - if (!vol) - return -ENOMEM; - if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) { ret = -EFAULT; goto out; } + len = strnlen(vol->name, BTRFS_PATH_NAME_MAX); switch (cmd) { case BTRFS_IOC_SCAN_DEV: diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index 4112d53d4f4d..8a08f9443340 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/fs/btrfs/transaction.c @@ -688,9 +688,7 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root, num_bytes -= btrfs_root_used(&dirty->root->root_item); bytes_used = btrfs_root_used(&root->root_item); if (num_bytes) { - mutex_lock(&root->fs_info->trans_mutex); btrfs_record_root_in_trans(root); - mutex_unlock(&root->fs_info->trans_mutex); btrfs_set_root_used(&root->root_item, bytes_used - num_bytes); } @@ -854,9 +852,11 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, { struct btrfs_pending_snapshot *pending; struct list_head *head = &trans->transaction->pending_snapshots; + struct list_head *cur; int ret; - list_for_each_entry(pending, head, list) { + list_for_each(cur, head) { + pending = list_entry(cur, struct btrfs_pending_snapshot, list); ret = create_pending_snapshot(trans, fs_info, pending); BUG_ON(ret); } diff --git a/trunk/fs/btrfs/tree-defrag.c b/trunk/fs/btrfs/tree-defrag.c index 98d25fa4570e..3e8358c36165 100644 --- a/trunk/fs/btrfs/tree-defrag.c +++ b/trunk/fs/btrfs/tree-defrag.c @@ -74,7 +74,6 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, u32 nritems; root_node = btrfs_lock_root_node(root); - btrfs_set_lock_blocking(root_node); nritems = btrfs_header_nritems(root_node); root->defrag_max.objectid = 0; /* from above we know this is not a leaf */ diff --git a/trunk/fs/btrfs/tree-log.c b/trunk/fs/btrfs/tree-log.c index 9c462fbd60fa..d81cda2e077c 100644 --- a/trunk/fs/btrfs/tree-log.c +++ b/trunk/fs/btrfs/tree-log.c @@ -77,6 +77,104 @@ static int link_to_fixup_dir(struct btrfs_trans_handle *trans, * and once to do all the other items. */ +/* + * btrfs_add_log_tree adds a new per-subvolume log tree into the + * tree of log tree roots. This must be called with a tree log transaction + * running (see start_log_trans). + */ +static int btrfs_add_log_tree(struct btrfs_trans_handle *trans, + struct btrfs_root *root) +{ + struct btrfs_key key; + struct btrfs_root_item root_item; + struct btrfs_inode_item *inode_item; + struct extent_buffer *leaf; + struct btrfs_root *new_root = root; + int ret; + u64 objectid = root->root_key.objectid; + + leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, + BTRFS_TREE_LOG_OBJECTID, + trans->transid, 0, 0, 0); + if (IS_ERR(leaf)) { + ret = PTR_ERR(leaf); + return ret; + } + + btrfs_set_header_nritems(leaf, 0); + btrfs_set_header_level(leaf, 0); + btrfs_set_header_bytenr(leaf, leaf->start); + btrfs_set_header_generation(leaf, trans->transid); + btrfs_set_header_owner(leaf, BTRFS_TREE_LOG_OBJECTID); + + write_extent_buffer(leaf, root->fs_info->fsid, + (unsigned long)btrfs_header_fsid(leaf), + BTRFS_FSID_SIZE); + btrfs_mark_buffer_dirty(leaf); + + inode_item = &root_item.inode; + memset(inode_item, 0, sizeof(*inode_item)); + inode_item->generation = cpu_to_le64(1); + inode_item->size = cpu_to_le64(3); + inode_item->nlink = cpu_to_le32(1); + inode_item->nbytes = cpu_to_le64(root->leafsize); + inode_item->mode = cpu_to_le32(S_IFDIR | 0755); + + btrfs_set_root_bytenr(&root_item, leaf->start); + btrfs_set_root_generation(&root_item, trans->transid); + btrfs_set_root_level(&root_item, 0); + btrfs_set_root_refs(&root_item, 0); + btrfs_set_root_used(&root_item, 0); + + memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress)); + root_item.drop_level = 0; + + btrfs_tree_unlock(leaf); + free_extent_buffer(leaf); + leaf = NULL; + + btrfs_set_root_dirid(&root_item, 0); + + key.objectid = BTRFS_TREE_LOG_OBJECTID; + key.offset = objectid; + btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); + ret = btrfs_insert_root(trans, root->fs_info->log_root_tree, &key, + &root_item); + if (ret) + goto fail; + + new_root = btrfs_read_fs_root_no_radix(root->fs_info->log_root_tree, + &key); + BUG_ON(!new_root); + + WARN_ON(root->log_root); + root->log_root = new_root; + + /* + * log trees do not get reference counted because they go away + * before a real commit is actually done. They do store pointers + * to file data extents, and those reference counts still get + * updated (along with back refs to the log tree). + */ + new_root->ref_cows = 0; + new_root->last_trans = trans->transid; + + /* + * we need to make sure the root block for this new tree + * is marked as dirty in the dirty_log_pages tree. This + * is how it gets flushed down to disk at tree log commit time. + * + * the tree logging mutex keeps others from coming in and changing + * the new_root->node, so we can safely access it here + */ + set_extent_dirty(&new_root->dirty_log_pages, new_root->node->start, + new_root->node->start + new_root->node->len - 1, + GFP_NOFS); + +fail: + return ret; +} + /* * start a sub transaction and setup the log tree * this increments the log tree writer count to make the people @@ -86,14 +184,6 @@ static int start_log_trans(struct btrfs_trans_handle *trans, struct btrfs_root *root) { int ret; - - mutex_lock(&root->log_mutex); - if (root->log_root) { - root->log_batch++; - atomic_inc(&root->log_writers); - mutex_unlock(&root->log_mutex); - return 0; - } mutex_lock(&root->fs_info->tree_log_mutex); if (!root->fs_info->log_root_tree) { ret = btrfs_init_log_root_tree(trans, root->fs_info); @@ -103,10 +193,9 @@ static int start_log_trans(struct btrfs_trans_handle *trans, ret = btrfs_add_log_tree(trans, root); BUG_ON(ret); } + atomic_inc(&root->fs_info->tree_log_writers); + root->fs_info->tree_log_batch++; mutex_unlock(&root->fs_info->tree_log_mutex); - root->log_batch++; - atomic_inc(&root->log_writers); - mutex_unlock(&root->log_mutex); return 0; } @@ -123,12 +212,13 @@ static int join_running_log_trans(struct btrfs_root *root) if (!root->log_root) return -ENOENT; - mutex_lock(&root->log_mutex); + mutex_lock(&root->fs_info->tree_log_mutex); if (root->log_root) { ret = 0; - atomic_inc(&root->log_writers); + atomic_inc(&root->fs_info->tree_log_writers); + root->fs_info->tree_log_batch++; } - mutex_unlock(&root->log_mutex); + mutex_unlock(&root->fs_info->tree_log_mutex); return ret; } @@ -138,11 +228,10 @@ static int join_running_log_trans(struct btrfs_root *root) */ static int end_log_trans(struct btrfs_root *root) { - if (atomic_dec_and_test(&root->log_writers)) { - smp_mb(); - if (waitqueue_active(&root->log_writer_wait)) - wake_up(&root->log_writer_wait); - } + atomic_dec(&root->fs_info->tree_log_writers); + smp_mb(); + if (waitqueue_active(&root->fs_info->tree_log_wait)) + wake_up(&root->fs_info->tree_log_wait); return 0; } @@ -1615,7 +1704,6 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, btrfs_tree_lock(next); clean_tree_block(trans, root, next); - btrfs_set_lock_blocking(next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); @@ -1662,7 +1750,6 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, next = path->nodes[*level]; btrfs_tree_lock(next); clean_tree_block(trans, root, next); - btrfs_set_lock_blocking(next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); @@ -1720,7 +1807,6 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans, btrfs_tree_lock(next); clean_tree_block(trans, root, next); - btrfs_set_lock_blocking(next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); @@ -1793,7 +1879,6 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, btrfs_tree_lock(next); clean_tree_block(trans, log, next); - btrfs_set_lock_blocking(next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); @@ -1817,65 +1902,26 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, } } btrfs_free_path(path); + if (wc->free) + free_extent_buffer(log->node); return ret; } -/* - * helper function to update the item for a given subvolumes log root - * in the tree of log roots - */ -static int update_log_root(struct btrfs_trans_handle *trans, - struct btrfs_root *log) -{ - int ret; - - if (log->log_transid == 1) { - /* insert root item on the first sync */ - ret = btrfs_insert_root(trans, log->fs_info->log_root_tree, - &log->root_key, &log->root_item); - } else { - ret = btrfs_update_root(trans, log->fs_info->log_root_tree, - &log->root_key, &log->root_item); - } - return ret; -} - -static int wait_log_commit(struct btrfs_root *root, unsigned long transid) +static int wait_log_commit(struct btrfs_root *log) { DEFINE_WAIT(wait); - int index = transid % 2; + u64 transid = log->fs_info->tree_log_transid; - /* - * we only allow two pending log transactions at a time, - * so we know that if ours is more than 2 older than the - * current transaction, we're done - */ do { - prepare_to_wait(&root->log_commit_wait[index], - &wait, TASK_UNINTERRUPTIBLE); - mutex_unlock(&root->log_mutex); - if (root->log_transid < transid + 2 && - atomic_read(&root->log_commit[index])) + prepare_to_wait(&log->fs_info->tree_log_wait, &wait, + TASK_UNINTERRUPTIBLE); + mutex_unlock(&log->fs_info->tree_log_mutex); + if (atomic_read(&log->fs_info->tree_log_commit)) schedule(); - finish_wait(&root->log_commit_wait[index], &wait); - mutex_lock(&root->log_mutex); - } while (root->log_transid < transid + 2 && - atomic_read(&root->log_commit[index])); - return 0; -} - -static int wait_for_writer(struct btrfs_root *root) -{ - DEFINE_WAIT(wait); - while (atomic_read(&root->log_writers)) { - prepare_to_wait(&root->log_writer_wait, - &wait, TASK_UNINTERRUPTIBLE); - mutex_unlock(&root->log_mutex); - if (atomic_read(&root->log_writers)) - schedule(); - mutex_lock(&root->log_mutex); - finish_wait(&root->log_writer_wait, &wait); - } + finish_wait(&log->fs_info->tree_log_wait, &wait); + mutex_lock(&log->fs_info->tree_log_mutex); + } while (transid == log->fs_info->tree_log_transid && + atomic_read(&log->fs_info->tree_log_commit)); return 0; } @@ -1887,114 +1933,57 @@ static int wait_for_writer(struct btrfs_root *root) int btrfs_sync_log(struct btrfs_trans_handle *trans, struct btrfs_root *root) { - int index1; - int index2; int ret; + unsigned long batch; struct btrfs_root *log = root->log_root; - struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; - mutex_lock(&root->log_mutex); - index1 = root->log_transid % 2; - if (atomic_read(&root->log_commit[index1])) { - wait_log_commit(root, root->log_transid); - mutex_unlock(&root->log_mutex); - return 0; + mutex_lock(&log->fs_info->tree_log_mutex); + if (atomic_read(&log->fs_info->tree_log_commit)) { + wait_log_commit(log); + goto out; } - atomic_set(&root->log_commit[index1], 1); - - /* wait for previous tree log sync to complete */ - if (atomic_read(&root->log_commit[(index1 + 1) % 2])) - wait_log_commit(root, root->log_transid - 1); + atomic_set(&log->fs_info->tree_log_commit, 1); while (1) { - unsigned long batch = root->log_batch; - mutex_unlock(&root->log_mutex); + batch = log->fs_info->tree_log_batch; + mutex_unlock(&log->fs_info->tree_log_mutex); schedule_timeout_uninterruptible(1); - mutex_lock(&root->log_mutex); - wait_for_writer(root); - if (batch == root->log_batch) + mutex_lock(&log->fs_info->tree_log_mutex); + + while (atomic_read(&log->fs_info->tree_log_writers)) { + DEFINE_WAIT(wait); + prepare_to_wait(&log->fs_info->tree_log_wait, &wait, + TASK_UNINTERRUPTIBLE); + mutex_unlock(&log->fs_info->tree_log_mutex); + if (atomic_read(&log->fs_info->tree_log_writers)) + schedule(); + mutex_lock(&log->fs_info->tree_log_mutex); + finish_wait(&log->fs_info->tree_log_wait, &wait); + } + if (batch == log->fs_info->tree_log_batch) break; } ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages); BUG_ON(ret); - - btrfs_set_root_bytenr(&log->root_item, log->node->start); - btrfs_set_root_generation(&log->root_item, trans->transid); - btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node)); - - root->log_batch = 0; - root->log_transid++; - log->log_transid = root->log_transid; - smp_mb(); - /* - * log tree has been flushed to disk, new modifications of - * the log will be written to new positions. so it's safe to - * allow log writers to go in. - */ - mutex_unlock(&root->log_mutex); - - mutex_lock(&log_root_tree->log_mutex); - log_root_tree->log_batch++; - atomic_inc(&log_root_tree->log_writers); - mutex_unlock(&log_root_tree->log_mutex); - - ret = update_log_root(trans, log); - BUG_ON(ret); - - mutex_lock(&log_root_tree->log_mutex); - if (atomic_dec_and_test(&log_root_tree->log_writers)) { - smp_mb(); - if (waitqueue_active(&log_root_tree->log_writer_wait)) - wake_up(&log_root_tree->log_writer_wait); - } - - index2 = log_root_tree->log_transid % 2; - if (atomic_read(&log_root_tree->log_commit[index2])) { - wait_log_commit(log_root_tree, log_root_tree->log_transid); - mutex_unlock(&log_root_tree->log_mutex); - goto out; - } - atomic_set(&log_root_tree->log_commit[index2], 1); - - if (atomic_read(&log_root_tree->log_commit[(index2 + 1) % 2])) - wait_log_commit(log_root_tree, log_root_tree->log_transid - 1); - - wait_for_writer(log_root_tree); - - ret = btrfs_write_and_wait_marked_extents(log_root_tree, - &log_root_tree->dirty_log_pages); + ret = btrfs_write_and_wait_marked_extents(root->fs_info->log_root_tree, + &root->fs_info->log_root_tree->dirty_log_pages); BUG_ON(ret); btrfs_set_super_log_root(&root->fs_info->super_for_commit, - log_root_tree->node->start); + log->fs_info->log_root_tree->node->start); btrfs_set_super_log_root_level(&root->fs_info->super_for_commit, - btrfs_header_level(log_root_tree->node)); - - log_root_tree->log_batch = 0; - log_root_tree->log_transid++; - smp_mb(); - - mutex_unlock(&log_root_tree->log_mutex); - - /* - * nobody else is going to jump in and write the the ctree - * super here because the log_commit atomic below is protecting - * us. We must be called with a transaction handle pinning - * the running transaction open, so a full commit can't hop - * in and cause problems either. - */ - write_ctree_super(trans, root->fs_info->tree_root, 2); + btrfs_header_level(log->fs_info->log_root_tree->node)); - atomic_set(&log_root_tree->log_commit[index2], 0); + write_ctree_super(trans, log->fs_info->tree_root, 2); + log->fs_info->tree_log_transid++; + log->fs_info->tree_log_batch = 0; + atomic_set(&log->fs_info->tree_log_commit, 0); smp_mb(); - if (waitqueue_active(&log_root_tree->log_commit_wait[index2])) - wake_up(&log_root_tree->log_commit_wait[index2]); + if (waitqueue_active(&log->fs_info->tree_log_wait)) + wake_up(&log->fs_info->tree_log_wait); out: - atomic_set(&root->log_commit[index1], 0); - smp_mb(); - if (waitqueue_active(&root->log_commit_wait[index1])) - wake_up(&root->log_commit_wait[index1]); + mutex_unlock(&log->fs_info->tree_log_mutex); return 0; } @@ -2030,17 +2019,37 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root) start, end, GFP_NOFS); } - if (log->log_transid > 0) { - ret = btrfs_del_root(trans, root->fs_info->log_root_tree, - &log->root_key); - BUG_ON(ret); - } + log = root->log_root; + ret = btrfs_del_root(trans, root->fs_info->log_root_tree, + &log->root_key); + BUG_ON(ret); root->log_root = NULL; - free_extent_buffer(log->node); - kfree(log); + kfree(root->log_root); return 0; } +/* + * helper function to update the item for a given subvolumes log root + * in the tree of log roots + */ +static int update_log_root(struct btrfs_trans_handle *trans, + struct btrfs_root *log) +{ + u64 bytenr = btrfs_root_bytenr(&log->root_item); + int ret; + + if (log->node->start == bytenr) + return 0; + + btrfs_set_root_bytenr(&log->root_item, log->node->start); + btrfs_set_root_generation(&log->root_item, trans->transid); + btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node)); + ret = btrfs_update_root(trans, log->fs_info->log_root_tree, + &log->root_key, &log->root_item); + BUG_ON(ret); + return ret; +} + /* * If both a file and directory are logged, and unlinks or renames are * mixed in, we have a few interesting corners: @@ -2702,6 +2711,11 @@ static int __btrfs_log_inode(struct btrfs_trans_handle *trans, btrfs_free_path(path); btrfs_free_path(dst_path); + + mutex_lock(&root->fs_info->tree_log_mutex); + ret = update_log_root(trans, log); + BUG_ON(ret); + mutex_unlock(&root->fs_info->tree_log_mutex); out: return 0; } @@ -2832,9 +2846,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) BUG_ON(!wc.replay_dest); wc.replay_dest->log_root = log; - mutex_lock(&fs_info->trans_mutex); btrfs_record_root_in_trans(wc.replay_dest); - mutex_unlock(&fs_info->trans_mutex); ret = walk_log_tree(trans, log, &wc); BUG_ON(ret); diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 1316139bf9e8..3451e1cca2b5 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "compat.h" #include "ctree.h" @@ -103,8 +104,10 @@ static noinline struct btrfs_device *__find_device(struct list_head *head, u64 devid, u8 *uuid) { struct btrfs_device *dev; + struct list_head *cur; - list_for_each_entry(dev, head, dev_list) { + list_for_each(cur, head) { + dev = list_entry(cur, struct btrfs_device, dev_list); if (dev->devid == devid && (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) { return dev; @@ -115,9 +118,11 @@ static noinline struct btrfs_device *__find_device(struct list_head *head, static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid) { + struct list_head *cur; struct btrfs_fs_devices *fs_devices; - list_for_each_entry(fs_devices, &fs_uuids, list) { + list_for_each(cur, &fs_uuids) { + fs_devices = list_entry(cur, struct btrfs_fs_devices, list); if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0) return fs_devices; } @@ -154,7 +159,6 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) loop: spin_lock(&device->io_lock); -loop_lock: /* take all the bios off the list at once and process them * later on (without the lock held). But, remember the * tail and other pointers so the bios can be properly reinserted @@ -204,7 +208,7 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) * is now congested. Back off and let other work structs * run instead */ - if (pending && bdi_write_congested(bdi) && num_run > 16 && + if (pending && bdi_write_congested(bdi) && fs_info->fs_devices->open_devices > 1) { struct bio *old_head; @@ -216,8 +220,7 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) tail->bi_next = old_head; else device->pending_bio_tail = tail; - - device->running_pending = 1; + device->running_pending = 0; spin_unlock(&device->io_lock); btrfs_requeue_work(&device->work); @@ -226,11 +229,6 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) } if (again) goto loop; - - spin_lock(&device->io_lock); - if (device->pending_bios) - goto loop_lock; - spin_unlock(&device->io_lock); done: return 0; } @@ -347,11 +345,14 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig) int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) { - struct btrfs_device *device, *next; + struct list_head *tmp; + struct list_head *cur; + struct btrfs_device *device; mutex_lock(&uuid_mutex); again: - list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { + list_for_each_safe(cur, tmp, &fs_devices->devices) { + device = list_entry(cur, struct btrfs_device, dev_list); if (device->in_fs_metadata) continue; @@ -382,12 +383,14 @@ int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) { + struct list_head *cur; struct btrfs_device *device; if (--fs_devices->opened > 0) return 0; - list_for_each_entry(device, &fs_devices->devices, dev_list) { + list_for_each(cur, &fs_devices->devices) { + device = list_entry(cur, struct btrfs_device, dev_list); if (device->bdev) { close_bdev_exclusive(device->bdev, device->mode); fs_devices->open_devices--; @@ -436,6 +439,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, { struct block_device *bdev; struct list_head *head = &fs_devices->devices; + struct list_head *cur; struct btrfs_device *device; struct block_device *latest_bdev = NULL; struct buffer_head *bh; @@ -446,7 +450,8 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, int seeding = 1; int ret = 0; - list_for_each_entry(device, head, dev_list) { + list_for_each(cur, head) { + device = list_entry(cur, struct btrfs_device, dev_list); if (device->bdev) continue; if (!device->name) @@ -573,7 +578,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, *(unsigned long long *)disk_super->fsid, *(unsigned long long *)(disk_super->fsid + 8)); } - printk(KERN_CONT "devid %llu transid %llu %s\n", + printk(KERN_INFO "devid %llu transid %llu %s\n", (unsigned long long)devid, (unsigned long long)transid, path); ret = device_list_add(path, disk_super, devid, fs_devices_ret); @@ -1012,12 +1017,14 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) } if (strcmp(device_path, "missing") == 0) { + struct list_head *cur; struct list_head *devices; struct btrfs_device *tmp; device = NULL; devices = &root->fs_info->fs_devices->devices; - list_for_each_entry(tmp, devices, dev_list) { + list_for_each(cur, devices) { + tmp = list_entry(cur, struct btrfs_device, dev_list); if (tmp->in_fs_metadata && !tmp->bdev) { device = tmp; break; @@ -1273,6 +1280,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) struct btrfs_trans_handle *trans; struct btrfs_device *device; struct block_device *bdev; + struct list_head *cur; struct list_head *devices; struct super_block *sb = root->fs_info->sb; u64 total_bytes; @@ -1296,7 +1304,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) mutex_lock(&root->fs_info->volume_mutex); devices = &root->fs_info->fs_devices->devices; - list_for_each_entry(device, devices, dev_list) { + list_for_each(cur, devices) { + device = list_entry(cur, struct btrfs_device, dev_list); if (device->bdev == bdev) { ret = -EEXIST; goto error; @@ -1695,6 +1704,7 @@ static u64 div_factor(u64 num, int factor) int btrfs_balance(struct btrfs_root *dev_root) { int ret; + struct list_head *cur; struct list_head *devices = &dev_root->fs_info->fs_devices->devices; struct btrfs_device *device; u64 old_size; @@ -1713,7 +1723,8 @@ int btrfs_balance(struct btrfs_root *dev_root) dev_root = dev_root->fs_info->dev_root; /* step one make some room on all the devices */ - list_for_each_entry(device, devices, dev_list) { + list_for_each(cur, devices) { + device = list_entry(cur, struct btrfs_device, dev_list); old_size = device->total_bytes; size_to_free = div_factor(old_size, 1); size_to_free = min(size_to_free, (u64)1 * 1024 * 1024); @@ -2894,6 +2905,10 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, free_extent_map(em); } + map = kzalloc(sizeof(*map), GFP_NOFS); + if (!map) + return -ENOMEM; + em = alloc_extent_map(GFP_NOFS); if (!em) return -ENOMEM; @@ -3102,8 +3117,6 @@ int btrfs_read_sys_array(struct btrfs_root *root) if (!sb) return -ENOMEM; btrfs_set_buffer_uptodate(sb); - btrfs_set_buffer_lockdep_class(sb, 0); - write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); array_size = btrfs_super_sys_array_size(super_copy); diff --git a/trunk/fs/btrfs/xattr.c b/trunk/fs/btrfs/xattr.c index a9d3bf4d2689..7f332e270894 100644 --- a/trunk/fs/btrfs/xattr.c +++ b/trunk/fs/btrfs/xattr.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "ctree.h" #include "btrfs_inode.h" #include "transaction.h" @@ -46,12 +45,9 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name, /* lookup the xattr by name */ di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name, strlen(name), 0); - if (!di) { + if (!di || IS_ERR(di)) { ret = -ENODATA; goto out; - } else if (IS_ERR(di)) { - ret = PTR_ERR(di); - goto out; } leaf = path->nodes[0]; @@ -66,14 +62,6 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name, ret = -ERANGE; goto out; } - - /* - * The way things are packed into the leaf is like this - * |struct btrfs_dir_item|name|data| - * where name is the xattr name, so security.foo, and data is the - * content of the xattr. data_ptr points to the location in memory - * where the data starts in the in memory leaf - */ data_ptr = (unsigned long)((char *)(di + 1) + btrfs_dir_name_len(leaf, di)); read_extent_buffer(leaf, buffer, data_ptr, @@ -98,7 +86,7 @@ int __btrfs_setxattr(struct inode *inode, const char *name, if (!path) return -ENOMEM; - trans = btrfs_join_transaction(root, 1); + trans = btrfs_start_transaction(root, 1); btrfs_set_trans_block_group(trans, inode); /* first lets see if we already have this xattr */ @@ -188,6 +176,7 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); if (ret < 0) goto err; + ret = 0; advance = 0; while (1) { leaf = path->nodes[0]; @@ -331,34 +320,3 @@ int btrfs_removexattr(struct dentry *dentry, const char *name) return -EOPNOTSUPP; return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); } - -int btrfs_xattr_security_init(struct inode *inode, struct inode *dir) -{ - int err; - size_t len; - void *value; - char *suffix; - char *name; - - err = security_inode_init_security(inode, dir, &suffix, &value, &len); - if (err) { - if (err == -EOPNOTSUPP) - return 0; - return err; - } - - name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1, - GFP_NOFS); - if (!name) { - err = -ENOMEM; - } else { - strcpy(name, XATTR_SECURITY_PREFIX); - strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); - err = __btrfs_setxattr(inode, name, value, len, 0); - kfree(name); - } - - kfree(suffix); - kfree(value); - return err; -} diff --git a/trunk/fs/btrfs/xattr.h b/trunk/fs/btrfs/xattr.h index c71e9c3cf3f7..5b1d08f8e68d 100644 --- a/trunk/fs/btrfs/xattr.h +++ b/trunk/fs/btrfs/xattr.h @@ -36,6 +36,4 @@ extern int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); extern int btrfs_removexattr(struct dentry *dentry, const char *name); -extern int btrfs_xattr_security_init(struct inode *inode, struct inode *dir); - #endif /* __XATTR__ */ diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 9f697419ed8e..b58208f1640a 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -777,7 +777,6 @@ static int __set_page_dirty(struct page *page, __inc_zone_page_state(page, NR_FILE_DIRTY); __inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); - task_dirty_inc(current); task_io_account_write(PAGE_CACHE_SIZE); } radix_tree_tag_set(&mapping->page_tree, @@ -2689,7 +2688,7 @@ int nobh_write_end(struct file *file, struct address_space *mapping, struct buffer_head *bh; BUG_ON(fsdata != NULL && page_has_buffers(page)); - if (unlikely(copied < len) && head) + if (unlikely(copied < len) && !page_has_buffers(page)) attach_nobh_buffers(page, head); if (page_has_buffers(page)) return generic_write_end(file, mapping, pos, len, @@ -3109,7 +3108,7 @@ int sync_dirty_buffer(struct buffer_head *bh) if (test_clear_buffer_dirty(bh)) { get_bh(bh); bh->b_end_io = end_buffer_write_sync; - ret = submit_bh(WRITE, bh); + ret = submit_bh(WRITE_SYNC, bh); wait_on_buffer(bh); if (buffer_eopnotsupp(bh)) { clear_buffer_eopnotsupp(bh); diff --git a/trunk/fs/cifs/CHANGES b/trunk/fs/cifs/CHANGES index 851388fafc73..73ac7ebd1dfc 100644 --- a/trunk/fs/cifs/CHANGES +++ b/trunk/fs/cifs/CHANGES @@ -1,13 +1,3 @@ -Version 1.57 ------------- -Improve support for multiple security contexts to the same server. We -used to use the same "vcnumber" for all connections which could cause -the server to treat subsequent connections, especially those that -are authenticated as guest, as reconnections, invalidating the earlier -user's smb session. This fix allows cifs to mount multiple times to the -same server with different userids without risking invalidating earlier -established security contexts. - Version 1.56 ------------ Add "forcemandatorylock" mount option to allow user to use mandatory @@ -17,10 +7,7 @@ specified and user does not have access to query information about the top of the share. Fix problem in 2.6.28 resolving DFS paths to Samba servers (worked to Windows). Fix rmdir so that pending search (readdir) requests do not get invalid results which include the now -removed directory. Fix oops in cifs_dfs_ref.c when prefixpath is not reachable -when using DFS. Add better file create support to servers which support -the CIFS POSIX protocol extensions (this adds support for new flags -on create, and improves semantics for write of locked ranges). +removed directory. Version 1.55 ------------ diff --git a/trunk/fs/cifs/cifsfs.h b/trunk/fs/cifs/cifsfs.h index 2b1d28a9ee28..7ac481841f87 100644 --- a/trunk/fs/cifs/cifsfs.h +++ b/trunk/fs/cifs/cifsfs.h @@ -100,5 +100,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* EXPERIMENTAL */ -#define CIFS_VERSION "1.57" +#define CIFS_VERSION "1.56" #endif /* _CIFSFS_H */ diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index e004f6db5fc8..94c1ca0ec953 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -164,12 +164,9 @@ struct TCP_Server_Info { /* multiplexed reads or writes */ unsigned int maxBuf; /* maxBuf specifies the maximum */ /* message size the server can send or receive for non-raw SMBs */ - unsigned int max_rw; /* maxRw specifies the maximum */ + unsigned int maxRw; /* maxRw specifies the maximum */ /* message size the server can send or receive for */ /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ - unsigned int max_vcs; /* maximum number of smb sessions, at least - those that can be specified uniquely with - vcnumbers */ char sessid[4]; /* unique token id for this session */ /* (returned on Negotiate */ int capabilities; /* allow selective disabling of caps by smb sess */ @@ -213,7 +210,6 @@ struct cifsSesInfo { unsigned overrideSecFlg; /* if non-zero override global sec flags */ __u16 ipc_tid; /* special tid for connection to IPC share */ __u16 flags; - __u16 vcnum; char *serverOS; /* name of operating system underlying server */ char *serverNOS; /* name of network operating system of server */ char *serverDomain; /* security realm of server */ diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index 083dfc57c7a3..382ba6298809 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -42,7 +42,6 @@ extern void _FreeXid(unsigned int); #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid())); #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));} extern char *build_path_from_dentry(struct dentry *); -extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); /* extern void renew_parental_timestamps(struct dentry *direntry);*/ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, @@ -92,9 +91,6 @@ extern u64 cifs_UnixTimeToNT(struct timespec); extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); -extern void posix_fill_in_inode(struct inode *tmp_inode, - FILE_UNIX_BASIC_INFO *pData, int isNewInode); -extern struct inode *cifs_new_inode(struct super_block *sb, __u64 *inum); extern int cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, FILE_ALL_INFO *pfile_info, diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index 939e2f76b959..552642a507c4 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -528,15 +528,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) server->maxReq = le16_to_cpu(rsp->MaxMpxCount); server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); - server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs); GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey); /* even though we do not use raw we might as well set this accurately, in case we ever find a need for it */ if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { - server->max_rw = 0xFF00; + server->maxRw = 0xFF00; server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; } else { - server->max_rw = 0;/* do not need to use raw anyway */ + server->maxRw = 0;/* we do not need to use raw anyway */ server->capabilities = CAP_MPX_MODE; } tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone); @@ -639,7 +638,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) /* probably no need to store and check maxvcs */ server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); - server->max_rw = le32_to_cpu(pSMBr->MaxRawSize); + server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); cFYI(DBG2, ("Max buf = %d", ses->server->maxBuf)); GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); server->capabilities = le32_to_cpu(pSMBr->Capabilities); diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index da0f4ffa0613..2209be943051 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,6 @@ #include #include #include -#include #include "cifspdu.h" #include "cifsglob.h" #include "cifsproto.h" @@ -1379,8 +1379,8 @@ cifs_find_tcp_session(struct sockaddr_storage *addr) server->addr.sockAddr.sin_addr.s_addr)) continue; else if (addr->ss_family == AF_INET6 && - !ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr, - &addr6->sin6_addr)) + memcmp(&server->addr.sockAddr6.sin6_addr, + &addr6->sin6_addr, sizeof(addr6->sin6_addr))) continue; ++server->srv_count; @@ -2180,33 +2180,6 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, "mount option supported")); } -static int -is_path_accessible(int xid, struct cifsTconInfo *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path) -{ - int rc; - __u64 inode_num; - FILE_ALL_INFO *pfile_info; - - rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num, - cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - if (rc != -EOPNOTSUPP) - return rc; - - pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); - if (pfile_info == NULL) - return -ENOMEM; - - rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info, - 0 /* not legacy */, cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - kfree(pfile_info); - return rc; -} - int cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, char *mount_data, const char *devname) @@ -2217,7 +2190,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, struct cifsSesInfo *pSesInfo = NULL; struct cifsTconInfo *tcon = NULL; struct TCP_Server_Info *srvTcp = NULL; - char *full_path; xid = GetXid(); @@ -2454,23 +2426,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_sb->rsize = min(cifs_sb->rsize, (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); - if (!rc && cifs_sb->prepathlen) { - /* build_path_to_root works only when we have a valid tcon */ - full_path = cifs_build_path_to_root(cifs_sb); - if (full_path == NULL) { - rc = -ENOMEM; - goto mount_fail_check; - } - rc = is_path_accessible(xid, tcon, cifs_sb, full_path); - if (rc) { - cERROR(1, ("Path %s in not accessible: %d", - full_path, rc)); - kfree(full_path); - goto mount_fail_check; - } - kfree(full_path); - } - /* volume_info->password is freed above when existing session found (in which case it is not needed anymore) but when new sesion is created the password ptr is put in the new session structure (in which case the diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index 89fb72832652..964aad03c5ad 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -3,7 +3,7 @@ * * vfs operations that deal with dentries * - * Copyright (C) International Business Machines Corp., 2002,2009 + * Copyright (C) International Business Machines Corp., 2002,2008 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -129,78 +129,6 @@ build_path_from_dentry(struct dentry *direntry) return full_path; } -static int cifs_posix_open(char *full_path, struct inode **pinode, - struct super_block *sb, int mode, int oflags, - int *poplock, __u16 *pnetfid, int xid) -{ - int rc; - __u32 oplock; - FILE_UNIX_BASIC_INFO *presp_data; - __u32 posix_flags = 0; - struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - - cFYI(1, ("posix open %s", full_path)); - - presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); - if (presp_data == NULL) - return -ENOMEM; - -/* So far cifs posix extensions can only map the following flags. - There are other valid fmode oflags such as FMODE_LSEEK, FMODE_PREAD, but - so far we do not seem to need them, and we can treat them as local only */ - if ((oflags & (FMODE_READ | FMODE_WRITE)) == - (FMODE_READ | FMODE_WRITE)) - posix_flags = SMB_O_RDWR; - else if (oflags & FMODE_READ) - posix_flags = SMB_O_RDONLY; - else if (oflags & FMODE_WRITE) - posix_flags = SMB_O_WRONLY; - if (oflags & O_CREAT) - posix_flags |= SMB_O_CREAT; - if (oflags & O_EXCL) - posix_flags |= SMB_O_EXCL; - if (oflags & O_TRUNC) - posix_flags |= SMB_O_TRUNC; - if (oflags & O_APPEND) - posix_flags |= SMB_O_APPEND; - if (oflags & O_SYNC) - posix_flags |= SMB_O_SYNC; - if (oflags & O_DIRECTORY) - posix_flags |= SMB_O_DIRECTORY; - if (oflags & O_NOFOLLOW) - posix_flags |= SMB_O_NOFOLLOW; - if (oflags & O_DIRECT) - posix_flags |= SMB_O_DIRECT; - - - rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, - pnetfid, presp_data, &oplock, full_path, - cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - if (rc) - goto posix_open_ret; - - if (presp_data->Type == cpu_to_le32(-1)) - goto posix_open_ret; /* open ok, caller does qpathinfo */ - - /* get new inode and set it up */ - if (!pinode) - goto posix_open_ret; /* caller does not need info */ - - *pinode = cifs_new_inode(sb, &presp_data->UniqueId); - - /* We do not need to close the file if new_inode fails since - the caller will retry qpathinfo as long as inode is null */ - if (*pinode == NULL) - goto posix_open_ret; - - posix_fill_in_inode(*pinode, presp_data, 1); - -posix_open_ret: - kfree(presp_data); - return rc; -} - static void setup_cifs_dentry(struct cifsTconInfo *tcon, struct dentry *direntry, struct inode *newinode) @@ -222,14 +150,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, int xid; int create_options = CREATE_NOT_DIR; int oplock = 0; - int oflags; - /* - * BB below access is probably too much for mknod to request - * but we have to do query and setpathinfo so requesting - * less could fail (unless we want to request getatr and setatr - * permissions (only). At least for POSIX we do not have to - * request so much. - */ + /* BB below access is too much for the mknod to request */ int desiredAccess = GENERIC_READ | GENERIC_WRITE; __u16 fileHandle; struct cifs_sb_info *cifs_sb; @@ -253,43 +174,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, } mode &= ~current->fs->umask; - if (oplockEnabled) - oplock = REQ_OPLOCK; - - if (nd && (nd->flags & LOOKUP_OPEN)) - oflags = nd->intent.open.flags; - else - oflags = FMODE_READ; - - if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && - (CIFS_UNIX_POSIX_PATH_OPS_CAP & - le64_to_cpu(tcon->fsUnixInfo.Capability))) { - rc = cifs_posix_open(full_path, &newinode, inode->i_sb, - mode, oflags, &oplock, &fileHandle, xid); - /* EIO could indicate that (posix open) operation is not - supported, despite what server claimed in capability - negotation. EREMOTE indicates DFS junction, which is not - handled in posix open */ - - if ((rc == 0) && (newinode == NULL)) - goto cifs_create_get_file_info; /* query inode info */ - else if (rc == 0) /* success, no need to query */ - goto cifs_create_set_dentry; - else if ((rc != -EIO) && (rc != -EREMOTE) && - (rc != -EOPNOTSUPP)) /* path not found or net err */ - goto cifs_create_out; - /* else fallthrough to retry, using older open call, this is - case where server does not support this SMB level, and - falsely claims capability (also get here for DFS case - which should be rare for path not covered on files) */ - } if (nd && (nd->flags & LOOKUP_OPEN)) { - /* if the file is going to stay open, then we - need to set the desired access properly */ + int oflags = nd->intent.open.flags; + desiredAccess = 0; if (oflags & FMODE_READ) - desiredAccess |= GENERIC_READ; /* is this too little? */ + desiredAccess |= GENERIC_READ; if (oflags & FMODE_WRITE) { desiredAccess |= GENERIC_WRITE; if (!(oflags & FMODE_READ)) @@ -308,6 +199,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, /* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */ + if (oplockEnabled) + oplock = REQ_OPLOCK; buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); if (buf == NULL) { @@ -340,112 +233,116 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, } if (rc) { cFYI(1, ("cifs_create returned 0x%x", rc)); - goto cifs_create_out; - } - - /* If Open reported that we actually created a file - then we now have to set the mode if possible */ - if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { - struct cifs_unix_set_info_args args = { + } else { + /* If Open reported that we actually created a file + then we now have to set the mode if possible */ + if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { + struct cifs_unix_set_info_args args = { .mode = mode, .ctime = NO_CHANGE_64, .atime = NO_CHANGE_64, .mtime = NO_CHANGE_64, .device = 0, - }; + }; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { - args.uid = (__u64) current_fsuid(); - if (inode->i_mode & S_ISGID) - args.gid = (__u64) inode->i_gid; - else - args.gid = (__u64) current_fsgid(); + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { + args.uid = (__u64) current_fsuid(); + if (inode->i_mode & S_ISGID) + args.gid = (__u64) inode->i_gid; + else + args.gid = (__u64) current_fsgid(); + } else { + args.uid = NO_CHANGE_64; + args.gid = NO_CHANGE_64; + } + CIFSSMBUnixSetInfo(xid, tcon, full_path, &args, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); } else { - args.uid = NO_CHANGE_64; - args.gid = NO_CHANGE_64; - } - CIFSSMBUnixSetInfo(xid, tcon, full_path, &args, - cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); - } else { - /* BB implement mode setting via Windows security - descriptors e.g. */ - /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ + /* BB implement mode setting via Windows security + descriptors e.g. */ + /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ - /* Could set r/o dos attribute if mode & 0222 == 0 */ - } + /* Could set r/o dos attribute if mode & 0222 == 0 */ + } -cifs_create_get_file_info: - /* server might mask mode so we have to query for it */ - if (tcon->unix_ext) - rc = cifs_get_inode_info_unix(&newinode, full_path, - inode->i_sb, xid); - else { - rc = cifs_get_inode_info(&newinode, full_path, buf, - inode->i_sb, xid, &fileHandle); - if (newinode) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) - newinode->i_mode = mode; - if ((oplock & CIFS_CREATE_ACTION) && - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { - newinode->i_uid = current_fsuid(); - if (inode->i_mode & S_ISGID) - newinode->i_gid = inode->i_gid; - else - newinode->i_gid = current_fsgid(); + /* server might mask mode so we have to query for it */ + if (tcon->unix_ext) + rc = cifs_get_inode_info_unix(&newinode, full_path, + inode->i_sb, xid); + else { + rc = cifs_get_inode_info(&newinode, full_path, + buf, inode->i_sb, xid, + &fileHandle); + if (newinode) { + if (cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_DYNPERM) + newinode->i_mode = mode; + if ((oplock & CIFS_CREATE_ACTION) && + (cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_SET_UID)) { + newinode->i_uid = current_fsuid(); + if (inode->i_mode & S_ISGID) + newinode->i_gid = + inode->i_gid; + else + newinode->i_gid = + current_fsgid(); + } } } - } -cifs_create_set_dentry: - if (rc == 0) - setup_cifs_dentry(tcon, direntry, newinode); - else - cFYI(1, ("Create worked, get_inode_info failed rc = %d", rc)); - - /* nfsd case - nfs srv does not set nd */ - if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { - /* mknod case - do not leave file open */ - CIFSSMBClose(xid, tcon, fileHandle); - } else if (newinode) { - struct cifsFileInfo *pCifsFile = - kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); - - if (pCifsFile == NULL) - goto cifs_create_out; - pCifsFile->netfid = fileHandle; - pCifsFile->pid = current->tgid; - pCifsFile->pInode = newinode; - pCifsFile->invalidHandle = false; - pCifsFile->closePend = false; - init_MUTEX(&pCifsFile->fh_sem); - mutex_init(&pCifsFile->lock_mutex); - INIT_LIST_HEAD(&pCifsFile->llist); - atomic_set(&pCifsFile->wrtPending, 0); - - /* set the following in open now + if (rc != 0) { + cFYI(1, ("Create worked, get_inode_info failed rc = %d", + rc)); + } else + setup_cifs_dentry(tcon, direntry, newinode); + + if ((nd == NULL /* nfsd case - nfs srv does not set nd */) || + (!(nd->flags & LOOKUP_OPEN))) { + /* mknod case - do not leave file open */ + CIFSSMBClose(xid, tcon, fileHandle); + } else if (newinode) { + struct cifsFileInfo *pCifsFile = + kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); + + if (pCifsFile == NULL) + goto cifs_create_out; + pCifsFile->netfid = fileHandle; + pCifsFile->pid = current->tgid; + pCifsFile->pInode = newinode; + pCifsFile->invalidHandle = false; + pCifsFile->closePend = false; + init_MUTEX(&pCifsFile->fh_sem); + mutex_init(&pCifsFile->lock_mutex); + INIT_LIST_HEAD(&pCifsFile->llist); + atomic_set(&pCifsFile->wrtPending, 0); + + /* set the following in open now pCifsFile->pfile = file; */ - write_lock(&GlobalSMBSeslock); - list_add(&pCifsFile->tlist, &tcon->openFileList); - pCifsInode = CIFS_I(newinode); - if (pCifsInode) { - /* if readable file instance put first in list*/ - if (write_only) { - list_add_tail(&pCifsFile->flist, - &pCifsInode->openFileList); - } else { - list_add(&pCifsFile->flist, - &pCifsInode->openFileList); + write_lock(&GlobalSMBSeslock); + list_add(&pCifsFile->tlist, &tcon->openFileList); + pCifsInode = CIFS_I(newinode); + if (pCifsInode) { + /* if readable file instance put first in list*/ + if (write_only) { + list_add_tail(&pCifsFile->flist, + &pCifsInode->openFileList); + } else { + list_add(&pCifsFile->flist, + &pCifsInode->openFileList); + } + if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { + pCifsInode->clientCanCacheAll = true; + pCifsInode->clientCanCacheRead = true; + cFYI(1, ("Exclusive Oplock inode %p", + newinode)); + } else if ((oplock & 0xF) == OPLOCK_READ) + pCifsInode->clientCanCacheRead = true; } - if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { - pCifsInode->clientCanCacheAll = true; - pCifsInode->clientCanCacheRead = true; - cFYI(1, ("Exclusive Oplock inode %p", - newinode)); - } else if ((oplock & 0xF) == OPLOCK_READ) - pCifsInode->clientCanCacheRead = true; + write_unlock(&GlobalSMBSeslock); } - write_unlock(&GlobalSMBSeslock); } cifs_create_out: kfree(buf); diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index 4690a360c855..bcf7b5184664 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -199,49 +199,6 @@ static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat, pfnd_dat->Gid = cpu_to_le64(pinode->i_gid); } -/** - * cifs_new inode - create new inode, initialize, and hash it - * @sb - pointer to superblock - * @inum - if valid pointer and serverino is enabled, replace i_ino with val - * - * Create a new inode, initialize it for CIFS and hash it. Returns the new - * inode or NULL if one couldn't be allocated. - * - * If the share isn't mounted with "serverino" or inum is a NULL pointer then - * we'll just use the inode number assigned by new_inode(). Note that this can - * mean i_ino collisions since the i_ino assigned by new_inode is not - * guaranteed to be unique. - */ -struct inode * -cifs_new_inode(struct super_block *sb, __u64 *inum) -{ - struct inode *inode; - - inode = new_inode(sb); - if (inode == NULL) - return NULL; - - /* - * BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we - * stop passing inum as ptr. Are there sanity checks we can use to - * ensure that the server is really filling in that field? Also, - * if serverino is disabled, perhaps we should be using iunique()? - */ - if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) - inode->i_ino = (unsigned long) *inum; - - /* - * must set this here instead of cifs_alloc_inode since VFS will - * clobber i_flags - */ - if (sb->s_flags & MS_NOATIME) - inode->i_flags |= S_NOATIME | S_NOCMTIME; - - insert_inode_hash(inode); - - return inode; -} - int cifs_get_inode_info_unix(struct inode **pinode, const unsigned char *full_path, struct super_block *sb, int xid) { @@ -276,11 +233,22 @@ int cifs_get_inode_info_unix(struct inode **pinode, /* get new inode */ if (*pinode == NULL) { - *pinode = cifs_new_inode(sb, &find_data.UniqueId); + *pinode = new_inode(sb); if (*pinode == NULL) { rc = -ENOMEM; goto cgiiu_exit; } + /* Is an i_ino of zero legal? */ + /* note ino incremented to unique num in new_inode */ + /* Are there sanity checks we can use to ensure that + the server is really filling in that field? */ + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) + (*pinode)->i_ino = (unsigned long)find_data.UniqueId; + + if (sb->s_flags & MS_NOATIME) + (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; + + insert_inode_hash(*pinode); } inode = *pinode; @@ -497,9 +465,11 @@ int cifs_get_inode_info(struct inode **pinode, /* get new inode */ if (*pinode == NULL) { - __u64 inode_num; - __u64 *pinum = &inode_num; - + *pinode = new_inode(sb); + if (*pinode == NULL) { + rc = -ENOMEM; + goto cgii_exit; + } /* Is an i_ino of zero legal? Can we use that to check if the server supports returning inode numbers? Are there other sanity checks we can use to ensure that @@ -516,26 +486,22 @@ int cifs_get_inode_info(struct inode **pinode, if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { int rc1 = 0; + __u64 inode_num; rc1 = CIFSGetSrvInodeNumber(xid, pTcon, - full_path, pinum, + full_path, &inode_num, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc1) { cFYI(1, ("GetSrvInodeNum rc %d", rc1)); - pinum = NULL; /* BB EOPNOSUPP disable SERVER_INUM? */ - } - } else { - pinum = NULL; - } - - *pinode = cifs_new_inode(sb, pinum); - if (*pinode == NULL) { - rc = -ENOMEM; - goto cgii_exit; - } + } else /* do we need cast or hash to ino? */ + (*pinode)->i_ino = inode_num; + } /* else ino incremented to unique num in new_inode*/ + if (sb->s_flags & MS_NOATIME) + (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; + insert_inode_hash(*pinode); } inode = *pinode; cifsInfo = CIFS_I(inode); @@ -655,7 +621,7 @@ static const struct inode_operations cifs_ipc_inode_ops = { .lookup = cifs_lookup, }; -char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) +static char *build_path_to_root(struct cifs_sb_info *cifs_sb) { int pplen = cifs_sb->prepathlen; int dfsplen; @@ -712,7 +678,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) return inode; cifs_sb = CIFS_SB(inode->i_sb); - full_path = cifs_build_path_to_root(cifs_sb); + full_path = build_path_to_root(cifs_sb); if (full_path == NULL) return ERR_PTR(-ENOMEM); @@ -1051,7 +1017,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) return rc; } -void posix_fill_in_inode(struct inode *tmp_inode, +static void posix_fill_in_inode(struct inode *tmp_inode, FILE_UNIX_BASIC_INFO *pData, int isNewInode) { struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); @@ -1148,14 +1114,24 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) else direntry->d_op = &cifs_dentry_ops; - newinode = cifs_new_inode(inode->i_sb, - &pInfo->UniqueId); + newinode = new_inode(inode->i_sb); if (newinode == NULL) { kfree(pInfo); goto mkdir_get_info; } + /* Is an i_ino of zero legal? */ + /* Are there sanity checks we can use to ensure that + the server is really filling in that field? */ + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { + newinode->i_ino = + (unsigned long)pInfo->UniqueId; + } /* note ino incremented to unique num in new_inode */ + if (inode->i_sb->s_flags & MS_NOATIME) + newinode->i_flags |= S_NOATIME | S_NOCMTIME; newinode->i_nlink = 2; + + insert_inode_hash(newinode); d_instantiate(direntry, newinode); /* we already checked in POSIXCreate whether diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index c2c01ff4c32c..9f51f9bf0292 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -56,34 +56,35 @@ static inline void dump_cifs_file_struct(struct file *file, char *label) } #endif /* DEBUG2 */ -/* Returns 1 if new inode created, 2 if both dentry and inode were */ +/* Returns one if new inode created (which therefore needs to be hashed) */ /* Might check in the future if inode number changed so we can rehash inode */ -static int -construct_dentry(struct qstr *qstring, struct file *file, - struct inode **ptmp_inode, struct dentry **pnew_dentry, - __u64 *inum) +static int construct_dentry(struct qstr *qstring, struct file *file, + struct inode **ptmp_inode, struct dentry **pnew_dentry) { - struct dentry *tmp_dentry = NULL; - struct super_block *sb = file->f_path.dentry->d_sb; + struct dentry *tmp_dentry; + struct cifs_sb_info *cifs_sb; + struct cifsTconInfo *pTcon; int rc = 0; cFYI(1, ("For %s", qstring->name)); + cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + pTcon = cifs_sb->tcon; qstring->hash = full_name_hash(qstring->name, qstring->len); tmp_dentry = d_lookup(file->f_path.dentry, qstring); if (tmp_dentry) { - /* BB: overwrite old name? i.e. tmp_dentry->d_name and - * tmp_dentry->d_name.len?? - */ cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); *ptmp_inode = tmp_dentry->d_inode; +/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ if (*ptmp_inode == NULL) { - *ptmp_inode = cifs_new_inode(sb, inum); + *ptmp_inode = new_inode(file->f_path.dentry->d_sb); if (*ptmp_inode == NULL) return rc; rc = 1; } + if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) + (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; } else { tmp_dentry = d_alloc(file->f_path.dentry, qstring); if (tmp_dentry == NULL) { @@ -92,14 +93,15 @@ construct_dentry(struct qstr *qstring, struct file *file, return rc; } - if (CIFS_SB(sb)->tcon->nocase) + *ptmp_inode = new_inode(file->f_path.dentry->d_sb); + if (pTcon->nocase) tmp_dentry->d_op = &cifs_ci_dentry_ops; else tmp_dentry->d_op = &cifs_dentry_ops; - - *ptmp_inode = cifs_new_inode(sb, inum); if (*ptmp_inode == NULL) return rc; + if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) + (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; rc = 2; } @@ -820,7 +822,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, /* inode num, inode type and filename returned */ static int cifs_get_name_from_search_buf(struct qstr *pqst, char *current_entry, __u16 level, unsigned int unicode, - struct cifs_sb_info *cifs_sb, int max_len, __u64 *pinum) + struct cifs_sb_info *cifs_sb, int max_len, ino_t *pinum) { int rc = 0; unsigned int len = 0; @@ -840,7 +842,9 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, len = strnlen(filename, PATH_MAX); } - *pinum = pFindData->UniqueId; + /* BB fixme - hash low and high 32 bits if not 64 bit arch BB */ + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) + *pinum = pFindData->UniqueId; } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { FILE_DIRECTORY_INFO *pFindData = (FILE_DIRECTORY_INFO *)current_entry; @@ -903,7 +907,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, struct qstr qstring; struct cifsFileInfo *pCifsF; unsigned int obj_type; - __u64 inum; + ino_t inum; struct cifs_sb_info *cifs_sb; struct inode *tmp_inode; struct dentry *tmp_dentry; @@ -936,18 +940,20 @@ static int cifs_filldir(char *pfindEntry, struct file *file, if (rc) return rc; - /* only these two infolevels return valid inode numbers */ - if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX || - pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) - rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, - &inum); - else - rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, - NULL); - + rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry); if ((tmp_inode == NULL) || (tmp_dentry == NULL)) return -ENOMEM; + if (rc) { + /* inode created, we need to hash it with right inode number */ + if (inum != 0) { + /* BB fixme - hash the 2 32 quantities bits together if + * necessary BB */ + tmp_inode->i_ino = inum; + } + insert_inode_hash(tmp_inode); + } + /* we pass in rc below, indicating whether it is a new inode, so we can figure out whether to invalidate the inode cached data if the file has changed */ diff --git a/trunk/fs/cifs/sess.c b/trunk/fs/cifs/sess.c index 5c68b4282be9..5f22de7b79a9 100644 --- a/trunk/fs/cifs/sess.c +++ b/trunk/fs/cifs/sess.c @@ -34,99 +34,15 @@ extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); -/* Checks if this is the first smb session to be reconnected after - the socket has been reestablished (so we know whether to use vc 0). - Called while holding the cifs_tcp_ses_lock, so do not block */ -static bool is_first_ses_reconnect(struct cifsSesInfo *ses) -{ - struct list_head *tmp; - struct cifsSesInfo *tmp_ses; - - list_for_each(tmp, &ses->server->smb_ses_list) { - tmp_ses = list_entry(tmp, struct cifsSesInfo, - smb_ses_list); - if (tmp_ses->need_reconnect == false) - return false; - } - /* could not find a session that was already connected, - this must be the first one we are reconnecting */ - return true; -} - -/* - * vc number 0 is treated specially by some servers, and should be the - * first one we request. After that we can use vcnumbers up to maxvcs, - * one for each smb session (some Windows versions set maxvcs incorrectly - * so maxvc=1 can be ignored). If we have too many vcs, we can reuse - * any vc but zero (some servers reset the connection on vcnum zero) - * - */ -static __le16 get_next_vcnum(struct cifsSesInfo *ses) -{ - __u16 vcnum = 0; - struct list_head *tmp; - struct cifsSesInfo *tmp_ses; - __u16 max_vcs = ses->server->max_vcs; - __u16 i; - int free_vc_found = 0; - - /* Quoting the MS-SMB specification: "Windows-based SMB servers set this - field to one but do not enforce this limit, which allows an SMB client - to establish more virtual circuits than allowed by this value ... but - other server implementations can enforce this limit." */ - if (max_vcs < 2) - max_vcs = 0xFFFF; - - write_lock(&cifs_tcp_ses_lock); - if ((ses->need_reconnect) && is_first_ses_reconnect(ses)) - goto get_vc_num_exit; /* vcnum will be zero */ - for (i = ses->server->srv_count - 1; i < max_vcs; i++) { - if (i == 0) /* this is the only connection, use vc 0 */ - break; - - free_vc_found = 1; - - list_for_each(tmp, &ses->server->smb_ses_list) { - tmp_ses = list_entry(tmp, struct cifsSesInfo, - smb_ses_list); - if (tmp_ses->vcnum == i) { - free_vc_found = 0; - break; /* found duplicate, try next vcnum */ - } - } - if (free_vc_found) - break; /* we found a vcnumber that will work - use it */ - } - - if (i == 0) - vcnum = 0; /* for most common case, ie if one smb session, use - vc zero. Also for case when no free vcnum, zero - is safest to send (some clients only send zero) */ - else if (free_vc_found == 0) - vcnum = 1; /* we can not reuse vc=0 safely, since some servers - reset all uids on that, but 1 is ok. */ - else - vcnum = i; - ses->vcnum = vcnum; -get_vc_num_exit: - write_unlock(&cifs_tcp_ses_lock); - - return le16_to_cpu(vcnum); -} - static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) { __u32 capabilities = 0; /* init fields common to all four types of SessSetup */ - /* Note that offsets for first seven fields in req struct are same */ - /* in CIFS Specs so does not matter which of 3 forms of struct */ - /* that we use in next few lines */ - /* Note that header is initialized to zero in header_assemble */ + /* note that header is initialized to zero in header_assemble */ pSMB->req.AndXCommand = 0xFF; pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); - pSMB->req.VcNumber = get_next_vcnum(ses); /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ @@ -155,6 +71,7 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) if (ses->capabilities & CAP_UNIX) capabilities |= CAP_UNIX; + /* BB check whether to init vcnum BB */ return capabilities; } @@ -311,7 +228,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, kfree(ses->serverOS); /* UTF-8 string will not grow more than four times as big as UCS-16 */ - ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); + ses->serverOS = kzalloc(4 * len, GFP_KERNEL); if (ses->serverOS != NULL) cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); data += 2 * (len + 1); @@ -324,7 +241,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, return rc; kfree(ses->serverNOS); - ses->serverNOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); + ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ if (ses->serverNOS != NULL) { cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, nls_cp); diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index d0145ca27572..65a070e705ab 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -1407,7 +1407,7 @@ int compat_do_execve(char * filename, bprm->cred = prepare_exec_creds(); if (!bprm->cred) goto out_unlock; - check_unsafe_exec(bprm, current->files); + check_unsafe_exec(bprm); file = open_exec(filename); retval = PTR_ERR(file); diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index 45e59d3c7f1f..c8f8d5904f5e 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -785,7 +785,7 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) if (copy_in_user(&sgio->status, &sgio32->status, (4 * sizeof(unsigned char)) + - (2 * sizeof(unsigned short)) + + (2 * sizeof(unsigned (short))) + (3 * sizeof(int)))) return -EFAULT; @@ -1913,9 +1913,6 @@ COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */ /* 0x00 */ COMPATIBLE_IOCTL(FIBMAP) COMPATIBLE_IOCTL(FIGETBSZ) -/* 'X' - originally XFS but some now in the VFS */ -COMPATIBLE_IOCTL(FIFREEZE) -COMPATIBLE_IOCTL(FITHAW) /* RAID */ COMPATIBLE_IOCTL(RAID_VERSION) COMPATIBLE_IOCTL(GET_ARRAY_INFO) @@ -1941,8 +1938,6 @@ ULONG_IOCTL(SET_BITMAP_FILE) /* Big K */ COMPATIBLE_IOCTL(PIO_FONT) COMPATIBLE_IOCTL(GIO_FONT) -COMPATIBLE_IOCTL(PIO_CMAP) -COMPATIBLE_IOCTL(GIO_CMAP) ULONG_IOCTL(KDSIGACCEPT) COMPATIBLE_IOCTL(KDGETKEYCODE) COMPATIBLE_IOCTL(KDSETKEYCODE) diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index 07e2d4a44bda..937df0fb0da5 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -1180,7 +1180,7 @@ struct dentry *d_obtain_alias(struct inode *inode) iput(inode); return res; } -EXPORT_SYMBOL(d_obtain_alias); +EXPORT_SYMBOL_GPL(d_obtain_alias); /** * d_splice_alias - splice a disconnected dentry into the tree if one exists diff --git a/trunk/fs/ecryptfs/crypto.c b/trunk/fs/ecryptfs/crypto.c index f6caeb1d1106..c01e043670e2 100644 --- a/trunk/fs/ecryptfs/crypto.c +++ b/trunk/fs/ecryptfs/crypto.c @@ -1716,7 +1716,7 @@ static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size, { int rc = 0; - (*copied_name) = kmalloc((name_size + 1), GFP_KERNEL); + (*copied_name) = kmalloc((name_size + 2), GFP_KERNEL); if (!(*copied_name)) { rc = -ENOMEM; goto out; @@ -1726,7 +1726,7 @@ static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size, * in printing out the * string in debug * messages */ - (*copied_name_size) = name_size; + (*copied_name_size) = (name_size + 1); out: return rc; } diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 929b58004b7e..0dd60a01f1b4 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -1049,32 +1049,16 @@ EXPORT_SYMBOL(install_exec_creds); * - the caller must hold current->cred_exec_mutex to protect against * PTRACE_ATTACH */ -void check_unsafe_exec(struct linux_binprm *bprm, struct files_struct *files) +void check_unsafe_exec(struct linux_binprm *bprm) { - struct task_struct *p = current, *t; - unsigned long flags; - unsigned n_fs, n_files, n_sighand; + struct task_struct *p = current; bprm->unsafe = tracehook_unsafe_exec(p); - n_fs = 1; - n_files = 1; - n_sighand = 1; - lock_task_sighand(p, &flags); - for (t = next_thread(p); t != p; t = next_thread(t)) { - if (t->fs == p->fs) - n_fs++; - if (t->files == files) - n_files++; - n_sighand++; - } - - if (atomic_read(&p->fs->count) > n_fs || - atomic_read(&p->files->count) > n_files || - atomic_read(&p->sighand->count) > n_sighand) + if (atomic_read(&p->fs->count) > 1 || + atomic_read(&p->files->count) > 1 || + atomic_read(&p->sighand->count) > 1) bprm->unsafe |= LSM_UNSAFE_SHARE; - - unlock_task_sighand(p, &flags); } /* @@ -1289,7 +1273,7 @@ int do_execve(char * filename, bprm->cred = prepare_exec_creds(); if (!bprm->cred) goto out_unlock; - check_unsafe_exec(bprm, displaced); + check_unsafe_exec(bprm); file = open_exec(filename); retval = PTR_ERR(file); diff --git a/trunk/fs/ext2/super.c b/trunk/fs/ext2/super.c index 7c6e3606f0ec..da8bdeaa2e6d 100644 --- a/trunk/fs/ext2/super.c +++ b/trunk/fs/ext2/super.c @@ -1185,12 +1185,9 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) es = sbi->s_es; if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) != (old_mount_opt & EXT2_MOUNT_XIP)) && - invalidate_inodes(sb)) { - ext2_warning(sb, __func__, "refusing change of xip flag " - "with busy inodes while remounting"); - sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; - sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP; - } + invalidate_inodes(sb)) + ext2_warning(sb, __func__, "busy inodes while remounting "\ + "xip remain in cache (no functional problem)"); if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; if (*flags & MS_RDONLY) { diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index 4a970411a458..b70d90e08a3c 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -2428,13 +2428,12 @@ static void ext3_write_super (struct super_block * sb) static int ext3_sync_fs(struct super_block *sb, int wait) { - tid_t target; - sb->s_dirt = 0; - if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) { - if (wait) - log_wait_commit(EXT3_SB(sb)->s_journal, target); - } + if (wait) + ext3_force_commit(sb); + else + journal_start_commit(EXT3_SB(sb)->s_journal, NULL); + return 0; } diff --git a/trunk/fs/ext4/balloc.c b/trunk/fs/ext4/balloc.c index de9459b4cb94..9a50b8052dcf 100644 --- a/trunk/fs/ext4/balloc.c +++ b/trunk/fs/ext4/balloc.c @@ -609,9 +609,7 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi, */ int ext4_should_retry_alloc(struct super_block *sb, int *retries) { - if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || - (*retries)++ > 3 || - !EXT4_SB(sb)->s_journal) + if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || (*retries)++ > 3) return 0; jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index b0c87dce66a3..aafc9eba1c25 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -868,7 +868,7 @@ static inline unsigned ext4_rec_len_from_disk(__le16 dlen) { unsigned len = le16_to_cpu(dlen); - if (len == EXT4_MAX_REC_LEN || len == 0) + if (len == EXT4_MAX_REC_LEN) return 1 << 16; return len; } diff --git a/trunk/fs/ext4/ialloc.c b/trunk/fs/ext4/ialloc.c index f18a919be70b..4fb86a0061d0 100644 --- a/trunk/fs/ext4/ialloc.c +++ b/trunk/fs/ext4/ialloc.c @@ -715,13 +715,6 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) if (sbi->s_log_groups_per_flex) { ret2 = find_group_flex(sb, dir, &group); - if (ret2 == -1) { - ret2 = find_group_other(sb, dir, &group); - if (ret2 == 0 && printk_ratelimit()) - printk(KERN_NOTICE "ext4: find_group_flex " - "failed, fallback succeeded dir %lu\n", - dir->i_ino); - } goto got_group; } diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index c7fed5b18745..03ba20be1329 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -47,10 +47,8 @@ static inline int ext4_begin_ordered_truncate(struct inode *inode, loff_t new_size) { - return jbd2_journal_begin_ordered_truncate( - EXT4_SB(inode->i_sb)->s_journal, - &EXT4_I(inode)->jinode, - new_size); + return jbd2_journal_begin_ordered_truncate(&EXT4_I(inode)->jinode, + new_size); } static void ext4_invalidatepage(struct page *page, unsigned long offset); @@ -1368,10 +1366,6 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, goto out; } - /* We cannot recurse into the filesystem as the transaction is already - * started */ - flags |= AOP_FLAG_NOFS; - page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { ext4_journal_stop(handle); @@ -1381,7 +1375,7 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, *pagep = page; ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, - ext4_get_block); + ext4_get_block); if (!ret && ext4_should_journal_data(inode)) { ret = walk_page_buffers(handle, page_buffers(page), @@ -2443,7 +2437,6 @@ static int ext4_da_writepages(struct address_space *mapping, int no_nrwrite_index_update; int pages_written = 0; long pages_skipped; - int range_cyclic, cycled = 1, io_done = 0; int needed_blocks, ret = 0, nr_to_writebump = 0; struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); @@ -2495,15 +2488,9 @@ static int ext4_da_writepages(struct address_space *mapping, if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) range_whole = 1; - range_cyclic = wbc->range_cyclic; - if (wbc->range_cyclic) { + if (wbc->range_cyclic) index = mapping->writeback_index; - if (index) - cycled = 0; - wbc->range_start = index << PAGE_CACHE_SHIFT; - wbc->range_end = LLONG_MAX; - wbc->range_cyclic = 0; - } else + else index = wbc->range_start >> PAGE_CACHE_SHIFT; mpd.wbc = wbc; @@ -2517,7 +2504,6 @@ static int ext4_da_writepages(struct address_space *mapping, wbc->no_nrwrite_index_update = 1; pages_skipped = wbc->pages_skipped; -retry: while (!ret && wbc->nr_to_write > 0) { /* @@ -2544,7 +2530,7 @@ static int ext4_da_writepages(struct address_space *mapping, ext4_journal_stop(handle); - if ((mpd.retval == -ENOSPC) && sbi->s_journal) { + if (mpd.retval == -ENOSPC) { /* commit the transaction which would * free blocks released in the transaction * and try again @@ -2560,7 +2546,6 @@ static int ext4_da_writepages(struct address_space *mapping, pages_written += mpd.pages_written; wbc->pages_skipped = pages_skipped; ret = 0; - io_done = 1; } else if (wbc->nr_to_write) /* * There is no more writeout needed @@ -2569,13 +2554,6 @@ static int ext4_da_writepages(struct address_space *mapping, */ break; } - if (!io_done && !cycled) { - cycled = 1; - index = 0; - wbc->range_start = index << PAGE_CACHE_SHIFT; - wbc->range_end = mapping->writeback_index - 1; - goto retry; - } if (pages_skipped != wbc->pages_skipped) printk(KERN_EMERG "This should not happen leaving %s " "with nr_to_write = %ld ret = %d\n", @@ -2583,7 +2561,6 @@ static int ext4_da_writepages(struct address_space *mapping, /* Update index */ index += pages_written; - wbc->range_cyclic = range_cyclic; if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) /* * set the writeback_index so that range_cyclic @@ -2671,9 +2648,6 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, ret = PTR_ERR(handle); goto out; } - /* We cannot recurse into the filesystem as the transaction is already - * started */ - flags |= AOP_FLAG_NOFS; page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index 4415beeb0b62..deba54f6cbed 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -3693,8 +3693,6 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) pa->pa_free = pa->pa_len; atomic_set(&pa->pa_count, 1); spin_lock_init(&pa->pa_lock); - INIT_LIST_HEAD(&pa->pa_inode_list); - INIT_LIST_HEAD(&pa->pa_group_list); pa->pa_deleted = 0; pa->pa_linear = 0; @@ -3757,7 +3755,6 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac) atomic_set(&pa->pa_count, 1); spin_lock_init(&pa->pa_lock); INIT_LIST_HEAD(&pa->pa_inode_list); - INIT_LIST_HEAD(&pa->pa_group_list); pa->pa_deleted = 0; pa->pa_linear = 1; @@ -4479,26 +4476,23 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac) pa->pa_free -= ac->ac_b_ex.fe_len; pa->pa_len -= ac->ac_b_ex.fe_len; spin_unlock(&pa->pa_lock); + /* + * We want to add the pa to the right bucket. + * Remove it from the list and while adding + * make sure the list to which we are adding + * doesn't grow big. + */ + if (likely(pa->pa_free)) { + spin_lock(pa->pa_obj_lock); + list_del_rcu(&pa->pa_inode_list); + spin_unlock(pa->pa_obj_lock); + ext4_mb_add_n_trim(ac); + } } + ext4_mb_put_pa(ac, ac->ac_sb, pa); } if (ac->alloc_semp) up_read(ac->alloc_semp); - if (pa) { - /* - * We want to add the pa to the right bucket. - * Remove it from the list and while adding - * make sure the list to which we are adding - * doesn't grow big. We need to release - * alloc_semp before calling ext4_mb_add_n_trim() - */ - if (pa->pa_linear && likely(pa->pa_free)) { - spin_lock(pa->pa_obj_lock); - list_del_rcu(&pa->pa_inode_list); - spin_unlock(pa->pa_obj_lock); - ext4_mb_add_n_trim(ac); - } - ext4_mb_put_pa(ac, ac->ac_sb, pa); - } if (ac->ac_bitmap_page) page_cache_release(ac->ac_bitmap_page); if (ac->ac_buddy_page) diff --git a/trunk/fs/ext4/migrate.c b/trunk/fs/ext4/migrate.c index fe64d9f79852..734abca25e35 100644 --- a/trunk/fs/ext4/migrate.c +++ b/trunk/fs/ext4/migrate.c @@ -481,7 +481,7 @@ int ext4_ext_migrate(struct inode *inode) + 1); if (IS_ERR(handle)) { retval = PTR_ERR(handle); - return retval; + goto err_out; } tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode, @@ -489,7 +489,8 @@ int ext4_ext_migrate(struct inode *inode) if (IS_ERR(tmp_inode)) { retval = -ENOMEM; ext4_journal_stop(handle); - return retval; + tmp_inode = NULL; + goto err_out; } i_size_write(tmp_inode, i_size_read(inode)); /* @@ -617,7 +618,8 @@ int ext4_ext_migrate(struct inode *inode) ext4_journal_stop(handle); - iput(tmp_inode); + if (tmp_inode) + iput(tmp_inode); return retval; } diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 39d1993cfa13..e5f06a5f045e 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -3046,17 +3046,14 @@ static void ext4_write_super(struct super_block *sb) static int ext4_sync_fs(struct super_block *sb, int wait) { int ret = 0; - tid_t target; trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); sb->s_dirt = 0; if (EXT4_SB(sb)->s_journal) { - if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, - &target)) { - if (wait) - jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, - target); - } + if (wait) + ret = ext4_force_commit(sb); + else + jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL); } else { ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait); } @@ -3091,6 +3088,7 @@ static int ext4_freeze(struct super_block *sb) /* Journal blocked and flushed, clear needs_recovery flag. */ EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); + ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); if (error) goto out; diff --git a/trunk/fs/hugetlbfs/inode.c b/trunk/fs/hugetlbfs/inode.c index 9b800d97a687..6903d37af037 100644 --- a/trunk/fs/hugetlbfs/inode.c +++ b/trunk/fs/hugetlbfs/inode.c @@ -108,8 +108,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) if (hugetlb_reserve_pages(inode, vma->vm_pgoff >> huge_page_order(h), - len >> huge_page_shift(h), vma, - vma->vm_flags)) + len >> huge_page_shift(h), vma)) goto out; ret = 0; @@ -948,7 +947,7 @@ static int can_do_hugetlb_shm(void) can_do_mlock()); } -struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag) +struct file *hugetlb_file_setup(const char *name, size_t size) { int error = -ENOMEM; struct file *file; @@ -982,8 +981,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag) error = -ENOMEM; if (hugetlb_reserve_pages(inode, 0, - size >> huge_page_shift(hstate_inode(inode)), NULL, - acctflag)) + size >> huge_page_shift(hstate_inode(inode)), NULL)) goto out_inode; d_instantiate(dentry, inode); diff --git a/trunk/fs/internal.h b/trunk/fs/internal.h index 0d8ac497b3d5..53af885f1732 100644 --- a/trunk/fs/internal.h +++ b/trunk/fs/internal.h @@ -43,7 +43,7 @@ extern void __init chrdev_init(void); /* * exec.c */ -extern void check_unsafe_exec(struct linux_binprm *, struct files_struct *); +extern void check_unsafe_exec(struct linux_binprm *); /* * namespace.c diff --git a/trunk/fs/jbd/journal.c b/trunk/fs/jbd/journal.c index e79c07812afa..9e4fa52d7dc8 100644 --- a/trunk/fs/jbd/journal.c +++ b/trunk/fs/jbd/journal.c @@ -427,7 +427,7 @@ int __log_space_left(journal_t *journal) } /* - * Called under j_state_lock. Returns true if a transaction commit was started. + * Called under j_state_lock. Returns true if a transaction was started. */ int __log_start_commit(journal_t *journal, tid_t target) { @@ -495,8 +495,7 @@ int journal_force_commit_nested(journal_t *journal) /* * Start a commit of the current running transaction (if any). Returns true - * if a transaction is going to be committed (or is currently already - * committing), and fills its tid in at *ptid + * if a transaction was started, and fills its tid in at *ptid */ int journal_start_commit(journal_t *journal, tid_t *ptid) { @@ -506,19 +505,15 @@ int journal_start_commit(journal_t *journal, tid_t *ptid) if (journal->j_running_transaction) { tid_t tid = journal->j_running_transaction->t_tid; - __log_start_commit(journal, tid); - /* There's a running transaction and we've just made sure - * it's commit has been scheduled. */ - if (ptid) + ret = __log_start_commit(journal, tid); + if (ret && ptid) *ptid = tid; - ret = 1; - } else if (journal->j_committing_transaction) { + } else if (journal->j_committing_transaction && ptid) { /* * If ext3_write_super() recently started a commit, then we * have to wait for completion of that transaction */ - if (ptid) - *ptid = journal->j_committing_transaction->t_tid; + *ptid = journal->j_committing_transaction->t_tid; ret = 1; } spin_unlock(&journal->j_state_lock); diff --git a/trunk/fs/jbd2/journal.c b/trunk/fs/jbd2/journal.c index 58144102bf25..eb343008eded 100644 --- a/trunk/fs/jbd2/journal.c +++ b/trunk/fs/jbd2/journal.c @@ -450,7 +450,7 @@ int __jbd2_log_space_left(journal_t *journal) } /* - * Called under j_state_lock. Returns true if a transaction commit was started. + * Called under j_state_lock. Returns true if a transaction was started. */ int __jbd2_log_start_commit(journal_t *journal, tid_t target) { @@ -518,8 +518,7 @@ int jbd2_journal_force_commit_nested(journal_t *journal) /* * Start a commit of the current running transaction (if any). Returns true - * if a transaction is going to be committed (or is currently already - * committing), and fills its tid in at *ptid + * if a transaction was started, and fills its tid in at *ptid */ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) { @@ -529,19 +528,15 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) if (journal->j_running_transaction) { tid_t tid = journal->j_running_transaction->t_tid; - __jbd2_log_start_commit(journal, tid); - /* There's a running transaction and we've just made sure - * it's commit has been scheduled. */ - if (ptid) + ret = __jbd2_log_start_commit(journal, tid); + if (ret && ptid) *ptid = tid; - ret = 1; - } else if (journal->j_committing_transaction) { + } else if (journal->j_committing_transaction && ptid) { /* * If ext3_write_super() recently started a commit, then we * have to wait for completion of that transaction */ - if (ptid) - *ptid = journal->j_committing_transaction->t_tid; + *ptid = journal->j_committing_transaction->t_tid; ret = 1; } spin_unlock(&journal->j_state_lock); diff --git a/trunk/fs/jbd2/transaction.c b/trunk/fs/jbd2/transaction.c index 28ce21d8598e..46b4e347ed7d 100644 --- a/trunk/fs/jbd2/transaction.c +++ b/trunk/fs/jbd2/transaction.c @@ -2129,46 +2129,26 @@ int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode) } /* - * File truncate and transaction commit interact with each other in a - * non-trivial way. If a transaction writing data block A is - * committing, we cannot discard the data by truncate until we have - * written them. Otherwise if we crashed after the transaction with - * write has committed but before the transaction with truncate has - * committed, we could see stale data in block A. This function is a - * helper to solve this problem. It starts writeout of the truncated - * part in case it is in the committing transaction. - * - * Filesystem code must call this function when inode is journaled in - * ordered mode before truncation happens and after the inode has been - * placed on orphan list with the new inode size. The second condition - * avoids the race that someone writes new data and we start - * committing the transaction after this function has been called but - * before a transaction for truncate is started (and furthermore it - * allows us to optimize the case where the addition to orphan list - * happens in the same transaction as write --- we don't have to write - * any data in such case). + * This function must be called when inode is journaled in ordered mode + * before truncation happens. It starts writeout of truncated part in + * case it is in the committing transaction so that we stand to ordered + * mode consistency guarantees. */ -int jbd2_journal_begin_ordered_truncate(journal_t *journal, - struct jbd2_inode *jinode, +int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode, loff_t new_size) { - transaction_t *inode_trans, *commit_trans; + journal_t *journal; + transaction_t *commit_trans; int ret = 0; - /* This is a quick check to avoid locking if not necessary */ - if (!jinode->i_transaction) + if (!inode->i_transaction && !inode->i_next_transaction) goto out; - /* Locks are here just to force reading of recent values, it is - * enough that the transaction was not committing before we started - * a transaction adding the inode to orphan list */ + journal = inode->i_transaction->t_journal; spin_lock(&journal->j_state_lock); commit_trans = journal->j_committing_transaction; spin_unlock(&journal->j_state_lock); - spin_lock(&journal->j_list_lock); - inode_trans = jinode->i_transaction; - spin_unlock(&journal->j_list_lock); - if (inode_trans == commit_trans) { - ret = filemap_fdatawrite_range(jinode->i_vfs_inode->i_mapping, + if (inode->i_transaction == commit_trans) { + ret = filemap_fdatawrite_range(inode->i_vfs_inode->i_mapping, new_size, LLONG_MAX); if (ret) jbd2_journal_abort(journal, ret); diff --git a/trunk/fs/jffs2/background.c b/trunk/fs/jffs2/background.c index e9580104b6ba..3cceef4ad2b7 100644 --- a/trunk/fs/jffs2/background.c +++ b/trunk/fs/jffs2/background.c @@ -95,17 +95,13 @@ static int jffs2_garbage_collect_thread(void *_c) spin_unlock(&c->erase_completion_lock); - /* Problem - immediately after bootup, the GCD spends a lot - * of time in places like jffs2_kill_fragtree(); so much so - * that userspace processes (like gdm and X) are starved - * despite plenty of cond_resched()s and renicing. Yield() - * doesn't help, either (presumably because userspace and GCD - * are generally competing for a higher latency resource - - * disk). - * This forces the GCD to slow the hell down. Pulling an - * inode in with read_inode() is much preferable to having - * the GC thread get there first. */ - schedule_timeout_interruptible(msecs_to_jiffies(50)); + /* This thread is purely an optimisation. But if it runs when + other things could be running, it actually makes things a + lot worse. Use yield() and put it at the back of the runqueue + every time. Especially during boot, pulling an inode in + with read_inode() is much preferable to having the GC thread + get there first. */ + yield(); /* Put_super will send a SIGKILL and then wait on the sem. */ diff --git a/trunk/fs/jffs2/readinode.c b/trunk/fs/jffs2/readinode.c index 1fc1e92356ee..6ca08ad887c0 100644 --- a/trunk/fs/jffs2/readinode.c +++ b/trunk/fs/jffs2/readinode.c @@ -220,7 +220,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) { uint32_t fn_end = tn->fn->ofs + tn->fn->size; - struct jffs2_tmp_dnode_info *this, *ptn; + struct jffs2_tmp_dnode_info *this; dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw)); @@ -251,18 +251,11 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, if (this) { /* If the node is coincident with another at a lower address, back up until the other node is found. It may be relevant */ - while (this->overlapped) { - ptn = tn_prev(this); - if (!ptn) { - /* - * We killed a node which set the overlapped - * flags during the scan. Fix it up. - */ - this->overlapped = 0; - break; - } - this = ptn; - } + while (this->overlapped) + this = tn_prev(this); + + /* First node should never be marked overlapped */ + BUG_ON(!this); dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole"); } @@ -367,17 +360,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, } if (!this->overlapped) break; - - ptn = tn_prev(this); - if (!ptn) { - /* - * We killed a node which set the overlapped - * flags during the scan. Fix it up. - */ - this->overlapped = 0; - break; - } - this = ptn; + this = tn_prev(this); } } @@ -473,15 +456,8 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c, eat_last(&rii->tn_root, &last->rb); ver_insert(&ver_root, last); - if (unlikely(last->overlapped)) { - if (pen) - continue; - /* - * We killed a node which set the overlapped - * flags during the scan. Fix it up. - */ - last->overlapped = 0; - } + if (unlikely(last->overlapped)) + continue; /* Now we have a bunch of nodes in reverse version order, in the tree at ver_root. Most of the time, diff --git a/trunk/fs/lockd/svclock.c b/trunk/fs/lockd/svclock.c index 763b78a6e9de..6063a8e4b9f3 100644 --- a/trunk/fs/lockd/svclock.c +++ b/trunk/fs/lockd/svclock.c @@ -427,7 +427,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, goto out; case -EAGAIN: ret = nlm_lck_denied; - break; + goto out; case FILE_LOCK_DEFERRED: if (wait) break; @@ -443,10 +443,6 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, goto out; } - ret = nlm_lck_denied; - if (!wait) - goto out; - ret = nlm_lck_blocked; /* Append to list of blocked */ diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 06f8e63f6cb1..228d8c4bfd18 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -614,11 +614,9 @@ static inline void __mntput(struct vfsmount *mnt) */ for_each_possible_cpu(cpu) { struct mnt_writer *cpu_writer = &per_cpu(mnt_writers, cpu); - spin_lock(&cpu_writer->lock); - if (cpu_writer->mnt != mnt) { - spin_unlock(&cpu_writer->lock); + if (cpu_writer->mnt != mnt) continue; - } + spin_lock(&cpu_writer->lock); atomic_add(cpu_writer->count, &mnt->__mnt_writers); cpu_writer->count = 0; /* diff --git a/trunk/fs/notify/inotify/inotify.c b/trunk/fs/notify/inotify/inotify.c index 331f2e88e284..dae3f28f30d4 100644 --- a/trunk/fs/notify/inotify/inotify.c +++ b/trunk/fs/notify/inotify/inotify.c @@ -156,7 +156,7 @@ static int inotify_handle_get_wd(struct inotify_handle *ih, int ret; do { - if (unlikely(!idr_pre_get(&ih->idr, GFP_NOFS))) + if (unlikely(!idr_pre_get(&ih->idr, GFP_KERNEL))) return -ENOSPC; ret = idr_get_new_above(&ih->idr, watch, ih->last_wd+1, &watch->wd); } while (ret == -EAGAIN); diff --git a/trunk/fs/ocfs2/alloc.c b/trunk/fs/ocfs2/alloc.c index 3a9e5deed74d..d861096c9d81 100644 --- a/trunk/fs/ocfs2/alloc.c +++ b/trunk/fs/ocfs2/alloc.c @@ -4796,29 +4796,6 @@ static int ocfs2_split_and_insert(struct inode *inode, return ret; } -static int ocfs2_replace_extent_rec(struct inode *inode, - handle_t *handle, - struct ocfs2_path *path, - struct ocfs2_extent_list *el, - int split_index, - struct ocfs2_extent_rec *split_rec) -{ - int ret; - - ret = ocfs2_path_bh_journal_access(handle, inode, path, - path_num_items(path) - 1); - if (ret) { - mlog_errno(ret); - goto out; - } - - el->l_recs[split_index] = *split_rec; - - ocfs2_journal_dirty(handle, path_leaf_bh(path)); -out: - return ret; -} - /* * Mark part or all of the extent record at split_index in the leaf * pointed to by path as written. This removes the unwritten @@ -4908,9 +4885,7 @@ static int __ocfs2_mark_extent_written(struct inode *inode, if (ctxt.c_contig_type == CONTIG_NONE) { if (ctxt.c_split_covers_rec) - ret = ocfs2_replace_extent_rec(inode, handle, - path, el, - split_index, split_rec); + el->l_recs[split_index] = *split_rec; else ret = ocfs2_split_and_insert(inode, handle, path, et, &last_eb_bh, split_index, @@ -5415,9 +5390,6 @@ int ocfs2_remove_btree_range(struct inode *inode, goto out; } - vfs_dq_free_space_nodirty(inode, - ocfs2_clusters_to_bytes(inode->i_sb, len)); - ret = ocfs2_remove_extent(inode, et, cpos, len, handle, meta_ac, dealloc); if (ret) { diff --git a/trunk/fs/ocfs2/dcache.c b/trunk/fs/ocfs2/dcache.c index e9d7c2038c0f..b1cc7c381e88 100644 --- a/trunk/fs/ocfs2/dcache.c +++ b/trunk/fs/ocfs2/dcache.c @@ -38,7 +38,6 @@ #include "dlmglue.h" #include "file.h" #include "inode.h" -#include "super.h" static int ocfs2_dentry_revalidate(struct dentry *dentry, @@ -295,34 +294,6 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry, return ret; } -static DEFINE_SPINLOCK(dentry_list_lock); - -/* We limit the number of dentry locks to drop in one go. We have - * this limit so that we don't starve other users of ocfs2_wq. */ -#define DL_INODE_DROP_COUNT 64 - -/* Drop inode references from dentry locks */ -void ocfs2_drop_dl_inodes(struct work_struct *work) -{ - struct ocfs2_super *osb = container_of(work, struct ocfs2_super, - dentry_lock_work); - struct ocfs2_dentry_lock *dl; - int drop_count = DL_INODE_DROP_COUNT; - - spin_lock(&dentry_list_lock); - while (osb->dentry_lock_list && drop_count--) { - dl = osb->dentry_lock_list; - osb->dentry_lock_list = dl->dl_next; - spin_unlock(&dentry_list_lock); - iput(dl->dl_inode); - kfree(dl); - spin_lock(&dentry_list_lock); - } - if (osb->dentry_lock_list) - queue_work(ocfs2_wq, &osb->dentry_lock_work); - spin_unlock(&dentry_list_lock); -} - /* * ocfs2_dentry_iput() and friends. * @@ -347,23 +318,16 @@ void ocfs2_drop_dl_inodes(struct work_struct *work) static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb, struct ocfs2_dentry_lock *dl) { + iput(dl->dl_inode); ocfs2_simple_drop_lockres(osb, &dl->dl_lockres); ocfs2_lock_res_free(&dl->dl_lockres); - - /* We leave dropping of inode reference to ocfs2_wq as that can - * possibly lead to inode deletion which gets tricky */ - spin_lock(&dentry_list_lock); - if (!osb->dentry_lock_list) - queue_work(ocfs2_wq, &osb->dentry_lock_work); - dl->dl_next = osb->dentry_lock_list; - osb->dentry_lock_list = dl; - spin_unlock(&dentry_list_lock); + kfree(dl); } void ocfs2_dentry_lock_put(struct ocfs2_super *osb, struct ocfs2_dentry_lock *dl) { - int unlock; + int unlock = 0; BUG_ON(dl->dl_count == 0); diff --git a/trunk/fs/ocfs2/dcache.h b/trunk/fs/ocfs2/dcache.h index d06e16c06640..c091c34d9883 100644 --- a/trunk/fs/ocfs2/dcache.h +++ b/trunk/fs/ocfs2/dcache.h @@ -29,13 +29,8 @@ extern struct dentry_operations ocfs2_dentry_ops; struct ocfs2_dentry_lock { - /* Use count of dentry lock */ unsigned int dl_count; - union { - /* Linked list of dentry locks to release */ - struct ocfs2_dentry_lock *dl_next; - u64 dl_parent_blkno; - }; + u64 dl_parent_blkno; /* * The ocfs2_dentry_lock keeps an inode reference until @@ -52,8 +47,6 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry, struct inode *inode, void ocfs2_dentry_lock_put(struct ocfs2_super *osb, struct ocfs2_dentry_lock *dl); -void ocfs2_drop_dl_inodes(struct work_struct *work); - struct dentry *ocfs2_find_local_alias(struct inode *inode, u64 parent_blkno, int skip_unhashed); diff --git a/trunk/fs/ocfs2/dlm/dlmmaster.c b/trunk/fs/ocfs2/dlm/dlmmaster.c index 0a2813947853..54e182a27caf 100644 --- a/trunk/fs/ocfs2/dlm/dlmmaster.c +++ b/trunk/fs/ocfs2/dlm/dlmmaster.c @@ -1849,12 +1849,12 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, if (!mle) { if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN && res->owner != assert->node_idx) { - mlog(ML_ERROR, "DIE! Mastery assert from %u, " - "but current owner is %u! (%.*s)\n", - assert->node_idx, res->owner, namelen, - name); - __dlm_print_one_lock_resource(res); - BUG(); + mlog(ML_ERROR, "assert_master from " + "%u, but current owner is " + "%u! (%.*s)\n", + assert->node_idx, res->owner, + namelen, name); + goto kill; } } else if (mle->type != DLM_MLE_MIGRATION) { if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) { diff --git a/trunk/fs/ocfs2/dlm/dlmthread.c b/trunk/fs/ocfs2/dlm/dlmthread.c index 4060bb328bc8..d1295203029f 100644 --- a/trunk/fs/ocfs2/dlm/dlmthread.c +++ b/trunk/fs/ocfs2/dlm/dlmthread.c @@ -181,7 +181,8 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm, spin_lock(&res->spinlock); /* This ensures that clear refmap is sent after the set */ - __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); + __dlm_wait_on_lockres_flags(res, (DLM_LOCK_RES_SETREF_INPROG | + DLM_LOCK_RES_MIGRATING)); spin_unlock(&res->spinlock); /* clear our bit from the master's refmap, ignore errors */ diff --git a/trunk/fs/ocfs2/dlm/dlmunlock.c b/trunk/fs/ocfs2/dlm/dlmunlock.c index fcf879ed6930..86ca085ef324 100644 --- a/trunk/fs/ocfs2/dlm/dlmunlock.c +++ b/trunk/fs/ocfs2/dlm/dlmunlock.c @@ -117,11 +117,11 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, else BUG_ON(res->owner == dlm->node_num); - spin_lock(&dlm->ast_lock); + spin_lock(&dlm->spinlock); /* We want to be sure that we're not freeing a lock * that still has AST's pending... */ in_use = !list_empty(&lock->ast_list); - spin_unlock(&dlm->ast_lock); + spin_unlock(&dlm->spinlock); if (in_use) { mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock " "while waiting for an ast!", res->lockname.len, diff --git a/trunk/fs/ocfs2/dlmglue.c b/trunk/fs/ocfs2/dlmglue.c index 7219a86d34cc..b0c4cadd4c45 100644 --- a/trunk/fs/ocfs2/dlmglue.c +++ b/trunk/fs/ocfs2/dlmglue.c @@ -320,14 +320,9 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb, struct ocfs2_lock_res *lockres); static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres, int convert); -#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \ - if ((_lockres)->l_type != OCFS2_LOCK_TYPE_DENTRY) \ - mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \ - _err, _func, _lockres->l_name); \ - else \ - mlog(ML_ERROR, "DLM error %d while calling %s on resource %.*s%08x\n", \ - _err, _func, OCFS2_DENTRY_LOCK_INO_START - 1, (_lockres)->l_name, \ - (unsigned int)ocfs2_get_dentry_lock_ino(_lockres)); \ +#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \ + mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \ + _err, _func, _lockres->l_name); \ } while (0) static int ocfs2_downconvert_thread(void *arg); static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb, @@ -2865,10 +2860,6 @@ static void ocfs2_unlock_ast(void *opaque, int error) case OCFS2_UNLOCK_CANCEL_CONVERT: mlog(0, "Cancel convert success for %s\n", lockres->l_name); lockres->l_action = OCFS2_AST_INVALID; - /* Downconvert thread may have requeued this lock, we - * need to wake it. */ - if (lockres->l_flags & OCFS2_LOCK_BLOCKED) - ocfs2_wake_downconvert_thread(ocfs2_get_lockres_osb(lockres)); break; case OCFS2_UNLOCK_DROP_LOCK: lockres->l_level = DLM_LOCK_IV; diff --git a/trunk/fs/ocfs2/journal.h b/trunk/fs/ocfs2/journal.h index 172850a9a12a..3c3532e1307c 100644 --- a/trunk/fs/ocfs2/journal.h +++ b/trunk/fs/ocfs2/journal.h @@ -513,10 +513,8 @@ static inline int ocfs2_jbd2_file_inode(handle_t *handle, struct inode *inode) static inline int ocfs2_begin_ordered_truncate(struct inode *inode, loff_t new_size) { - return jbd2_journal_begin_ordered_truncate( - OCFS2_SB(inode->i_sb)->journal->j_journal, - &OCFS2_I(inode)->ip_jinode, - new_size); + return jbd2_journal_begin_ordered_truncate(&OCFS2_I(inode)->ip_jinode, + new_size); } #endif /* OCFS2_JOURNAL_H */ diff --git a/trunk/fs/ocfs2/ocfs2.h b/trunk/fs/ocfs2/ocfs2.h index 946d3c34b90b..ad5c24a29edd 100644 --- a/trunk/fs/ocfs2/ocfs2.h +++ b/trunk/fs/ocfs2/ocfs2.h @@ -210,7 +210,6 @@ struct ocfs2_journal; struct ocfs2_slot_info; struct ocfs2_recovery_map; struct ocfs2_quota_recovery; -struct ocfs2_dentry_lock; struct ocfs2_super { struct task_struct *commit_task; @@ -326,11 +325,6 @@ struct ocfs2_super struct list_head blocked_lock_list; unsigned long blocked_lock_count; - /* List of dentry locks to release. Anyone can add locks to - * the list, ocfs2_wq processes the list */ - struct ocfs2_dentry_lock *dentry_lock_list; - struct work_struct dentry_lock_work; - wait_queue_head_t osb_mount_event; /* Truncate log info */ @@ -341,9 +335,6 @@ struct ocfs2_super struct ocfs2_node_map osb_recovering_orphan_dirs; unsigned int *osb_orphan_wipes; wait_queue_head_t osb_wipe_event; - - /* used to protect metaecc calculation check of xattr. */ - spinlock_t osb_xattr_lock; }; #define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info) diff --git a/trunk/fs/ocfs2/quota_global.c b/trunk/fs/ocfs2/quota_global.c index 1ed0f7c86869..f4efa89baee5 100644 --- a/trunk/fs/ocfs2/quota_global.c +++ b/trunk/fs/ocfs2/quota_global.c @@ -754,9 +754,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) if (dquot->dq_flags & mask) sync = 1; spin_unlock(&dq_data_lock); - /* This is a slight hack but we can't afford getting global quota - * lock if we already have a transaction started. */ - if (!sync || journal_current_handle()) { + if (!sync) { status = ocfs2_write_dquot(dquot); goto out; } diff --git a/trunk/fs/ocfs2/super.c b/trunk/fs/ocfs2/super.c index 7ac83a81ee55..43ed11345b59 100644 --- a/trunk/fs/ocfs2/super.c +++ b/trunk/fs/ocfs2/super.c @@ -1537,13 +1537,6 @@ static int ocfs2_get_sector(struct super_block *sb, unlock_buffer(*bh); ll_rw_block(READ, 1, bh); wait_on_buffer(*bh); - if (!buffer_uptodate(*bh)) { - mlog_errno(-EIO); - brelse(*bh); - *bh = NULL; - return -EIO; - } - return 0; } @@ -1754,7 +1747,6 @@ static int ocfs2_initialize_super(struct super_block *sb, INIT_LIST_HEAD(&osb->blocked_lock_list); osb->blocked_lock_count = 0; spin_lock_init(&osb->osb_lock); - spin_lock_init(&osb->osb_xattr_lock); ocfs2_init_inode_steal_slot(osb); atomic_set(&osb->alloc_stats.moves, 0); @@ -1895,9 +1887,6 @@ static int ocfs2_initialize_super(struct super_block *sb, INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery); journal->j_state = OCFS2_JOURNAL_FREE; - INIT_WORK(&osb->dentry_lock_work, ocfs2_drop_dl_inodes); - osb->dentry_lock_list = NULL; - /* get some pseudo constants for clustersize bits */ osb->s_clustersize_bits = le32_to_cpu(di->id2.i_super.s_clustersize_bits); diff --git a/trunk/fs/ocfs2/xattr.c b/trunk/fs/ocfs2/xattr.c index 4ddd788add67..e1d638af6ac3 100644 --- a/trunk/fs/ocfs2/xattr.c +++ b/trunk/fs/ocfs2/xattr.c @@ -82,14 +82,13 @@ struct ocfs2_xattr_set_ctxt { #define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root)) #define OCFS2_XATTR_INLINE_SIZE 80 -#define OCFS2_XATTR_HEADER_GAP 4 #define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \ - sizeof(struct ocfs2_xattr_header) \ - - OCFS2_XATTR_HEADER_GAP) + - sizeof(__u32)) #define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \ - sizeof(struct ocfs2_xattr_block) \ - sizeof(struct ocfs2_xattr_header) \ - - OCFS2_XATTR_HEADER_GAP) + - sizeof(__u32)) static struct ocfs2_xattr_def_value_root def_xv = { .xv.xr_list.l_count = cpu_to_le16(1), @@ -275,12 +274,10 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket, bucket->bu_blocks, bucket->bu_bhs, 0, NULL); if (!rc) { - spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb, bucket->bu_bhs, bucket->bu_blocks, &bucket_xh(bucket)->xh_check); - spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); if (rc) mlog_errno(rc); } @@ -313,11 +310,9 @@ static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle, { int i; - spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb, bucket->bu_bhs, bucket->bu_blocks, &bucket_xh(bucket)->xh_check); - spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); for (i = 0; i < bucket->bu_blocks; i++) ocfs2_journal_dirty(handle, bucket->bu_bhs[i]); @@ -1512,7 +1507,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode, last += 1; } - free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP; + free = min_offs - ((void *)last - xs->base) - sizeof(__u32); if (free < 0) return -EIO; @@ -2195,7 +2190,7 @@ static int ocfs2_xattr_can_be_in_inode(struct inode *inode, last += 1; } - free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP; + free = min_offs - ((void *)last - xs->base) - sizeof(__u32); if (free < 0) return 0; @@ -2597,9 +2592,8 @@ static int __ocfs2_xattr_set_handle(struct inode *inode, if (!ret) { /* Update inode ctime. */ - ret = ocfs2_journal_access_di(ctxt->handle, inode, - xis->inode_bh, - OCFS2_JOURNAL_ACCESS_WRITE); + ret = ocfs2_journal_access(ctxt->handle, inode, xis->inode_bh, + OCFS2_JOURNAL_ACCESS_WRITE); if (ret) { mlog_errno(ret); goto out; @@ -4735,6 +4729,13 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode, vb.vb_xv = (struct ocfs2_xattr_value_root *) (vb.vb_bh->b_data + offset % blocksize); + ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket, + OCFS2_JOURNAL_ACCESS_WRITE); + if (ret) { + mlog_errno(ret); + goto out; + } + /* * From here on out we have to dirty the bucket. The generic * value calls only modify one of the bucket's bhs, but we need @@ -4747,18 +4748,12 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode, ret = ocfs2_xattr_value_truncate(inode, &vb, len, ctxt); if (ret) { mlog_errno(ret); - goto out; - } - - ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket, - OCFS2_JOURNAL_ACCESS_WRITE); - if (ret) { - mlog_errno(ret); - goto out; + goto out_dirty; } xe->xe_value_size = cpu_to_le64(len); +out_dirty: ocfs2_xattr_bucket_journal_dirty(ctxt->handle, bucket); out: @@ -5066,8 +5061,8 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, xh_free_start = le16_to_cpu(xh->xh_free_start); header_size = sizeof(struct ocfs2_xattr_header) + count * sizeof(struct ocfs2_xattr_entry); - max_free = OCFS2_XATTR_BUCKET_SIZE - header_size - - le16_to_cpu(xh->xh_name_value_len) - OCFS2_XATTR_HEADER_GAP; + max_free = OCFS2_XATTR_BUCKET_SIZE - + le16_to_cpu(xh->xh_name_value_len) - header_size; mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size " "of %u which exceed block size\n", @@ -5100,7 +5095,7 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, need = 0; } - free = xh_free_start - header_size - OCFS2_XATTR_HEADER_GAP; + free = xh_free_start - header_size; /* * We need to make sure the new name/value pair * can exist in the same block. @@ -5133,8 +5128,7 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, } xh_free_start = le16_to_cpu(xh->xh_free_start); - free = xh_free_start - header_size - - OCFS2_XATTR_HEADER_GAP; + free = xh_free_start - header_size; if (xh_free_start % blocksize < need) free -= xh_free_start % blocksize; diff --git a/trunk/fs/proc/inode.c b/trunk/fs/proc/inode.c index d8bb5c671f42..3e76bb9b3ad6 100644 --- a/trunk/fs/proc/inode.c +++ b/trunk/fs/proc/inode.c @@ -485,10 +485,8 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, } } unlock_new_inode(inode); - } else { + } else module_put(de->owner); - de_put(de); - } return inode; out_ino: diff --git a/trunk/fs/proc/page.c b/trunk/fs/proc/page.c index 2d1345112a42..767d95a6d1b1 100644 --- a/trunk/fs/proc/page.c +++ b/trunk/fs/proc/page.c @@ -107,7 +107,7 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf, else kflags = ppage->flags; - uflags = kpf_copy_bit(kflags, KPF_LOCKED, PG_locked) | + uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) | kpf_copy_bit(kflags, KPF_ERROR, PG_error) | kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) | kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) | diff --git a/trunk/fs/seq_file.c b/trunk/fs/seq_file.c index a1a4cfe19210..b569ff1c4dc8 100644 --- a/trunk/fs/seq_file.c +++ b/trunk/fs/seq_file.c @@ -48,78 +48,12 @@ int seq_open(struct file *file, const struct seq_operations *op) */ file->f_version = 0; - /* - * seq_files support lseek() and pread(). They do not implement - * write() at all, but we clear FMODE_PWRITE here for historical - * reasons. - * - * If a client of seq_files a) implements file.write() and b) wishes to - * support pwrite() then that client will need to implement its own - * file.open() which calls seq_open() and then sets FMODE_PWRITE. - */ - file->f_mode &= ~FMODE_PWRITE; + /* SEQ files support lseek, but not pread/pwrite */ + file->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); return 0; } EXPORT_SYMBOL(seq_open); -static int traverse(struct seq_file *m, loff_t offset) -{ - loff_t pos = 0, index; - int error = 0; - void *p; - - m->version = 0; - index = 0; - m->count = m->from = 0; - if (!offset) { - m->index = index; - return 0; - } - if (!m->buf) { - m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); - if (!m->buf) - return -ENOMEM; - } - p = m->op->start(m, &index); - while (p) { - error = PTR_ERR(p); - if (IS_ERR(p)) - break; - error = m->op->show(m, p); - if (error < 0) - break; - if (unlikely(error)) { - error = 0; - m->count = 0; - } - if (m->count == m->size) - goto Eoverflow; - if (pos + m->count > offset) { - m->from = offset - pos; - m->count -= m->from; - m->index = index; - break; - } - pos += m->count; - m->count = 0; - if (pos == offset) { - index++; - m->index = index; - break; - } - p = m->op->next(m, p, &index); - } - m->op->stop(m, p); - m->index = index; - return error; - -Eoverflow: - m->op->stop(m, p); - kfree(m->buf); - m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); - return !m->buf ? -ENOMEM : -EAGAIN; -} - /** * seq_read - ->read() method for sequential files. * @file: the file to read from @@ -139,22 +73,6 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) int err = 0; mutex_lock(&m->lock); - - /* Don't assume *ppos is where we left it */ - if (unlikely(*ppos != m->read_pos)) { - m->read_pos = *ppos; - while ((err = traverse(m, *ppos)) == -EAGAIN) - ; - if (err) { - /* With prejudice... */ - m->read_pos = 0; - m->version = 0; - m->index = 0; - m->count = 0; - goto Done; - } - } - /* * seq_file->op->..m_start/m_stop/m_next may do special actions * or optimisations based on the file->f_version, so we want to @@ -254,10 +172,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) Done: if (!copied) copied = err; - else { + else *ppos += copied; - m->read_pos += copied; - } file->f_version = m->version; mutex_unlock(&m->lock); return copied; @@ -270,6 +186,63 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) } EXPORT_SYMBOL(seq_read); +static int traverse(struct seq_file *m, loff_t offset) +{ + loff_t pos = 0, index; + int error = 0; + void *p; + + m->version = 0; + index = 0; + m->count = m->from = 0; + if (!offset) { + m->index = index; + return 0; + } + if (!m->buf) { + m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); + if (!m->buf) + return -ENOMEM; + } + p = m->op->start(m, &index); + while (p) { + error = PTR_ERR(p); + if (IS_ERR(p)) + break; + error = m->op->show(m, p); + if (error < 0) + break; + if (unlikely(error)) { + error = 0; + m->count = 0; + } + if (m->count == m->size) + goto Eoverflow; + if (pos + m->count > offset) { + m->from = offset - pos; + m->count -= m->from; + m->index = index; + break; + } + pos += m->count; + m->count = 0; + if (pos == offset) { + index++; + m->index = index; + break; + } + p = m->op->next(m, p, &index); + } + m->op->stop(m, p); + return error; + +Eoverflow: + m->op->stop(m, p); + kfree(m->buf); + m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); + return !m->buf ? -ENOMEM : -EAGAIN; +} + /** * seq_lseek - ->llseek() method for sequential files. * @file: the file in question @@ -292,18 +265,16 @@ loff_t seq_lseek(struct file *file, loff_t offset, int origin) if (offset < 0) break; retval = offset; - if (offset != m->read_pos) { + if (offset != file->f_pos) { while ((retval=traverse(m, offset)) == -EAGAIN) ; if (retval) { /* with extreme prejudice... */ file->f_pos = 0; - m->read_pos = 0; m->version = 0; m->index = 0; m->count = 0; } else { - m->read_pos = offset; retval = file->f_pos = offset; } } diff --git a/trunk/fs/super.c b/trunk/fs/super.c index 8349ed6b1412..645e5403f2a0 100644 --- a/trunk/fs/super.c +++ b/trunk/fs/super.c @@ -82,22 +82,7 @@ static struct super_block *alloc_super(struct file_system_type *type) * lock ordering than usbfs: */ lockdep_set_class(&s->s_lock, &type->s_lock_key); - /* - * sget() can have s_umount recursion. - * - * When it cannot find a suitable sb, it allocates a new - * one (this one), and tries again to find a suitable old - * one. - * - * In case that succeeds, it will acquire the s_umount - * lock of the old one. Since these are clearly distrinct - * locks, and this object isn't exposed yet, there's no - * risk of deadlocks. - * - * Annotate this by putting this lock in a different - * subclass. - */ - down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); + down_write(&s->s_umount); s->s_count = S_BIAS; atomic_set(&s->s_active, 1); mutex_init(&s->s_vfs_rename_mutex); @@ -316,7 +301,7 @@ void generic_shutdown_super(struct super_block *sb) /* * wait for asynchronous fs operations to finish before going further */ - async_synchronize_full_domain(&sb->s_async_list); + async_synchronize_full_special(&sb->s_async_list); /* bad name - it should be evict_inodes() */ invalidate_inodes(sb); @@ -485,7 +470,7 @@ void sync_filesystems(int wait) sb->s_count++; spin_unlock(&sb_lock); down_read(&sb->s_umount); - async_synchronize_full_domain(&sb->s_async_list); + async_synchronize_full_special(&sb->s_async_list); if (sb->s_root && (wait || sb->s_dirt)) sb->s_op->sync_fs(sb, wait); up_read(&sb->s_umount); diff --git a/trunk/fs/timerfd.c b/trunk/fs/timerfd.c index b042bd7034b1..6a123b8ff3f5 100644 --- a/trunk/fs/timerfd.c +++ b/trunk/fs/timerfd.c @@ -186,9 +186,10 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC); BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK); - if ((flags & ~TFD_CREATE_FLAGS) || - (clockid != CLOCK_MONOTONIC && - clockid != CLOCK_REALTIME)) + if (flags & ~(TFD_CLOEXEC | TFD_NONBLOCK)) + return -EINVAL; + if (clockid != CLOCK_MONOTONIC && + clockid != CLOCK_REALTIME) return -EINVAL; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); @@ -200,7 +201,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, - flags & TFD_SHARED_FCNTL_FLAGS); + flags & (O_CLOEXEC | O_NONBLOCK)); if (ufd < 0) kfree(ctx); @@ -218,8 +219,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) return -EFAULT; - if ((flags & ~TFD_SETTIME_FLAGS) || - !timespec_valid(&ktmr.it_value) || + if (!timespec_valid(&ktmr.it_value) || !timespec_valid(&ktmr.it_interval)) return -EINVAL; diff --git a/trunk/fs/ubifs/budget.c b/trunk/fs/ubifs/budget.c index f393620890ee..175f9c590b77 100644 --- a/trunk/fs/ubifs/budget.c +++ b/trunk/fs/ubifs/budget.c @@ -689,7 +689,7 @@ long long ubifs_reported_space(const struct ubifs_info *c, long long free) } /** - * ubifs_get_free_space_nolock - return amount of free space. + * ubifs_get_free_space - return amount of free space. * @c: UBIFS file-system description object * * This function calculates amount of free space to report to user-space. @@ -704,14 +704,16 @@ long long ubifs_reported_space(const struct ubifs_info *c, long long free) * traditional file-systems, because they have way less overhead than UBIFS. * So, to keep users happy, UBIFS tries to take the overhead into account. */ -long long ubifs_get_free_space_nolock(struct ubifs_info *c) +long long ubifs_get_free_space(struct ubifs_info *c) { - int rsvd_idx_lebs, lebs; + int min_idx_lebs, rsvd_idx_lebs, lebs; long long available, outstanding, free; - ubifs_assert(c->min_idx_lebs == ubifs_calc_min_idx_lebs(c)); + spin_lock(&c->space_lock); + min_idx_lebs = c->min_idx_lebs; + ubifs_assert(min_idx_lebs == ubifs_calc_min_idx_lebs(c)); outstanding = c->budg_data_growth + c->budg_dd_growth; - available = ubifs_calc_available(c, c->min_idx_lebs); + available = ubifs_calc_available(c, min_idx_lebs); /* * When reporting free space to user-space, UBIFS guarantees that it is @@ -724,14 +726,15 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c) * Note, the calculations below are similar to what we have in * 'do_budget_space()', so refer there for comments. */ - if (c->min_idx_lebs > c->lst.idx_lebs) - rsvd_idx_lebs = c->min_idx_lebs - c->lst.idx_lebs; + if (min_idx_lebs > c->lst.idx_lebs) + rsvd_idx_lebs = min_idx_lebs - c->lst.idx_lebs; else rsvd_idx_lebs = 0; lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt - c->lst.taken_empty_lebs; lebs -= rsvd_idx_lebs; available += lebs * (c->dark_wm - c->leb_overhead); + spin_unlock(&c->space_lock); if (available > outstanding) free = ubifs_reported_space(c, available - outstanding); @@ -739,21 +742,3 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c) free = 0; return free; } - -/** - * ubifs_get_free_space - return amount of free space. - * @c: UBIFS file-system description object - * - * This function calculates and retuns amount of free space to report to - * user-space. - */ -long long ubifs_get_free_space(struct ubifs_info *c) -{ - long long free; - - spin_lock(&c->space_lock); - free = ubifs_get_free_space_nolock(c); - spin_unlock(&c->space_lock); - - return free; -} diff --git a/trunk/fs/ubifs/debug.c b/trunk/fs/ubifs/debug.c index e975bd82f38b..792c5a16c182 100644 --- a/trunk/fs/ubifs/debug.c +++ b/trunk/fs/ubifs/debug.c @@ -620,11 +620,9 @@ void dbg_dump_budg(struct ubifs_info *c) c->dark_wm, c->dead_wm, c->max_idx_node_sz); printk(KERN_DEBUG "\tgc_lnum %d, ihead_lnum %d\n", c->gc_lnum, c->ihead_lnum); - /* If we are in R/O mode, journal heads do not exist */ - if (c->jheads) - for (i = 0; i < c->jhead_cnt; i++) - printk(KERN_DEBUG "\tjhead %d\t LEB %d\n", - c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum); + for (i = 0; i < c->jhead_cnt; i++) + printk(KERN_DEBUG "\tjhead %d\t LEB %d\n", + c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum); for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) { bud = rb_entry(rb, struct ubifs_bud, rb); printk(KERN_DEBUG "\tbud LEB %d\n", bud->lnum); @@ -639,7 +637,10 @@ void dbg_dump_budg(struct ubifs_info *c) /* Print budgeting predictions */ available = ubifs_calc_available(c, c->min_idx_lebs); outstanding = c->budg_data_growth + c->budg_dd_growth; - free = ubifs_get_free_space_nolock(c); + if (available > outstanding) + free = ubifs_reported_space(c, available - outstanding); + else + free = 0; printk(KERN_DEBUG "Budgeting predictions:\n"); printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n", available, outstanding, free); @@ -859,65 +860,6 @@ void dbg_dump_index(struct ubifs_info *c) dbg_walk_index(c, NULL, dump_znode, NULL); } -/** - * dbg_save_space_info - save information about flash space. - * @c: UBIFS file-system description object - * - * This function saves information about UBIFS free space, dirty space, etc, in - * order to check it later. - */ -void dbg_save_space_info(struct ubifs_info *c) -{ - struct ubifs_debug_info *d = c->dbg; - - ubifs_get_lp_stats(c, &d->saved_lst); - - spin_lock(&c->space_lock); - d->saved_free = ubifs_get_free_space_nolock(c); - spin_unlock(&c->space_lock); -} - -/** - * dbg_check_space_info - check flash space information. - * @c: UBIFS file-system description object - * - * This function compares current flash space information with the information - * which was saved when the 'dbg_save_space_info()' function was called. - * Returns zero if the information has not changed, and %-EINVAL it it has - * changed. - */ -int dbg_check_space_info(struct ubifs_info *c) -{ - struct ubifs_debug_info *d = c->dbg; - struct ubifs_lp_stats lst; - long long avail, free; - - spin_lock(&c->space_lock); - avail = ubifs_calc_available(c, c->min_idx_lebs); - spin_unlock(&c->space_lock); - free = ubifs_get_free_space(c); - - if (free != d->saved_free) { - ubifs_err("free space changed from %lld to %lld", - d->saved_free, free); - goto out; - } - - return 0; - -out: - ubifs_msg("saved lprops statistics dump"); - dbg_dump_lstats(&d->saved_lst); - ubifs_get_lp_stats(c, &lst); - ubifs_msg("current lprops statistics dump"); - dbg_dump_lstats(&d->saved_lst); - spin_lock(&c->space_lock); - dbg_dump_budg(c); - spin_unlock(&c->space_lock); - dump_stack(); - return -EINVAL; -} - /** * dbg_check_synced_i_size - check synchronized inode size. * @inode: inode to check @@ -1407,7 +1349,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra) * @c: UBIFS file-system description object * @leaf_cb: called for each leaf node * @znode_cb: called for each indexing node - * @priv: private data which is passed to callbacks + * @priv: private date which is passed to callbacks * * This function walks the UBIFS index and calls the @leaf_cb for each leaf * node and @znode_cb for each indexing node. Returns zero in case of success @@ -2467,7 +2409,7 @@ void ubifs_debugging_exit(struct ubifs_info *c) * Root directory for UBIFS stuff in debugfs. Contains sub-directories which * contain the stuff specific to particular file-system mounts. */ -static struct dentry *dfs_rootdir; +static struct dentry *debugfs_rootdir; /** * dbg_debugfs_init - initialize debugfs file-system. @@ -2479,9 +2421,9 @@ static struct dentry *dfs_rootdir; */ int dbg_debugfs_init(void) { - dfs_rootdir = debugfs_create_dir("ubifs", NULL); - if (IS_ERR(dfs_rootdir)) { - int err = PTR_ERR(dfs_rootdir); + debugfs_rootdir = debugfs_create_dir("ubifs", NULL); + if (IS_ERR(debugfs_rootdir)) { + int err = PTR_ERR(debugfs_rootdir); ubifs_err("cannot create \"ubifs\" debugfs directory, " "error %d\n", err); return err; @@ -2495,7 +2437,7 @@ int dbg_debugfs_init(void) */ void dbg_debugfs_exit(void) { - debugfs_remove(dfs_rootdir); + debugfs_remove(debugfs_rootdir); } static int open_debugfs_file(struct inode *inode, struct file *file) @@ -2510,13 +2452,13 @@ static ssize_t write_debugfs_file(struct file *file, const char __user *buf, struct ubifs_info *c = file->private_data; struct ubifs_debug_info *d = c->dbg; - if (file->f_path.dentry == d->dfs_dump_lprops) + if (file->f_path.dentry == d->dump_lprops) dbg_dump_lprops(c); - else if (file->f_path.dentry == d->dfs_dump_budg) { + else if (file->f_path.dentry == d->dump_budg) { spin_lock(&c->space_lock); dbg_dump_budg(c); spin_unlock(&c->space_lock); - } else if (file->f_path.dentry == d->dfs_dump_tnc) { + } else if (file->f_path.dentry == d->dump_tnc) { mutex_lock(&c->tnc_mutex); dbg_dump_tnc(c); mutex_unlock(&c->tnc_mutex); @@ -2527,7 +2469,7 @@ static ssize_t write_debugfs_file(struct file *file, const char __user *buf, return count; } -static const struct file_operations dfs_fops = { +static const struct file_operations debugfs_fops = { .open = open_debugfs_file, .write = write_debugfs_file, .owner = THIS_MODULE, @@ -2552,32 +2494,36 @@ int dbg_debugfs_init_fs(struct ubifs_info *c) struct dentry *dent; struct ubifs_debug_info *d = c->dbg; - sprintf(d->dfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); - d->dfs_dir = debugfs_create_dir(d->dfs_dir_name, dfs_rootdir); - if (IS_ERR(d->dfs_dir)) { - err = PTR_ERR(d->dfs_dir); + sprintf(d->debugfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); + d->debugfs_dir = debugfs_create_dir(d->debugfs_dir_name, + debugfs_rootdir); + if (IS_ERR(d->debugfs_dir)) { + err = PTR_ERR(d->debugfs_dir); ubifs_err("cannot create \"%s\" debugfs directory, error %d\n", - d->dfs_dir_name, err); + d->debugfs_dir_name, err); goto out; } fname = "dump_lprops"; - dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops); + dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c, + &debugfs_fops); if (IS_ERR(dent)) goto out_remove; - d->dfs_dump_lprops = dent; + d->dump_lprops = dent; fname = "dump_budg"; - dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops); + dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c, + &debugfs_fops); if (IS_ERR(dent)) goto out_remove; - d->dfs_dump_budg = dent; + d->dump_budg = dent; fname = "dump_tnc"; - dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops); + dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c, + &debugfs_fops); if (IS_ERR(dent)) goto out_remove; - d->dfs_dump_tnc = dent; + d->dump_tnc = dent; return 0; @@ -2585,7 +2531,7 @@ int dbg_debugfs_init_fs(struct ubifs_info *c) err = PTR_ERR(dent); ubifs_err("cannot create \"%s\" debugfs directory, error %d\n", fname, err); - debugfs_remove_recursive(d->dfs_dir); + debugfs_remove_recursive(d->debugfs_dir); out: return err; } @@ -2596,7 +2542,7 @@ int dbg_debugfs_init_fs(struct ubifs_info *c) */ void dbg_debugfs_exit_fs(struct ubifs_info *c) { - debugfs_remove_recursive(c->dbg->dfs_dir); + debugfs_remove_recursive(c->dbg->debugfs_dir); } #endif /* CONFIG_UBIFS_FS_DEBUG */ diff --git a/trunk/fs/ubifs/debug.h b/trunk/fs/ubifs/debug.h index c1cd73b2e06e..9820d6999f7e 100644 --- a/trunk/fs/ubifs/debug.h +++ b/trunk/fs/ubifs/debug.h @@ -41,17 +41,15 @@ * @chk_lpt_wastage: used by LPT tree size checker * @chk_lpt_lebs: used by LPT tree size checker * @new_nhead_offs: used by LPT tree size checker - * @new_ihead_lnum: used by debugging to check @c->ihead_lnum - * @new_ihead_offs: used by debugging to check @c->ihead_offs + * @new_ihead_lnum: used by debugging to check ihead_lnum + * @new_ihead_offs: used by debugging to check ihead_offs * - * @saved_lst: saved lprops statistics (used by 'dbg_save_space_info()') - * @saved_free: saved free space (used by 'dbg_save_space_info()') - * - * dfs_dir_name: name of debugfs directory containing this file-system's files - * dfs_dir: direntry object of the file-system debugfs directory - * dfs_dump_lprops: "dump lprops" debugfs knob - * dfs_dump_budg: "dump budgeting information" debugfs knob - * dfs_dump_tnc: "dump TNC" debugfs knob + * debugfs_dir_name: name of debugfs directory containing this file-system's + * files + * debugfs_dir: direntry object of the file-system debugfs directory + * dump_lprops: "dump lprops" debugfs knob + * dump_budg: "dump budgeting information" debugfs knob + * dump_tnc: "dump TNC" debugfs knob */ struct ubifs_debug_info { void *buf; @@ -71,14 +69,11 @@ struct ubifs_debug_info { int new_ihead_lnum; int new_ihead_offs; - struct ubifs_lp_stats saved_lst; - long long saved_free; - - char dfs_dir_name[100]; - struct dentry *dfs_dir; - struct dentry *dfs_dump_lprops; - struct dentry *dfs_dump_budg; - struct dentry *dfs_dump_tnc; + char debugfs_dir_name[100]; + struct dentry *debugfs_dir; + struct dentry *dump_lprops; + struct dentry *dump_budg; + struct dentry *dump_tnc; }; #define ubifs_assert(expr) do { \ @@ -302,8 +297,7 @@ int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, dbg_znode_callback znode_cb, void *priv); /* Checking functions */ -void dbg_save_space_info(struct ubifs_info *c); -int dbg_check_space_info(struct ubifs_info *c); + int dbg_check_lprops(struct ubifs_info *c); int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot); int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot); @@ -445,8 +439,6 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c); #define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0 #define dbg_old_index_check_init(c, zroot) 0 -#define dbg_save_space_info(c) ({}) -#define dbg_check_space_info(c) 0 #define dbg_check_old_index(c, zroot) 0 #define dbg_check_cats(c) 0 #define dbg_check_ltab(c) 0 diff --git a/trunk/fs/ubifs/dir.c b/trunk/fs/ubifs/dir.c index f55d523c52bb..f448ab1f9c38 100644 --- a/trunk/fs/ubifs/dir.c +++ b/trunk/fs/ubifs/dir.c @@ -482,29 +482,30 @@ static int ubifs_dir_release(struct inode *dir, struct file *file) } /** - * lock_2_inodes - a wrapper for locking two UBIFS inodes. + * lock_2_inodes - lock two UBIFS inodes. * @inode1: first inode * @inode2: second inode - * - * We do not implement any tricks to guarantee strict lock ordering, because - * VFS has already done it for us on the @i_mutex. So this is just a simple - * wrapper function. */ static void lock_2_inodes(struct inode *inode1, struct inode *inode2) { - mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1); - mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2); + if (inode1->i_ino < inode2->i_ino) { + mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_2); + mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_3); + } else { + mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2); + mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_3); + } } /** - * unlock_2_inodes - a wrapper for unlocking two UBIFS inodes. + * unlock_2_inodes - unlock two UBIFS inodes inodes. * @inode1: first inode * @inode2: second inode */ static void unlock_2_inodes(struct inode *inode1, struct inode *inode2) { - mutex_unlock(&ubifs_inode(inode2)->ui_mutex); mutex_unlock(&ubifs_inode(inode1)->ui_mutex); + mutex_unlock(&ubifs_inode(inode2)->ui_mutex); } static int ubifs_link(struct dentry *old_dentry, struct inode *dir, @@ -526,8 +527,6 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, dbg_gen("dent '%.*s' to ino %lu (nlink %d) in dir ino %lu", dentry->d_name.len, dentry->d_name.name, inode->i_ino, inode->i_nlink, dir->i_ino); - ubifs_assert(mutex_is_locked(&dir->i_mutex)); - ubifs_assert(mutex_is_locked(&inode->i_mutex)); err = dbg_check_synced_i_size(inode); if (err) return err; @@ -581,8 +580,6 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry) dbg_gen("dent '%.*s' from ino %lu (nlink %d) in dir ino %lu", dentry->d_name.len, dentry->d_name.name, inode->i_ino, inode->i_nlink, dir->i_ino); - ubifs_assert(mutex_is_locked(&dir->i_mutex)); - ubifs_assert(mutex_is_locked(&inode->i_mutex)); err = dbg_check_synced_i_size(inode); if (err) return err; @@ -670,8 +667,7 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry) dbg_gen("directory '%.*s', ino %lu in dir ino %lu", dentry->d_name.len, dentry->d_name.name, inode->i_ino, dir->i_ino); - ubifs_assert(mutex_is_locked(&dir->i_mutex)); - ubifs_assert(mutex_is_locked(&inode->i_mutex)); + err = check_dir_empty(c, dentry->d_inode); if (err) return err; @@ -926,30 +922,59 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry, } /** - * lock_3_inodes - a wrapper for locking three UBIFS inodes. + * lock_3_inodes - lock three UBIFS inodes for rename. * @inode1: first inode * @inode2: second inode * @inode3: third inode * - * This function is used for 'ubifs_rename()' and @inode1 may be the same as - * @inode2 whereas @inode3 may be %NULL. - * - * We do not implement any tricks to guarantee strict lock ordering, because - * VFS has already done it for us on the @i_mutex. So this is just a simple - * wrapper function. + * For 'ubifs_rename()', @inode1 may be the same as @inode2 whereas @inode3 may + * be null. */ static void lock_3_inodes(struct inode *inode1, struct inode *inode2, struct inode *inode3) { - mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1); - if (inode2 != inode1) - mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2); - if (inode3) - mutex_lock_nested(&ubifs_inode(inode3)->ui_mutex, WB_MUTEX_3); + struct inode *i1, *i2, *i3; + + if (!inode3) { + if (inode1 != inode2) { + lock_2_inodes(inode1, inode2); + return; + } + mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1); + return; + } + + if (inode1 == inode2) { + lock_2_inodes(inode1, inode3); + return; + } + + /* 3 different inodes */ + if (inode1 < inode2) { + i3 = inode2; + if (inode1 < inode3) { + i1 = inode1; + i2 = inode3; + } else { + i1 = inode3; + i2 = inode1; + } + } else { + i3 = inode1; + if (inode2 < inode3) { + i1 = inode2; + i2 = inode3; + } else { + i1 = inode3; + i2 = inode2; + } + } + mutex_lock_nested(&ubifs_inode(i1)->ui_mutex, WB_MUTEX_1); + lock_2_inodes(i2, i3); } /** - * unlock_3_inodes - a wrapper for unlocking three UBIFS inodes for rename. + * unlock_3_inodes - unlock three UBIFS inodes for rename. * @inode1: first inode * @inode2: second inode * @inode3: third inode @@ -957,11 +982,11 @@ static void lock_3_inodes(struct inode *inode1, struct inode *inode2, static void unlock_3_inodes(struct inode *inode1, struct inode *inode2, struct inode *inode3) { - if (inode3) - mutex_unlock(&ubifs_inode(inode3)->ui_mutex); + mutex_unlock(&ubifs_inode(inode1)->ui_mutex); if (inode1 != inode2) mutex_unlock(&ubifs_inode(inode2)->ui_mutex); - mutex_unlock(&ubifs_inode(inode1)->ui_mutex); + if (inode3) + mutex_unlock(&ubifs_inode(inode3)->ui_mutex); } static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, @@ -995,11 +1020,6 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, "dir ino %lu", old_dentry->d_name.len, old_dentry->d_name.name, old_inode->i_ino, old_dir->i_ino, new_dentry->d_name.len, new_dentry->d_name.name, new_dir->i_ino); - ubifs_assert(mutex_is_locked(&old_dir->i_mutex)); - ubifs_assert(mutex_is_locked(&new_dir->i_mutex)); - if (unlink) - ubifs_assert(mutex_is_locked(&new_inode->i_mutex)); - if (unlink && is_dir) { err = check_dir_empty(c, new_inode); @@ -1179,7 +1199,7 @@ int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry, return 0; } -const struct inode_operations ubifs_dir_inode_operations = { +struct inode_operations ubifs_dir_inode_operations = { .lookup = ubifs_lookup, .create = ubifs_create, .link = ubifs_link, @@ -1199,7 +1219,7 @@ const struct inode_operations ubifs_dir_inode_operations = { #endif }; -const struct file_operations ubifs_dir_operations = { +struct file_operations ubifs_dir_operations = { .llseek = ubifs_dir_llseek, .release = ubifs_dir_release, .read = generic_read_dir, diff --git a/trunk/fs/ubifs/file.c b/trunk/fs/ubifs/file.c index 93b6de51f261..bf37374567fa 100644 --- a/trunk/fs/ubifs/file.c +++ b/trunk/fs/ubifs/file.c @@ -432,6 +432,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, int uninitialized_var(err), appending = !!(pos + len > inode->i_size); struct page *page; + ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size); if (unlikely(c->ro_media)) @@ -1540,7 +1541,7 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -const struct address_space_operations ubifs_file_address_operations = { +struct address_space_operations ubifs_file_address_operations = { .readpage = ubifs_readpage, .writepage = ubifs_writepage, .write_begin = ubifs_write_begin, @@ -1550,7 +1551,7 @@ const struct address_space_operations ubifs_file_address_operations = { .releasepage = ubifs_releasepage, }; -const struct inode_operations ubifs_file_inode_operations = { +struct inode_operations ubifs_file_inode_operations = { .setattr = ubifs_setattr, .getattr = ubifs_getattr, #ifdef CONFIG_UBIFS_FS_XATTR @@ -1561,14 +1562,14 @@ const struct inode_operations ubifs_file_inode_operations = { #endif }; -const struct inode_operations ubifs_symlink_inode_operations = { +struct inode_operations ubifs_symlink_inode_operations = { .readlink = generic_readlink, .follow_link = ubifs_follow_link, .setattr = ubifs_setattr, .getattr = ubifs_getattr, }; -const struct file_operations ubifs_file_operations = { +struct file_operations ubifs_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, .write = do_sync_write, diff --git a/trunk/fs/ubifs/gc.c b/trunk/fs/ubifs/gc.c index a711d33b3d3e..9832f9abe28e 100644 --- a/trunk/fs/ubifs/gc.c +++ b/trunk/fs/ubifs/gc.c @@ -31,26 +31,6 @@ * to be reused. Garbage collection will cause the number of dirty index nodes * to grow, however sufficient space is reserved for the index to ensure the * commit will never run out of space. - * - * Notes about dead watermark. At current UBIFS implementation we assume that - * LEBs which have less than @c->dead_wm bytes of free + dirty space are full - * and not worth garbage-collecting. The dead watermark is one min. I/O unit - * size, or min. UBIFS node size, depending on what is greater. Indeed, UBIFS - * Garbage Collector has to synchronize the GC head's write buffer before - * returning, so this is about wasting one min. I/O unit. However, UBIFS GC can - * actually reclaim even very small pieces of dirty space by garbage collecting - * enough dirty LEBs, but we do not bother doing this at this implementation. - * - * Notes about dark watermark. The results of GC work depends on how big are - * the UBIFS nodes GC deals with. Large nodes make GC waste more space. Indeed, - * if GC move data from LEB A to LEB B and nodes in LEB A are large, GC would - * have to waste large pieces of free space at the end of LEB B, because nodes - * from LEB A would not fit. And the worst situation is when all nodes are of - * maximum size. So dark watermark is the amount of free + dirty space in LEB - * which are guaranteed to be reclaimable. If LEB has less space, the GC migh - * be unable to reclaim it. So, LEBs with free + dirty greater than dark - * watermark are "good" LEBs from GC's point of few. The other LEBs are not so - * good, and GC takes extra care when moving them. */ #include @@ -401,7 +381,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp) /* * Don't release the LEB until after the next commit, because - * it may contain data which is needed for recovery. So + * it may contain date which is needed for recovery. So * although we freed this LEB, it will become usable only after * the commit. */ @@ -830,9 +810,8 @@ int ubifs_gc_end_commit(struct ubifs_info *c) * ubifs_destroy_idx_gc - destroy idx_gc list. * @c: UBIFS file-system description object * - * This function destroys the @c->idx_gc list. It is called when unmounting - * so locks are not needed. Returns zero in case of success and a negative - * error code in case of failure. + * This function destroys the idx_gc list. It is called when unmounting or + * remounting read-only so locks are not needed. */ void ubifs_destroy_idx_gc(struct ubifs_info *c) { @@ -845,6 +824,7 @@ void ubifs_destroy_idx_gc(struct ubifs_info *c) list_del(&idx_gc->list); kfree(idx_gc); } + } /** diff --git a/trunk/fs/ubifs/io.c b/trunk/fs/ubifs/io.c index e8e632a1dcdf..01682713af69 100644 --- a/trunk/fs/ubifs/io.c +++ b/trunk/fs/ubifs/io.c @@ -29,7 +29,7 @@ * would have been wasted for padding to the nearest minimal I/O unit boundary. * Instead, data first goes to the write-buffer and is flushed when the * buffer is full or when it is not used for some time (by timer). This is - * similar to the mechanism is used by JFFS2. + * similarto the mechanism is used by JFFS2. * * Write-buffers are defined by 'struct ubifs_wbuf' objects and protected by * mutexes defined inside these objects. Since sometimes upper-level code @@ -75,7 +75,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err) * @lnum: logical eraseblock number * @offs: offset within the logical eraseblock * @quiet: print no messages - * @must_chk_crc: indicates whether to always check the CRC + * @chk_crc: indicates whether to always check the CRC * * This function checks node magic number and CRC checksum. This function also * validates node length to prevent UBIFS from becoming crazy when an attacker @@ -83,17 +83,11 @@ void ubifs_ro_mode(struct ubifs_info *c, int err) * node length in the common header could cause UBIFS to read memory outside of * allocated buffer when checking the CRC checksum. * - * This function may skip data nodes CRC checking if @c->no_chk_data_crc is - * true, which is controlled by corresponding UBIFS mount option. However, if - * @must_chk_crc is true, then @c->no_chk_data_crc is ignored and CRC is - * checked. Similarly, if @c->always_chk_crc is true, @c->no_chk_data_crc is - * ignored and CRC is checked. - * - * This function returns zero in case of success and %-EUCLEAN in case of bad - * CRC or magic. + * This function returns zero in case of success %-EUCLEAN in case of bad CRC + * or magic. */ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, - int offs, int quiet, int must_chk_crc) + int offs, int quiet, int chk_crc) { int err = -EINVAL, type, node_len; uint32_t crc, node_crc, magic; @@ -129,9 +123,9 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, node_len > c->ranges[type].max_len) goto out_len; - if (!must_chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc && - c->no_chk_data_crc) - return 0; + if (!chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc) + if (c->no_chk_data_crc) + return 0; crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); node_crc = le32_to_cpu(ch->crc); diff --git a/trunk/fs/ubifs/journal.c b/trunk/fs/ubifs/journal.c index a11ca0958a23..9b7c54e0cd2a 100644 --- a/trunk/fs/ubifs/journal.c +++ b/trunk/fs/ubifs/journal.c @@ -208,7 +208,7 @@ static int reserve_space(struct ubifs_info *c, int jhead, int len) offs = 0; out: - err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, wbuf->dtype); + err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, UBI_SHORTTERM); if (err) goto out_unlock; diff --git a/trunk/fs/ubifs/lprops.c b/trunk/fs/ubifs/lprops.c index 4cdd284dea56..dfd2bcece27a 100644 --- a/trunk/fs/ubifs/lprops.c +++ b/trunk/fs/ubifs/lprops.c @@ -635,10 +635,10 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c, * @c: UBIFS file-system description object * @st: return statistics */ -void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *lst) +void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *st) { spin_lock(&c->space_lock); - memcpy(lst, &c->lst, sizeof(struct ubifs_lp_stats)); + memcpy(st, &c->lst, sizeof(struct ubifs_lp_stats)); spin_unlock(&c->space_lock); } @@ -678,9 +678,6 @@ int ubifs_change_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, out: ubifs_release_lprops(c); - if (err) - ubifs_err("cannot change properties of LEB %d, error %d", - lnum, err); return err; } @@ -717,9 +714,6 @@ int ubifs_update_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, out: ubifs_release_lprops(c); - if (err) - ubifs_err("cannot update properties of LEB %d, error %d", - lnum, err); return err; } @@ -743,8 +737,6 @@ int ubifs_read_one_lp(struct ubifs_info *c, int lnum, struct ubifs_lprops *lp) lpp = ubifs_lpt_lookup(c, lnum); if (IS_ERR(lpp)) { err = PTR_ERR(lpp); - ubifs_err("cannot read properties of LEB %d, error %d", - lnum, err); goto out; } diff --git a/trunk/fs/ubifs/lpt_commit.c b/trunk/fs/ubifs/lpt_commit.c index 3216a1f277f8..96ca95707175 100644 --- a/trunk/fs/ubifs/lpt_commit.c +++ b/trunk/fs/ubifs/lpt_commit.c @@ -556,23 +556,23 @@ static int write_cnodes(struct ubifs_info *c) } /** - * next_pnode_to_dirty - find next pnode to dirty. + * next_pnode - find next pnode. * @c: UBIFS file-system description object * @pnode: pnode * - * This function returns the next pnode to dirty or %NULL if there are no more - * pnodes. Note that pnodes that have never been written (lnum == 0) are - * skipped. + * This function returns the next pnode or %NULL if there are no more pnodes. */ -static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c, - struct ubifs_pnode *pnode) +static struct ubifs_pnode *next_pnode(struct ubifs_info *c, + struct ubifs_pnode *pnode) { struct ubifs_nnode *nnode; int iip; /* Try to go right */ nnode = pnode->parent; - for (iip = pnode->iip + 1; iip < UBIFS_LPT_FANOUT; iip++) { + iip = pnode->iip + 1; + if (iip < UBIFS_LPT_FANOUT) { + /* We assume here that LEB zero is never an LPT LEB */ if (nnode->nbranch[iip].lnum) return ubifs_get_pnode(c, nnode, iip); } @@ -583,11 +583,8 @@ static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c, nnode = nnode->parent; if (!nnode) return NULL; - for (; iip < UBIFS_LPT_FANOUT; iip++) { - if (nnode->nbranch[iip].lnum) - break; - } - } while (iip >= UBIFS_LPT_FANOUT); + /* We assume here that LEB zero is never an LPT LEB */ + } while (iip >= UBIFS_LPT_FANOUT || !nnode->nbranch[iip].lnum); /* Go right */ nnode = ubifs_get_nnode(c, nnode, iip); @@ -596,29 +593,12 @@ static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c, /* Go down to level 1 */ while (nnode->level > 1) { - for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++) { - if (nnode->nbranch[iip].lnum) - break; - } - if (iip >= UBIFS_LPT_FANOUT) { - /* - * Should not happen, but we need to keep going - * if it does. - */ - iip = 0; - } - nnode = ubifs_get_nnode(c, nnode, iip); + nnode = ubifs_get_nnode(c, nnode, 0); if (IS_ERR(nnode)) return (void *)nnode; } - for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++) - if (nnode->nbranch[iip].lnum) - break; - if (iip >= UBIFS_LPT_FANOUT) - /* Should not happen, but we need to keep going if it does */ - iip = 0; - return ubifs_get_pnode(c, nnode, iip); + return ubifs_get_pnode(c, nnode, 0); } /** @@ -708,7 +688,7 @@ static int make_tree_dirty(struct ubifs_info *c) pnode = pnode_lookup(c, 0); while (pnode) { do_make_pnode_dirty(c, pnode); - pnode = next_pnode_to_dirty(c, pnode); + pnode = next_pnode(c, pnode); if (IS_ERR(pnode)) return PTR_ERR(pnode); } diff --git a/trunk/fs/ubifs/master.c b/trunk/fs/ubifs/master.c index a88f33801b98..71d5493bf565 100644 --- a/trunk/fs/ubifs/master.c +++ b/trunk/fs/ubifs/master.c @@ -354,7 +354,7 @@ int ubifs_write_master(struct ubifs_info *c) int err, lnum, offs, len; if (c->ro_media) - return -EROFS; + return -EINVAL; lnum = UBIFS_MST_LNUM; offs = c->mst_offs + c->mst_node_alsz; diff --git a/trunk/fs/ubifs/orphan.c b/trunk/fs/ubifs/orphan.c index 152a7b34a141..9e6f403f170e 100644 --- a/trunk/fs/ubifs/orphan.c +++ b/trunk/fs/ubifs/orphan.c @@ -46,7 +46,7 @@ * Orphans are accumulated in a rb-tree. When an inode's link count drops to * zero, the inode number is added to the rb-tree. It is removed from the tree * when the inode is deleted. Any new orphans that are in the orphan tree when - * the commit is run, are written to the orphan area in 1 or more orphan nodes. + * the commit is run, are written to the orphan area in 1 or more orph nodes. * If the orphan area is full, it is consolidated to make space. There is * always enough space because validation prevents the user from creating more * than the maximum number of orphans allowed. @@ -231,7 +231,7 @@ static int tot_avail_orphs(struct ubifs_info *c) } /** - * do_write_orph_node - write a node to the orphan head. + * do_write_orph_node - write a node * @c: UBIFS file-system description object * @len: length of node * @atomic: write atomically @@ -264,11 +264,11 @@ static int do_write_orph_node(struct ubifs_info *c, int len, int atomic) } /** - * write_orph_node - write an orphan node. + * write_orph_node - write an orph node * @c: UBIFS file-system description object * @atomic: write atomically * - * This function builds an orphan node from the cnext list and writes it to the + * This function builds an orph node from the cnext list and writes it to the * orphan head. On success, %0 is returned, otherwise a negative error code * is returned. */ @@ -326,11 +326,11 @@ static int write_orph_node(struct ubifs_info *c, int atomic) } /** - * write_orph_nodes - write orphan nodes until there are no more to commit. + * write_orph_nodes - write orph nodes until there are no more to commit * @c: UBIFS file-system description object * @atomic: write atomically * - * This function writes orphan nodes for all the orphans to commit. On success, + * This function writes orph nodes for all the orphans to commit. On success, * %0 is returned, otherwise a negative error code is returned. */ static int write_orph_nodes(struct ubifs_info *c, int atomic) @@ -478,14 +478,14 @@ int ubifs_orphan_end_commit(struct ubifs_info *c) } /** - * ubifs_clear_orphans - erase all LEBs used for orphans. + * clear_orphans - erase all LEBs used for orphans. * @c: UBIFS file-system description object * * If recovery is not required, then the orphans from the previous session * are not needed. This function locates the LEBs used to record * orphans, and un-maps them. */ -int ubifs_clear_orphans(struct ubifs_info *c) +static int clear_orphans(struct ubifs_info *c) { int lnum, err; @@ -547,9 +547,9 @@ static int insert_dead_orphan(struct ubifs_info *c, ino_t inum) * do_kill_orphans - remove orphan inodes from the index. * @c: UBIFS file-system description object * @sleb: scanned LEB - * @last_cmt_no: cmt_no of last orphan node read is passed and returned here + * @last_cmt_no: cmt_no of last orph node read is passed and returned here * @outofdate: whether the LEB is out of date is returned here - * @last_flagged: whether the end orphan node is encountered + * @last_flagged: whether the end orph node is encountered * * This function is a helper to the 'kill_orphans()' function. It goes through * every orphan node in a LEB and for every inode number recorded, removes @@ -580,8 +580,8 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb, /* * The commit number on the master node may be less, because * of a failed commit. If there are several failed commits in a - * row, the commit number written on orphan nodes will continue - * to increase (because the commit number is adjusted here) even + * row, the commit number written on orph nodes will continue to + * increase (because the commit number is adjusted here) even * though the commit number on the master node stays the same * because the master node has not been re-written. */ @@ -589,9 +589,9 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb, c->cmt_no = cmt_no; if (cmt_no < *last_cmt_no && *last_flagged) { /* - * The last orphan node had a higher commit number and - * was flagged as the last written for that commit - * number. That makes this orphan node, out of date. + * The last orph node had a higher commit number and was + * flagged as the last written for that commit number. + * That makes this orph node, out of date. */ if (!first) { ubifs_err("out of order commit number %llu in " @@ -658,10 +658,10 @@ static int kill_orphans(struct ubifs_info *c) /* * Orph nodes always start at c->orph_first and are written to each * successive LEB in turn. Generally unused LEBs will have been unmapped - * but may contain out of date orphan nodes if the unmap didn't go - * through. In addition, the last orphan node written for each commit is + * but may contain out of date orph nodes if the unmap didn't go + * through. In addition, the last orph node written for each commit is * marked (top bit of orph->cmt_no is set to 1). It is possible that - * there are orphan nodes from the next commit (i.e. the commit did not + * there are orph nodes from the next commit (i.e. the commit did not * complete successfully). In that case, no orphans will have been lost * due to the way that orphans are written, and any orphans added will * be valid orphans anyway and so can be deleted. @@ -718,7 +718,7 @@ int ubifs_mount_orphans(struct ubifs_info *c, int unclean, int read_only) if (unclean) err = kill_orphans(c); else if (!read_only) - err = ubifs_clear_orphans(c); + err = clear_orphans(c); return err; } diff --git a/trunk/fs/ubifs/super.c b/trunk/fs/ubifs/super.c index 1182b66a5491..89556ee72518 100644 --- a/trunk/fs/ubifs/super.c +++ b/trunk/fs/ubifs/super.c @@ -397,7 +397,6 @@ static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_namelen = UBIFS_MAX_NLEN; buf->f_fsid.val[0] = le32_to_cpu(uuid[0]) ^ le32_to_cpu(uuid[2]); buf->f_fsid.val[1] = le32_to_cpu(uuid[1]) ^ le32_to_cpu(uuid[3]); - ubifs_assert(buf->f_bfree <= c->block_cnt); return 0; } @@ -433,23 +432,32 @@ static int ubifs_sync_fs(struct super_block *sb, int wait) int i, err; struct ubifs_info *c = sb->s_fs_info; struct writeback_control wbc = { - .sync_mode = WB_SYNC_ALL, + .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE, .range_start = 0, .range_end = LLONG_MAX, .nr_to_write = LONG_MAX, }; /* - * Zero @wait is just an advisory thing to help the file system shove - * lots of data into the queues, and there will be the second + * Note by akpm about WB_SYNC_NONE used above: zero @wait is just an + * advisory thing to help the file system shove lots of data into the + * queues. If some gets missed then it'll be picked up on the second * '->sync_fs()' call, with non-zero @wait. */ - if (!wait) - return 0; if (sb->s_flags & MS_RDONLY) return 0; + /* + * Synchronize write buffers, because 'ubifs_run_commit()' does not + * do this if it waits for an already running commit. + */ + for (i = 0; i < c->jhead_cnt; i++) { + err = ubifs_wbuf_sync(&c->jheads[i].wbuf); + if (err) + return err; + } + /* * VFS calls '->sync_fs()' before synchronizing all dirty inodes and * pages, so synchronize them first, then commit the journal. Strictly @@ -461,16 +469,6 @@ static int ubifs_sync_fs(struct super_block *sb, int wait) */ generic_sync_sb_inodes(sb, &wbc); - /* - * Synchronize write buffers, because 'ubifs_run_commit()' does not - * do this if it waits for an already running commit. - */ - for (i = 0; i < c->jhead_cnt; i++) { - err = ubifs_wbuf_sync(&c->jheads[i].wbuf); - if (err) - return err; - } - err = ubifs_run_commit(c); if (err) return err; @@ -574,8 +572,15 @@ static int init_constants_early(struct ubifs_info *c) c->ranges[UBIFS_IDX_NODE].max_len = INT_MAX; /* - * Initialize dead and dark LEB space watermarks. See gc.c for comments - * about these values. + * Initialize dead and dark LEB space watermarks. + * + * Dead space is the space which cannot be used. Its watermark is + * equivalent to min. I/O unit or minimum node size if it is greater + * then min. I/O unit. + * + * Dark space is the space which might be used, or might not, depending + * on which node should be written to the LEB. Its watermark is + * equivalent to maximum UBIFS node size. */ c->dead_wm = ALIGN(MIN_WRITE_SZ, c->min_io_size); c->dark_wm = ALIGN(UBIFS_MAX_NODE_SZ, c->min_io_size); @@ -736,12 +741,12 @@ static void init_constants_master(struct ubifs_info *c) * take_gc_lnum - reserve GC LEB. * @c: UBIFS file-system description object * - * This function ensures that the LEB reserved for garbage collection is marked - * as "taken" in lprops. We also have to set free space to LEB size and dirty - * space to zero, because lprops may contain out-of-date information if the - * file-system was un-mounted before it has been committed. This function - * returns zero in case of success and a negative error code in case of - * failure. + * This function ensures that the LEB reserved for garbage collection is + * unmapped and is marked as "taken" in lprops. We also have to set free space + * to LEB size and dirty space to zero, because lprops may contain out-of-date + * information if the file-system was un-mounted before it has been committed. + * This function returns zero in case of success and a negative error code in + * case of failure. */ static int take_gc_lnum(struct ubifs_info *c) { @@ -752,6 +757,10 @@ static int take_gc_lnum(struct ubifs_info *c) return -EINVAL; } + err = ubifs_leb_unmap(c, c->gc_lnum); + if (err) + return err; + /* And we have to tell lprops that this LEB is taken */ err = ubifs_change_one_lp(c, c->gc_lnum, c->leb_size, 0, LPROPS_TAKEN, 0, 0); @@ -957,16 +966,13 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, token = match_token(p, tokens, args); switch (token) { - /* - * %Opt_fast_unmount and %Opt_norm_unmount options are ignored. - * We accepte them in order to be backware-compatible. But this - * should be removed at some point. - */ case Opt_fast_unmount: c->mount_opts.unmount_mode = 2; + c->fast_unmount = 1; break; case Opt_norm_unmount: c->mount_opts.unmount_mode = 1; + c->fast_unmount = 0; break; case Opt_bulk_read: c->mount_opts.bulk_read = 2; @@ -1088,7 +1094,12 @@ static int check_free_space(struct ubifs_info *c) ubifs_err("insufficient free space to mount in read/write mode"); dbg_dump_budg(c); dbg_dump_lprops(c); - return -ENOSPC; + /* + * We return %-EINVAL instead of %-ENOSPC because it seems to + * be the closest error code mentioned in the mount function + * documentation. + */ + return -EINVAL; } return 0; } @@ -1275,19 +1286,10 @@ static int mount_ubifs(struct ubifs_info *c) if (err) goto out_orphans; err = ubifs_rcvry_gc_commit(c); - } else { + } else err = take_gc_lnum(c); - if (err) - goto out_orphans; - - /* - * GC LEB may contain garbage if there was an unclean - * reboot, and it should be un-mapped. - */ - err = ubifs_leb_unmap(c, c->gc_lnum); - if (err) - return err; - } + if (err) + goto out_orphans; err = dbg_check_lprops(c); if (err) @@ -1296,16 +1298,6 @@ static int mount_ubifs(struct ubifs_info *c) err = ubifs_recover_size(c); if (err) goto out_orphans; - } else { - /* - * Even if we mount read-only, we have to set space in GC LEB - * to proper value because this affects UBIFS free space - * reporting. We do not want to have a situation when - * re-mounting from R/O to R/W changes amount of free space. - */ - err = take_gc_lnum(c); - if (err) - goto out_orphans; } spin_lock(&ubifs_infos_lock); @@ -1318,17 +1310,14 @@ static int mount_ubifs(struct ubifs_info *c) else { c->need_recovery = 0; ubifs_msg("recovery completed"); - /* GC LEB has to be empty and taken at this point */ - ubifs_assert(c->lst.taken_empty_lebs == 1); } - } else - ubifs_assert(c->lst.taken_empty_lebs == 1); + } - err = dbg_check_filesystem(c); + err = dbg_debugfs_init_fs(c); if (err) goto out_infos; - err = dbg_debugfs_init_fs(c); + err = dbg_check_filesystem(c); if (err) goto out_infos; @@ -1362,6 +1351,7 @@ static int mount_ubifs(struct ubifs_info *c) c->uuid[4], c->uuid[5], c->uuid[6], c->uuid[7], c->uuid[8], c->uuid[9], c->uuid[10], c->uuid[11], c->uuid[12], c->uuid[13], c->uuid[14], c->uuid[15]); + dbg_msg("fast unmount: %d", c->fast_unmount); dbg_msg("big_lpt %d", c->big_lpt); dbg_msg("log LEBs: %d (%d - %d)", c->log_lebs, UBIFS_LOG_LNUM, c->log_last); @@ -1485,8 +1475,10 @@ static int ubifs_remount_rw(struct ubifs_info *c) { int err, lnum; + if (c->ro_media) + return -EINVAL; + mutex_lock(&c->umount_mutex); - dbg_save_space_info(c); c->remounting_rw = 1; c->always_chk_crc = 1; @@ -1522,12 +1514,6 @@ static int ubifs_remount_rw(struct ubifs_info *c) err = ubifs_recover_inl_heads(c, c->sbuf); if (err) goto out; - } else { - /* A readonly mount is not allowed to have orphans */ - ubifs_assert(c->tot_orphans == 0); - err = ubifs_clear_orphans(c); - if (err) - goto out; } if (!(c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY))) { @@ -1583,7 +1569,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) if (c->need_recovery) err = ubifs_rcvry_gc_commit(c); else - err = ubifs_leb_unmap(c, c->gc_lnum); + err = take_gc_lnum(c); if (err) goto out; @@ -1596,9 +1582,8 @@ static int ubifs_remount_rw(struct ubifs_info *c) c->vfs_sb->s_flags &= ~MS_RDONLY; c->remounting_rw = 0; c->always_chk_crc = 0; - err = dbg_check_space_info(c); mutex_unlock(&c->umount_mutex); - return err; + return 0; out: vfree(c->orph_buf); @@ -1617,19 +1602,44 @@ static int ubifs_remount_rw(struct ubifs_info *c) return err; } +/** + * commit_on_unmount - commit the journal when un-mounting. + * @c: UBIFS file-system description object + * + * This function is called during un-mounting and re-mounting, and it commits + * the journal unless the "fast unmount" mode is enabled. + */ +static void commit_on_unmount(struct ubifs_info *c) +{ + struct super_block *sb = c->vfs_sb; + long long bud_bytes; + + /* + * This function is called before the background thread is stopped, so + * we may race with ongoing commit, which means we have to take + * @c->bud_lock to access @c->bud_bytes. + */ + spin_lock(&c->buds_lock); + bud_bytes = c->bud_bytes; + spin_unlock(&c->buds_lock); + + if (!c->fast_unmount && !(sb->s_flags & MS_RDONLY) && bud_bytes) + ubifs_run_commit(c); +} + /** * ubifs_remount_ro - re-mount in read-only mode. * @c: UBIFS file-system description object * - * We assume VFS has stopped writing. Possibly the background thread could be - * running a commit, however kthread_stop will wait in that case. + * We rely on VFS to have stopped writing. Possibly the background thread could + * be running a commit, however kthread_stop will wait in that case. */ static void ubifs_remount_ro(struct ubifs_info *c) { int i, err; ubifs_assert(!c->need_recovery); - ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); + commit_on_unmount(c); mutex_lock(&c->umount_mutex); if (c->bgt) { @@ -1637,29 +1647,27 @@ static void ubifs_remount_ro(struct ubifs_info *c) c->bgt = NULL; } - dbg_save_space_info(c); - for (i = 0; i < c->jhead_cnt; i++) { ubifs_wbuf_sync(&c->jheads[i].wbuf); del_timer_sync(&c->jheads[i].wbuf.timer); } - c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); - c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); - c->mst_node->gc_lnum = cpu_to_le32(c->gc_lnum); - err = ubifs_write_master(c); - if (err) - ubifs_ro_mode(c, err); + if (!c->ro_media) { + c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); + c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); + c->mst_node->gc_lnum = cpu_to_le32(c->gc_lnum); + err = ubifs_write_master(c); + if (err) + ubifs_ro_mode(c, err); + } + ubifs_destroy_idx_gc(c); free_wbufs(c); vfree(c->orph_buf); c->orph_buf = NULL; vfree(c->ileb_buf); c->ileb_buf = NULL; ubifs_lpt_free(c, 1); - err = dbg_check_space_info(c); - if (err) - ubifs_ro_mode(c, err); mutex_unlock(&c->umount_mutex); } @@ -1752,20 +1760,11 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) } if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { - if (c->ro_media) { - ubifs_msg("cannot re-mount due to prior errors"); - return -EROFS; - } err = ubifs_remount_rw(c); if (err) return err; - } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { - if (c->ro_media) { - ubifs_msg("cannot re-mount due to prior errors"); - return -EROFS; - } + } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) ubifs_remount_ro(c); - } if (c->bulk_read == 1) bu_init(c); @@ -1775,11 +1774,10 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) c->bu.buf = NULL; } - ubifs_assert(c->lst.taken_empty_lebs == 1); return 0; } -const struct super_operations ubifs_super_operations = { +struct super_operations ubifs_super_operations = { .alloc_inode = ubifs_alloc_inode, .destroy_inode = ubifs_destroy_inode, .put_super = ubifs_put_super, @@ -2046,6 +2044,15 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags, static void ubifs_kill_sb(struct super_block *sb) { + struct ubifs_info *c = sb->s_fs_info; + + /* + * We do 'commit_on_unmount()' here instead of 'ubifs_put_super()' + * in order to be outside BKL. + */ + if (sb->s_root) + commit_on_unmount(c); + /* The un-mount routine is actually done in put_super() */ generic_shutdown_super(sb); } diff --git a/trunk/fs/ubifs/tnc.c b/trunk/fs/ubifs/tnc.c index fa28a84c6a1b..f7e36f545527 100644 --- a/trunk/fs/ubifs/tnc.c +++ b/trunk/fs/ubifs/tnc.c @@ -443,11 +443,6 @@ static int tnc_read_node_nm(struct ubifs_info *c, struct ubifs_zbranch *zbr, * This function performs that same function as ubifs_read_node except that * it does not require that there is actually a node present and instead * the return code indicates if a node was read. - * - * Note, this function does not check CRC of data nodes if @c->no_chk_data_crc - * is true (it is controlled by corresponding mount option). However, if - * @c->always_chk_crc is true, @c->no_chk_data_crc is ignored and CRC is always - * checked. */ static int try_read_node(const struct ubifs_info *c, void *buf, int type, int len, int lnum, int offs) @@ -475,8 +470,9 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type, if (node_len != len) return 0; - if (type == UBIFS_DATA_NODE && !c->always_chk_crc && c->no_chk_data_crc) - return 1; + if (type == UBIFS_DATA_NODE && !c->always_chk_crc) + if (c->no_chk_data_crc) + return 0; crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); node_crc = le32_to_cpu(ch->crc); @@ -1510,7 +1506,7 @@ int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, * * Note, if the bulk-read buffer length (@bu->buf_len) is known, this function * makes sure bulk-read nodes fit the buffer. Otherwise, this function prepares - * maximum possible amount of nodes for bulk-read. + * maxumum possible amount of nodes for bulk-read. */ int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu) { diff --git a/trunk/fs/ubifs/ubifs.h b/trunk/fs/ubifs/ubifs.h index 039a68bee29a..fc2a4cc66d03 100644 --- a/trunk/fs/ubifs/ubifs.h +++ b/trunk/fs/ubifs/ubifs.h @@ -426,9 +426,9 @@ struct ubifs_unclean_leb { * LEB properties flags. * * LPROPS_UNCAT: not categorized - * LPROPS_DIRTY: dirty > free, dirty >= @c->dead_wm, not index + * LPROPS_DIRTY: dirty > 0, not index * LPROPS_DIRTY_IDX: dirty + free > @c->min_idx_node_sze and index - * LPROPS_FREE: free > 0, dirty < @c->dead_wm, not empty, not index + * LPROPS_FREE: free > 0, not empty, not index * LPROPS_HEAP_CNT: number of heaps used for storing categorized LEBs * LPROPS_EMPTY: LEB is empty, not taken * LPROPS_FREEABLE: free + dirty == leb_size, not index, not taken @@ -961,6 +961,7 @@ struct ubifs_debug_info; * @cs_lock: commit state lock * @cmt_wq: wait queue to sleep on if the log is full and a commit is running * + * @fast_unmount: do not run journal commit before un-mounting * @big_lpt: flag that LPT is too big to write whole during commit * @no_chk_data_crc: do not check CRCs when reading data nodes (except during * recovery) @@ -1201,6 +1202,7 @@ struct ubifs_info { spinlock_t cs_lock; wait_queue_head_t cmt_wq; + unsigned int fast_unmount:1; unsigned int big_lpt:1; unsigned int no_chk_data_crc:1; unsigned int bulk_read:1; @@ -1403,13 +1405,13 @@ extern struct list_head ubifs_infos; extern spinlock_t ubifs_infos_lock; extern atomic_long_t ubifs_clean_zn_cnt; extern struct kmem_cache *ubifs_inode_slab; -extern const struct super_operations ubifs_super_operations; -extern const struct address_space_operations ubifs_file_address_operations; -extern const struct file_operations ubifs_file_operations; -extern const struct inode_operations ubifs_file_inode_operations; -extern const struct file_operations ubifs_dir_operations; -extern const struct inode_operations ubifs_dir_inode_operations; -extern const struct inode_operations ubifs_symlink_inode_operations; +extern struct super_operations ubifs_super_operations; +extern struct address_space_operations ubifs_file_address_operations; +extern struct file_operations ubifs_file_operations; +extern struct inode_operations ubifs_file_inode_operations; +extern struct file_operations ubifs_dir_operations; +extern struct inode_operations ubifs_dir_inode_operations; +extern struct inode_operations ubifs_symlink_inode_operations; extern struct backing_dev_info ubifs_backing_dev_info; extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; @@ -1426,7 +1428,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum, int offs, int dtype); int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, - int offs, int quiet, int must_chk_crc); + int offs, int quiet, int chk_crc); void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad); void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last); int ubifs_io_init(struct ubifs_info *c); @@ -1493,7 +1495,6 @@ void ubifs_release_ino_dirty(struct ubifs_info *c, struct inode *inode, void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode, struct ubifs_budget_req *req); long long ubifs_get_free_space(struct ubifs_info *c); -long long ubifs_get_free_space_nolock(struct ubifs_info *c); int ubifs_calc_min_idx_lebs(struct ubifs_info *c); void ubifs_convert_page_budget(struct ubifs_info *c); long long ubifs_reported_space(const struct ubifs_info *c, long long free); @@ -1602,7 +1603,6 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum); int ubifs_orphan_start_commit(struct ubifs_info *c); int ubifs_orphan_end_commit(struct ubifs_info *c); int ubifs_mount_orphans(struct ubifs_info *c, int unclean, int read_only); -int ubifs_clear_orphans(struct ubifs_info *c); /* lpt.c */ int ubifs_calc_lpt_geom(struct ubifs_info *c); @@ -1646,7 +1646,7 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c, const struct ubifs_lprops *lp, int free, int dirty, int flags, int idx_gc_cnt); -void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *lst); +void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *stats); void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops, int cat); void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops, diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index cb329edc925b..d71dc44e21ed 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -165,75 +165,6 @@ test_page_region( return (mask && (page_private(page) & mask) == mask); } -/* - * Mapping of multi-page buffers into contiguous virtual space - */ - -typedef struct a_list { - void *vm_addr; - struct a_list *next; -} a_list_t; - -static a_list_t *as_free_head; -static int as_list_len; -static DEFINE_SPINLOCK(as_lock); - -/* - * Try to batch vunmaps because they are costly. - */ -STATIC void -free_address( - void *addr) -{ - a_list_t *aentry; - -#ifdef CONFIG_XEN - /* - * Xen needs to be able to make sure it can get an exclusive - * RO mapping of pages it wants to turn into a pagetable. If - * a newly allocated page is also still being vmap()ed by xfs, - * it will cause pagetable construction to fail. This is a - * quick workaround to always eagerly unmap pages so that Xen - * is happy. - */ - vunmap(addr); - return; -#endif - - aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT); - if (likely(aentry)) { - spin_lock(&as_lock); - aentry->next = as_free_head; - aentry->vm_addr = addr; - as_free_head = aentry; - as_list_len++; - spin_unlock(&as_lock); - } else { - vunmap(addr); - } -} - -STATIC void -purge_addresses(void) -{ - a_list_t *aentry, *old; - - if (as_free_head == NULL) - return; - - spin_lock(&as_lock); - aentry = as_free_head; - as_free_head = NULL; - as_list_len = 0; - spin_unlock(&as_lock); - - while ((old = aentry) != NULL) { - vunmap(aentry->vm_addr); - aentry = aentry->next; - kfree(old); - } -} - /* * Internal xfs_buf_t object manipulation */ @@ -333,7 +264,7 @@ xfs_buf_free( uint i; if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) - free_address(bp->b_addr - bp->b_offset); + vm_unmap_ram(bp->b_addr - bp->b_offset, bp->b_page_count); for (i = 0; i < bp->b_page_count; i++) { struct page *page = bp->b_pages[i]; @@ -455,10 +386,8 @@ _xfs_buf_map_pages( bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; bp->b_flags |= XBF_MAPPED; } else if (flags & XBF_MAPPED) { - if (as_list_len > 64) - purge_addresses(); - bp->b_addr = vmap(bp->b_pages, bp->b_page_count, - VM_MAP, PAGE_KERNEL); + bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, + -1, PAGE_KERNEL); if (unlikely(bp->b_addr == NULL)) return -ENOMEM; bp->b_addr += bp->b_offset; @@ -1743,8 +1672,6 @@ xfsbufd( count++; } - if (as_list_len > 0) - purge_addresses(); if (count) blk_run_address_space(target->bt_mapping); diff --git a/trunk/fs/xfs/linux-2.6/xfs_sync.c b/trunk/fs/xfs/linux-2.6/xfs_sync.c index a608e72fa405..2ed035354c26 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_sync.c +++ b/trunk/fs/xfs/linux-2.6/xfs_sync.c @@ -371,11 +371,7 @@ xfs_quiesce_attr( /* flush inodes and push all remaining buffers out to disk */ xfs_quiesce_fs(mp); - /* - * Just warn here till VFS can correctly support - * read-only remount without racing. - */ - WARN_ON(atomic_read(&mp->m_active_trans) != 0); + ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); /* Push the superblock and write an unmount record */ error = xfs_log_sbcount(mp, 1); diff --git a/trunk/fs/xfs/xfs_dfrag.c b/trunk/fs/xfs/xfs_dfrag.c index f8278cfcc1d3..b4c1ee713492 100644 --- a/trunk/fs/xfs/xfs_dfrag.c +++ b/trunk/fs/xfs/xfs_dfrag.c @@ -55,11 +55,17 @@ xfs_swapext( struct file *file, *target_file; int error = 0; + sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); + if (!sxp) { + error = XFS_ERROR(ENOMEM); + goto out; + } + /* Pull information for the target fd */ file = fget((int)sxp->sx_fdtarget); if (!file) { error = XFS_ERROR(EINVAL); - goto out; + goto out_free_sxp; } if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) { @@ -103,6 +109,8 @@ xfs_swapext( fput(target_file); out_put_file: fput(file); + out_free_sxp: + kmem_free(sxp); out: return error; } diff --git a/trunk/fs/xfs/xfs_log_recover.c b/trunk/fs/xfs/xfs_log_recover.c index b1047de2fffd..35cca98bd94c 100644 --- a/trunk/fs/xfs/xfs_log_recover.c +++ b/trunk/fs/xfs/xfs_log_recover.c @@ -70,21 +70,16 @@ STATIC void xlog_recover_check_summary(xlog_t *); xfs_buf_t * xlog_get_bp( xlog_t *log, - int nbblks) + int num_bblks) { - if (nbblks <= 0 || nbblks > log->l_logBBsize) { - xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); - XFS_ERROR_REPORT("xlog_get_bp(1)", - XFS_ERRLEVEL_HIGH, log->l_mp); - return NULL; - } + ASSERT(num_bblks > 0); if (log->l_sectbb_log) { - if (nbblks > 1) - nbblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1); - nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks); + if (num_bblks > 1) + num_bblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1); + num_bblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, num_bblks); } - return xfs_buf_get_noaddr(BBTOB(nbblks), log->l_mp->m_logdev_targp); + return xfs_buf_get_noaddr(BBTOB(num_bblks), log->l_mp->m_logdev_targp); } void @@ -107,13 +102,6 @@ xlog_bread( { int error; - if (nbblks <= 0 || nbblks > log->l_logBBsize) { - xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); - XFS_ERROR_REPORT("xlog_bread(1)", - XFS_ERRLEVEL_HIGH, log->l_mp); - return EFSCORRUPTED; - } - if (log->l_sectbb_log) { blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no); nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks); @@ -151,13 +139,6 @@ xlog_bwrite( { int error; - if (nbblks <= 0 || nbblks > log->l_logBBsize) { - xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); - XFS_ERROR_REPORT("xlog_bwrite(1)", - XFS_ERRLEVEL_HIGH, log->l_mp); - return EFSCORRUPTED; - } - if (log->l_sectbb_log) { blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no); nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks); diff --git a/trunk/include/acpi/pdc_intel.h b/trunk/include/acpi/pdc_intel.h index 552637b0d051..e72bfdd887f9 100644 --- a/trunk/include/acpi/pdc_intel.h +++ b/trunk/include/acpi/pdc_intel.h @@ -14,7 +14,6 @@ #define ACPI_PDC_SMP_T_SWCOORD (0x0080) #define ACPI_PDC_C_C1_FFH (0x0100) #define ACPI_PDC_C_C2C3_FFH (0x0200) -#define ACPI_PDC_SMP_P_HWCOORD (0x0800) #define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ ACPI_PDC_C_C1_HALT | \ @@ -23,7 +22,6 @@ #define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ ACPI_PDC_C_C1_HALT | \ ACPI_PDC_SMP_P_SWCOORD | \ - ACPI_PDC_SMP_P_HWCOORD | \ ACPI_PDC_P_FFH) #define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ diff --git a/trunk/include/asm-frv/pgtable.h b/trunk/include/asm-frv/pgtable.h index e16fdb1f4f4f..83c51aba534b 100644 --- a/trunk/include/asm-frv/pgtable.h +++ b/trunk/include/asm-frv/pgtable.h @@ -478,7 +478,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define __swp_type(x) (((x).val >> 2) & 0x1f) #define __swp_offset(x) ((x).val >> 8) #define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 8) }) -#define __pte_to_swp_entry(_pte) ((swp_entry_t) { (_pte).pte }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) static inline int pte_file(pte_t pte) diff --git a/trunk/include/crypto/hash.h b/trunk/include/crypto/hash.h index d797e119e3d5..cd16d6e668ce 100644 --- a/trunk/include/crypto/hash.h +++ b/trunk/include/crypto/hash.h @@ -222,7 +222,7 @@ static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm) static inline void crypto_free_shash(struct crypto_shash *tfm) { - crypto_destroy_tfm(tfm, crypto_shash_tfm(tfm)); + crypto_free_tfm(crypto_shash_tfm(tfm)); } static inline unsigned int crypto_shash_alignmask( diff --git a/trunk/include/drm/drmP.h b/trunk/include/drm/drmP.h index e5f4ae989abf..8190b9bcc2d9 100644 --- a/trunk/include/drm/drmP.h +++ b/trunk/include/drm/drmP.h @@ -1321,8 +1321,6 @@ void drm_gem_object_free(struct kref *kref); struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, size_t size); void drm_gem_object_handle_free(struct kref *kref); -void drm_gem_vm_open(struct vm_area_struct *vma); -void drm_gem_vm_close(struct vm_area_struct *vma); int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); static inline void diff --git a/trunk/include/drm/drm_crtc.h b/trunk/include/drm/drm_crtc.h index 5ded1acfb543..d54de24bf371 100644 --- a/trunk/include/drm/drm_crtc.h +++ b/trunk/include/drm/drm_crtc.h @@ -609,7 +609,7 @@ extern char *drm_get_dvi_i_subconnector_name(int val); extern char *drm_get_dvi_i_select_name(int val); extern char *drm_get_tv_subconnector_name(int val); extern char *drm_get_tv_select_name(int val); -extern void drm_fb_release(struct drm_file *file_priv); +extern void drm_fb_release(struct file *filp); extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group); extern struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter); diff --git a/trunk/include/drm/drm_crtc_helper.h b/trunk/include/drm/drm_crtc_helper.h index c7d4b2e606a5..0c6f0e11b41b 100644 --- a/trunk/include/drm/drm_crtc_helper.h +++ b/trunk/include/drm/drm_crtc_helper.h @@ -54,13 +54,13 @@ struct drm_crtc_helper_funcs { struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); /* Actually set the mode */ - int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, - struct drm_framebuffer *old_fb); + void (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, int x, int y, + struct drm_framebuffer *old_fb); /* Move the crtc on the current fb to the given position *optional* */ - int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb); + void (*mode_set_base)(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb); }; struct drm_encoder_helper_funcs { @@ -76,7 +76,6 @@ struct drm_encoder_helper_funcs { void (*mode_set)(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); - struct drm_crtc *(*get_crtc)(struct drm_encoder *encoder); /* detect for DAC style encoders */ enum drm_connector_status (*detect)(struct drm_encoder *encoder, struct drm_connector *connector); diff --git a/trunk/include/drm/drm_edid.h b/trunk/include/drm/drm_edid.h index ff8d27af4786..c707c15f5164 100644 --- a/trunk/include/drm/drm_edid.h +++ b/trunk/include/drm/drm_edid.h @@ -58,10 +58,10 @@ struct detailed_pixel_timing { u8 hsync_pulse_width_lo; u8 vsync_pulse_width_lo:4; u8 vsync_offset_lo:4; - u8 vsync_pulse_width_hi:2; - u8 vsync_offset_hi:2; u8 hsync_pulse_width_hi:2; u8 hsync_offset_hi:2; + u8 vsync_pulse_width_hi:2; + u8 vsync_offset_hi:2; u8 width_mm_lo; u8 height_mm_lo; u8 height_mm_hi:4; diff --git a/trunk/include/drm/i915_drm.h b/trunk/include/drm/i915_drm.h index 912cd52db965..b3bcf72dc656 100644 --- a/trunk/include/drm/i915_drm.h +++ b/trunk/include/drm/i915_drm.h @@ -261,7 +261,6 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_LAST_DISPATCH 3 #define I915_PARAM_CHIPSET_ID 4 #define I915_PARAM_HAS_GEM 5 -#define I915_PARAM_NUM_FENCES_AVAIL 6 typedef struct drm_i915_getparam { int param; @@ -273,7 +272,6 @@ typedef struct drm_i915_getparam { #define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1 #define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 #define I915_SETPARAM_ALLOW_BATCHBUFFER 3 -#define I915_SETPARAM_NUM_USED_FENCES 4 typedef struct drm_i915_setparam { int param; diff --git a/trunk/include/linux/async.h b/trunk/include/linux/async.h index 68a9530196f2..c4ecacd0b327 100644 --- a/trunk/include/linux/async.h +++ b/trunk/include/linux/async.h @@ -17,11 +17,9 @@ typedef u64 async_cookie_t; typedef void (async_func_ptr) (void *data, async_cookie_t cookie); extern async_cookie_t async_schedule(async_func_ptr *ptr, void *data); -extern async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, - struct list_head *list); +extern async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *list); extern void async_synchronize_full(void); -extern void async_synchronize_full_domain(struct list_head *list); +extern void async_synchronize_full_special(struct list_head *list); extern void async_synchronize_cookie(async_cookie_t cookie); -extern void async_synchronize_cookie_domain(async_cookie_t cookie, - struct list_head *list); +extern void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *list); diff --git a/trunk/include/linux/ata.h b/trunk/include/linux/ata.h index 08a86d5cdf1b..a53318b8cbd0 100644 --- a/trunk/include/linux/ata.h +++ b/trunk/include/linux/ata.h @@ -731,17 +731,12 @@ static inline int ata_id_current_chs_valid(const u16 *id) static inline int ata_id_is_cfa(const u16 *id) { - if (id[ATA_ID_CONFIG] == 0x848A) /* Traditional CF */ + if (id[ATA_ID_CONFIG] == 0x848A) /* Standard CF */ return 1; - /* - * CF specs don't require specific value in the word 0 anymore and yet - * they forbid to report the ATA version in the word 80 and require the - * CFA feature set support to be indicated in the word 83 in this case. - * Unfortunately, some cards only follow either of this requirements, - * and while those that don't indicate CFA feature support need some - * sort of quirk list, it seems impractical for the ones that do... - */ - if ((id[ATA_ID_COMMAND_SET_2] & 0xC004) == 0x4004) + /* Could be CF hiding as standard ATA */ + if (ata_id_major_version(id) >= 3 && + id[ATA_ID_COMMAND_SET_1] != 0xFFFF && + (id[ATA_ID_COMMAND_SET_1] & (1 << 2))) return 1; return 0; } diff --git a/trunk/include/linux/bio.h b/trunk/include/linux/bio.h index 1b16108a5417..2aa283ab062b 100644 --- a/trunk/include/linux/bio.h +++ b/trunk/include/linux/bio.h @@ -171,6 +171,8 @@ struct bio { #define BIO_RW_FAILFAST_TRANSPORT 8 #define BIO_RW_FAILFAST_DRIVER 9 +#define BIO_RW_SYNC (BIO_RW_SYNCIO | BIO_RW_UNPLUG) + #define bio_rw_flagged(bio, flag) ((bio)->bi_rw & (1 << (flag))) /* diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index 465d6babc847..dcaa0fd84b02 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -708,8 +708,6 @@ struct req_iterator { }; /* This should not be used directly - use rq_for_each_segment */ -#define for_each_bio(_bio) \ - for (; _bio; _bio = _bio->bi_next) #define __rq_for_each_bio(_bio, rq) \ if ((rq->bio)) \ for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next) diff --git a/trunk/include/linux/blktrace_api.h b/trunk/include/linux/blktrace_api.h index 6e915878e88c..25379cba2370 100644 --- a/trunk/include/linux/blktrace_api.h +++ b/trunk/include/linux/blktrace_api.h @@ -15,7 +15,6 @@ enum blktrace_cat { BLK_TC_WRITE = 1 << 1, /* writes */ BLK_TC_BARRIER = 1 << 2, /* barrier */ BLK_TC_SYNC = 1 << 3, /* sync IO */ - BLK_TC_SYNCIO = BLK_TC_SYNC, BLK_TC_QUEUE = 1 << 4, /* queueing/merging */ BLK_TC_REQUEUE = 1 << 5, /* requeueing */ BLK_TC_ISSUE = 1 << 6, /* issue */ diff --git a/trunk/include/linux/cgroup.h b/trunk/include/linux/cgroup.h index 499900d0cee7..e4e8e117d27d 100644 --- a/trunk/include/linux/cgroup.h +++ b/trunk/include/linux/cgroup.h @@ -378,7 +378,6 @@ struct cgroup_subsys { * - initiating hotplug events */ struct mutex hierarchy_mutex; - struct lock_class_key subsys_key; /* * Link to parent, and list entry in parent's children. diff --git a/trunk/include/linux/crypto.h b/trunk/include/linux/crypto.h index 1f2e9020acc6..3bacd71509fb 100644 --- a/trunk/include/linux/crypto.h +++ b/trunk/include/linux/crypto.h @@ -552,12 +552,7 @@ struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, const struct crypto_type *frontend, u32 type, u32 mask); struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask); -void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm); - -static inline void crypto_free_tfm(struct crypto_tfm *tfm) -{ - return crypto_destroy_tfm(tfm, tfm); -} +void crypto_free_tfm(struct crypto_tfm *tfm); int alg_test(const char *driver, const char *alg, u32 type, u32 mask); diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index 47f343c7bdda..45e5b1921fbb 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -147,8 +147,6 @@ extern void put_driver(struct device_driver *drv); extern struct device_driver *driver_find(const char *name, struct bus_type *bus); extern int driver_probe_done(void); -extern int wait_for_device_probe(void); - /* sysfs interface for exporting driver attributes */ diff --git a/trunk/include/linux/dmaengine.h b/trunk/include/linux/dmaengine.h index f0413845f20e..3e68469c1885 100644 --- a/trunk/include/linux/dmaengine.h +++ b/trunk/include/linux/dmaengine.h @@ -121,7 +121,6 @@ struct dma_chan_percpu { * @local: per-cpu pointer to a struct dma_chan_percpu * @client-count: how many clients are using this channel * @table_count: number of appearances in the mem-to-mem allocation table - * @private: private data for certain client-channel associations */ struct dma_chan { struct dma_device *device; @@ -135,7 +134,6 @@ struct dma_chan { struct dma_chan_percpu *local; int client_count; int table_count; - void *private; }; /** diff --git a/trunk/include/linux/fb.h b/trunk/include/linux/fb.h index 31527e17076b..818fe21257e8 100644 --- a/trunk/include/linux/fb.h +++ b/trunk/include/linux/fb.h @@ -960,21 +960,6 @@ extern struct fb_info *registered_fb[FB_MAX]; extern int num_registered_fb; extern struct class *fb_class; -static inline int lock_fb_info(struct fb_info *info) -{ - mutex_lock(&info->lock); - if (!info->fbops) { - mutex_unlock(&info->lock); - return 0; - } - return 1; -} - -static inline void unlock_fb_info(struct fb_info *info) -{ - mutex_unlock(&info->lock); -} - static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) { diff --git a/trunk/include/linux/firmware-map.h b/trunk/include/linux/firmware-map.h index cca686b39123..6e199c8dfacc 100644 --- a/trunk/include/linux/firmware-map.h +++ b/trunk/include/linux/firmware-map.h @@ -1,7 +1,7 @@ /* * include/linux/firmware-map.h: * Copyright (C) 2008 SUSE LINUX Products GmbH - * by Bernhard Walle + * by Bernhard Walle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License v2.0 as published by diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 92734c0012e6..6022f44043f2 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -54,30 +54,24 @@ struct inodes_stat_t { #define MAY_ACCESS 16 #define MAY_OPEN 32 -/* - * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond - * to O_WRONLY and O_RDWR via the strange trick in __dentry_open() - */ - /* file is open for reading */ #define FMODE_READ ((__force fmode_t)1) /* file is open for writing */ #define FMODE_WRITE ((__force fmode_t)2) /* file is seekable */ #define FMODE_LSEEK ((__force fmode_t)4) -/* file can be accessed using pread */ +/* file can be accessed using pread/pwrite */ #define FMODE_PREAD ((__force fmode_t)8) -/* file can be accessed using pwrite */ -#define FMODE_PWRITE ((__force fmode_t)16) +#define FMODE_PWRITE FMODE_PREAD /* These go hand in hand */ /* File is opened for execution with sys_execve / sys_uselib */ -#define FMODE_EXEC ((__force fmode_t)32) +#define FMODE_EXEC ((__force fmode_t)16) /* File is opened with O_NDELAY (only set for block devices) */ -#define FMODE_NDELAY ((__force fmode_t)64) +#define FMODE_NDELAY ((__force fmode_t)32) /* File is opened with O_EXCL (only set for block devices) */ -#define FMODE_EXCL ((__force fmode_t)128) +#define FMODE_EXCL ((__force fmode_t)64) /* File is opened using open(.., 3, ..) and is writeable only for ioctls (specialy hack for floppy.c) */ -#define FMODE_WRITE_IOCTL ((__force fmode_t)256) +#define FMODE_WRITE_IOCTL ((__force fmode_t)128) /* * Don't update ctime and mtime. @@ -93,10 +87,10 @@ struct inodes_stat_t { #define WRITE 1 #define READA 2 /* read-ahead - don't block if no resources */ #define SWRITE 3 /* for ll_rw_block() - wait for buffer lock */ -#define READ_SYNC (READ | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) +#define READ_SYNC (READ | (1 << BIO_RW_SYNC)) #define READ_META (READ | (1 << BIO_RW_META)) -#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) -#define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) +#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC)) +#define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNC)) #define WRITE_BARRIER (WRITE | (1 << BIO_RW_BARRIER)) #define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD) #define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER)) diff --git a/trunk/include/linux/hugetlb.h b/trunk/include/linux/hugetlb.h index 03be7f29ca01..f1d2fba19ea0 100644 --- a/trunk/include/linux/hugetlb.h +++ b/trunk/include/linux/hugetlb.h @@ -33,8 +33,7 @@ unsigned long hugetlb_total_pages(void); int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access); int hugetlb_reserve_pages(struct inode *inode, long from, long to, - struct vm_area_struct *vma, - int acctflags); + struct vm_area_struct *vma); void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed); extern unsigned long hugepages_treat_as_movable; @@ -139,7 +138,7 @@ static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) extern const struct file_operations hugetlbfs_file_operations; extern struct vm_operations_struct hugetlb_vm_ops; -struct file *hugetlb_file_setup(const char *name, size_t, int); +struct file *hugetlb_file_setup(const char *name, size_t); int hugetlb_get_quota(struct address_space *mapping, long delta); void hugetlb_put_quota(struct address_space *mapping, long delta); @@ -159,9 +158,9 @@ static inline void set_file_hugepages(struct file *file) } #else /* !CONFIG_HUGETLBFS */ -#define is_file_hugepages(file) 0 -#define set_file_hugepages(file) BUG() -#define hugetlb_file_setup(name,size,acctflag) ERR_PTR(-ENOSYS) +#define is_file_hugepages(file) 0 +#define set_file_hugepages(file) BUG() +#define hugetlb_file_setup(name,size) ERR_PTR(-ENOSYS) #endif /* !CONFIG_HUGETLBFS */ diff --git a/trunk/include/linux/i2c-dev.h b/trunk/include/linux/i2c-dev.h index fd53bfd26470..311315b56b61 100644 --- a/trunk/include/linux/i2c-dev.h +++ b/trunk/include/linux/i2c-dev.h @@ -33,7 +33,7 @@ */ #define I2C_RETRIES 0x0701 /* number of times a device address should be polled when not acknowledging */ -#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms */ +#define I2C_TIMEOUT 0x0702 /* set timeout in jiffies - call with int */ /* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses * are NOT supported! (due to code brokenness) diff --git a/trunk/include/linux/i2c.h b/trunk/include/linux/i2c.h index c86c3b07604c..fcfbfea3af72 100644 --- a/trunk/include/linux/i2c.h +++ b/trunk/include/linux/i2c.h @@ -361,7 +361,7 @@ struct i2c_adapter { struct mutex bus_lock; struct mutex clist_lock; - int timeout; /* in jiffies */ + int timeout; int retries; struct device dev; /* the adapter device */ diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index fe235b65207e..194da5a4b0d6 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -663,7 +663,7 @@ typedef struct ide_drive_s ide_drive_t; #define to_ide_device(dev) container_of(dev, ide_drive_t, gendev) #define to_ide_drv(obj, cont_type) \ - container_of(obj, struct cont_type, dev) + container_of(obj, struct cont_type, kref) #define ide_drv_g(disk, cont_type) \ container_of((disk)->private_data, struct cont_type, driver) diff --git a/trunk/include/linux/init_task.h b/trunk/include/linux/init_task.h index e752d973fa21..ea0ea1a4c36f 100644 --- a/trunk/include/linux/init_task.h +++ b/trunk/include/linux/init_task.h @@ -48,11 +48,12 @@ extern struct fs_struct init_fs; .posix_timers = LIST_HEAD_INIT(sig.posix_timers), \ .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \ .rlim = INIT_RLIMITS, \ - .cputimer = { \ - .cputime = INIT_CPUTIME, \ - .running = 0, \ - .lock = __SPIN_LOCK_UNLOCKED(sig.cputimer.lock), \ - }, \ + .cputime = { .totals = { \ + .utime = cputime_zero, \ + .stime = cputime_zero, \ + .sum_exec_runtime = 0, \ + .lock = __SPIN_LOCK_UNLOCKED(sig.cputime.totals.lock), \ + }, }, \ } extern struct nsproxy init_nsproxy; diff --git a/trunk/include/linux/intel-iommu.h b/trunk/include/linux/intel-iommu.h index d2e3cbfba14f..c4f6c101dbcd 100644 --- a/trunk/include/linux/intel-iommu.h +++ b/trunk/include/linux/intel-iommu.h @@ -194,7 +194,6 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) /* FSTS_REG */ #define DMA_FSTS_PPF ((u32)2) #define DMA_FSTS_PFO ((u32)1) -#define DMA_FSTS_IQE (1 << 4) #define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff) /* FRCD_REG, 32 bits access */ @@ -329,7 +328,7 @@ extern int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, unsigned int size_order, u64 type, int non_present_entry_flush); -extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); +extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); extern void *intel_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); extern void intel_free_coherent(struct device *, size_t, void *, dma_addr_t); diff --git a/trunk/include/linux/io-mapping.h b/trunk/include/linux/io-mapping.h index cbc2f0cd631b..82df31726a54 100644 --- a/trunk/include/linux/io-mapping.h +++ b/trunk/include/linux/io-mapping.h @@ -30,13 +30,10 @@ * See Documentation/io_mapping.txt */ -#ifdef CONFIG_HAVE_ATOMIC_IOMAP +/* this struct isn't actually defined anywhere */ +struct io_mapping; -struct io_mapping { - resource_size_t base; - unsigned long size; - pgprot_t prot; -}; +#ifdef CONFIG_HAVE_ATOMIC_IOMAP /* * For small address space machines, mapping large objects @@ -46,40 +43,23 @@ struct io_mapping { */ static inline struct io_mapping * -io_mapping_create_wc(resource_size_t base, unsigned long size) +io_mapping_create_wc(unsigned long base, unsigned long size) { - struct io_mapping *iomap; - - if (!is_io_mapping_possible(base, size)) - return NULL; - - iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); - if (!iomap) - return NULL; - - iomap->base = base; - iomap->size = size; - iomap->prot = pgprot_writecombine(__pgprot(__PAGE_KERNEL)); - return iomap; + return (struct io_mapping *) base; } static inline void io_mapping_free(struct io_mapping *mapping) { - kfree(mapping); } /* Atomic map/unmap */ static inline void * io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) { - resource_size_t phys_addr; - unsigned long pfn; - - BUG_ON(offset >= mapping->size); - phys_addr = mapping->base + offset; - pfn = (unsigned long) (phys_addr >> PAGE_SHIFT); - return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot); + offset += (unsigned long) mapping; + return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, + __pgprot(__PAGE_KERNEL_WC)); } static inline void @@ -91,9 +71,8 @@ io_mapping_unmap_atomic(void *vaddr) static inline void * io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) { - BUG_ON(offset >= mapping->size); - resource_size_t phys_addr = mapping->base + offset; - return ioremap_wc(phys_addr, PAGE_SIZE); + offset += (unsigned long) mapping; + return ioremap_wc(offset, PAGE_SIZE); } static inline void @@ -104,12 +83,9 @@ io_mapping_unmap(void *vaddr) #else -/* this struct isn't actually defined anywhere */ -struct io_mapping; - /* Create the io_mapping object*/ static inline struct io_mapping * -io_mapping_create_wc(resource_size_t base, unsigned long size) +io_mapping_create_wc(unsigned long base, unsigned long size) { return (struct io_mapping *) ioremap_wc(base, size); } diff --git a/trunk/include/linux/jbd2.h b/trunk/include/linux/jbd2.h index 4d248b3f1323..b28b37eb11c6 100644 --- a/trunk/include/linux/jbd2.h +++ b/trunk/include/linux/jbd2.h @@ -1150,8 +1150,7 @@ extern int jbd2_journal_clear_err (journal_t *); extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *); extern int jbd2_journal_force_commit(journal_t *); extern int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode); -extern int jbd2_journal_begin_ordered_truncate(journal_t *journal, - struct jbd2_inode *inode, loff_t new_size); +extern int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode, loff_t new_size); extern void jbd2_journal_init_jbd_inode(struct jbd2_inode *jinode, struct inode *inode); extern void jbd2_journal_release_jbd_inode(journal_t *journal, struct jbd2_inode *jinode); diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index 7fa371898e3e..343df9ef2412 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -480,8 +480,7 @@ static inline char *pack_hex_byte(char *buf, u8 byte) /* * swap - swap value of @a and @b */ -#define swap(a, b) \ - do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) +#define swap(a, b) ({ typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; }) /** * container_of - cast a member of a structure out to the containing structure diff --git a/trunk/include/linux/kvm.h b/trunk/include/linux/kvm.h index 0424326f1679..5715f1907601 100644 --- a/trunk/include/linux/kvm.h +++ b/trunk/include/linux/kvm.h @@ -58,10 +58,10 @@ struct kvm_irqchip { __u32 pad; union { char dummy[512]; /* reserving space */ -#ifdef __KVM_HAVE_PIT +#ifdef CONFIG_X86 struct kvm_pic_state pic; #endif -#ifdef __KVM_HAVE_IOAPIC +#if defined(CONFIG_X86) || defined(CONFIG_IA64) struct kvm_ioapic_state ioapic; #endif } chip; @@ -384,16 +384,16 @@ struct kvm_trace_rec { #define KVM_CAP_MP_STATE 14 #define KVM_CAP_COALESCED_MMIO 15 #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ -#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT +#if defined(CONFIG_X86)||defined(CONFIG_IA64) #define KVM_CAP_DEVICE_ASSIGNMENT 17 #endif #define KVM_CAP_IOMMU 18 -#ifdef __KVM_HAVE_MSI +#if defined(CONFIG_X86) #define KVM_CAP_DEVICE_MSI 20 #endif /* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ #define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 -#ifdef __KVM_HAVE_USER_NMI +#if defined(CONFIG_X86) #define KVM_CAP_USER_NMI 22 #endif diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index bf6f703642fc..ec49d0be7f52 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -285,7 +285,6 @@ void kvm_free_physmem(struct kvm *kvm); struct kvm *kvm_arch_create_vm(void); void kvm_arch_destroy_vm(struct kvm *kvm); void kvm_free_all_assigned_devices(struct kvm *kvm); -void kvm_arch_sync_events(struct kvm *kvm); int kvm_cpu_get_interrupt(struct kvm_vcpu *v); int kvm_cpu_has_interrupt(struct kvm_vcpu *v); diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index 5d87bc09a1f5..bca3ba25f52a 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -380,7 +380,6 @@ enum { ATA_HORKAGE_ATAPI_MOD16_DMA = (1 << 11), /* use ATAPI DMA for commands not multiple of 16 bytes */ ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firwmare update warning */ - ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ @@ -581,7 +580,7 @@ struct ata_device { acpi_handle acpi_handle; union acpi_object *gtf_cache; #endif - /* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */ + /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ u64 n_sectors; /* size of device, if ATA */ unsigned int class; /* ATA_DEV_xxx */ unsigned long unpark_deadline; @@ -606,22 +605,20 @@ struct ata_device { u16 heads; /* Number of heads */ u16 sectors; /* Number of sectors per track */ + /* error history */ + int spdn_cnt; + struct ata_ering ering; + union { u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */ }; - - /* error history */ - int spdn_cnt; - /* ering is CLEAR_END, read comment above CLEAR_END */ - struct ata_ering ering; }; -/* Fields between ATA_DEVICE_CLEAR_BEGIN and ATA_DEVICE_CLEAR_END are - * cleared to zero on ata_dev_init(). +/* Offset into struct ata_device. Fields above it are maintained + * acress device init. Fields below are zeroed. */ -#define ATA_DEVICE_CLEAR_BEGIN offsetof(struct ata_device, n_sectors) -#define ATA_DEVICE_CLEAR_END offsetof(struct ata_device, ering) +#define ATA_DEVICE_CLEAR_OFFSET offsetof(struct ata_device, n_sectors) struct ata_eh_info { struct ata_device *dev; /* offending device */ diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 065cdf8c09fb..e8ddc98b8405 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -1041,23 +1041,10 @@ extern void free_bootmem_with_active_regions(int nid, typedef int (*work_fn_t)(unsigned long, unsigned long, void *); extern void work_with_active_regions(int nid, work_fn_t work_fn, void *data); extern void sparse_memory_present_with_active_regions(int nid); -#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */ - -#if !defined(CONFIG_ARCH_POPULATES_NODE_MAP) && \ - !defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) -static inline int __early_pfn_to_nid(unsigned long pfn) -{ - return 0; -} -#else -/* please see mm/page_alloc.c */ -extern int __meminit early_pfn_to_nid(unsigned long pfn); -#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID -/* there is a per-arch backend function. */ -extern int __meminit __early_pfn_to_nid(unsigned long pfn); +#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID +extern int early_pfn_to_nid(unsigned long pfn); #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ -#endif - +#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */ extern void set_dma_reserve(unsigned long new_dma_reserve); extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long, enum memmap_context); @@ -1142,7 +1129,8 @@ extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long flag, unsigned long pgoff); extern unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long len, unsigned long flags, - unsigned int vm_flags, unsigned long pgoff); + unsigned int vm_flags, unsigned long pgoff, + int accountable); static inline unsigned long do_mmap(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, @@ -1172,7 +1160,6 @@ extern int filemap_fault(struct vm_area_struct *, struct vm_fault *); /* mm/page-writeback.c */ int write_one_page(struct page *page, int wait); -void task_dirty_inc(struct task_struct *tsk); /* readahead.c */ #define VM_MAX_READAHEAD 128 /* kbytes */ @@ -1318,6 +1305,5 @@ void vmemmap_populate_print_last(void); extern void *alloc_locked_buffer(size_t size); extern void free_locked_buffer(void *buffer, size_t size); -extern void release_locked_buffer(void *buffer, size_t size); #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/trunk/include/linux/mmzone.h b/trunk/include/linux/mmzone.h index 1aca6cebbb78..09c14e213b63 100644 --- a/trunk/include/linux/mmzone.h +++ b/trunk/include/linux/mmzone.h @@ -1071,7 +1071,7 @@ void sparse_init(void); #endif /* CONFIG_SPARSEMEM */ #ifdef CONFIG_NODES_SPAN_OTHER_NODES -bool early_pfn_in_nid(unsigned long pfn, int nid); +#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid)) #else #define early_pfn_in_nid(pfn, nid) (1) #endif diff --git a/trunk/include/linux/module.h b/trunk/include/linux/module.h index 145a75528cc1..f3b8329eb5b8 100644 --- a/trunk/include/linux/module.h +++ b/trunk/include/linux/module.h @@ -407,6 +407,7 @@ static inline local_t *__module_ref_addr(struct module *mod, int cpu) static inline void __module_get(struct module *module) { if (module) { + BUG_ON(module_refcount(module) == 0); local_inc(__module_ref_addr(module, get_cpu())); put_cpu(); } diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index 7bd624bfdcfd..48890cf3f96e 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -684,7 +684,7 @@ int pci_enable_rom(struct pci_dev *pdev); void pci_disable_rom(struct pci_dev *pdev); void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); -size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); +size_t pci_get_rom_size(void __iomem *rom, size_t size); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index aca8c458aa8a..52a9fe08451c 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1312,7 +1312,6 @@ #define PCI_DEVICE_ID_VIA_VT3351 0x0351 #define PCI_DEVICE_ID_VIA_VT3364 0x0364 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 -#define PCI_DEVICE_ID_VIA_6415 0x0415 #define PCI_DEVICE_ID_VIA_8501_0 0x0501 #define PCI_DEVICE_ID_VIA_82C561 0x0561 #define PCI_DEVICE_ID_VIA_82C586_1 0x0571 @@ -1445,7 +1444,6 @@ #define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071 #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072 #define PCI_DEVICE_ID_DIGI_DF_M_A 0x0073 -#define PCI_DEVICE_ID_DIGI_NEO_8 0x00B1 #define PCI_DEVICE_ID_NEO_2DB9 0x00C8 #define PCI_DEVICE_ID_NEO_2DB9PRI 0x00C9 #define PCI_DEVICE_ID_NEO_2RJ45 0x00CA @@ -2323,9 +2321,6 @@ #define PCI_DEVICE_ID_INTEL_82378 0x0484 #define PCI_DEVICE_ID_INTEL_I960 0x0960 #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 -#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062 -#define PCI_DEVICE_ID_INTEL_82573E_SOL 0x1085 -#define PCI_DEVICE_ID_INTEL_82573L_SOL 0x108F #define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 #define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 diff --git a/trunk/include/linux/pm.h b/trunk/include/linux/pm.h index 24ba5f67b3a3..de2e0a8f6728 100644 --- a/trunk/include/linux/pm.h +++ b/trunk/include/linux/pm.h @@ -381,12 +381,10 @@ struct dev_pm_info { #ifdef CONFIG_PM_SLEEP extern void device_pm_lock(void); -extern int sysdev_resume(void); extern void device_power_up(pm_message_t state); extern void device_resume(pm_message_t state); extern void device_pm_unlock(void); -extern int sysdev_suspend(pm_message_t state); extern int device_power_down(pm_message_t state); extern int device_suspend(pm_message_t state); extern int device_prepare_suspend(pm_message_t state); diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 8981e52c714f..5a7c76388731 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -453,33 +453,23 @@ struct task_cputime { cputime_t utime; cputime_t stime; unsigned long long sum_exec_runtime; + spinlock_t lock; }; /* Alternate field names when used to cache expirations. */ #define prof_exp stime #define virt_exp utime #define sched_exp sum_exec_runtime -#define INIT_CPUTIME \ - (struct task_cputime) { \ - .utime = cputime_zero, \ - .stime = cputime_zero, \ - .sum_exec_runtime = 0, \ - } - /** - * struct thread_group_cputimer - thread group interval timer counts - * @cputime: thread group interval timers. - * @running: non-zero when there are timers running and - * @cputime receives updates. - * @lock: lock for fields in this struct. + * struct thread_group_cputime - thread group interval timer counts + * @totals: thread group interval timers; substructure for + * uniprocessor kernel, per-cpu for SMP kernel. * * This structure contains the version of task_cputime, above, that is - * used for thread group CPU timer calculations. + * used for thread group CPU clock calculations. */ -struct thread_group_cputimer { - struct task_cputime cputime; - int running; - spinlock_t lock; +struct thread_group_cputime { + struct task_cputime totals; }; /* @@ -528,10 +518,10 @@ struct signal_struct { cputime_t it_prof_incr, it_virt_incr; /* - * Thread group totals for process CPU timers. - * See thread_group_cputimer(), et al, for details. + * Thread group totals for process CPU clocks. + * See thread_group_cputime(), et al, for details. */ - struct thread_group_cputimer cputimer; + struct thread_group_cputime cputime; /* Earliest-expiration cache. */ struct task_cputime cputime_expires; @@ -568,7 +558,7 @@ struct signal_struct { * Live threads maintain their own counters and add to these * in __exit_signal, except for the group leader. */ - cputime_t utime, stime, cutime, cstime; + cputime_t cutime, cstime; cputime_t gtime; cputime_t cgtime; unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; @@ -576,14 +566,6 @@ struct signal_struct { unsigned long inblock, oublock, cinblock, coublock; struct task_io_accounting ioac; - /* - * Cumulative ns of schedule CPU time fo dead threads in the - * group, not including a zombie group leader, (This only differs - * from jiffies_to_ns(utime + stime) if sched_clock uses something - * other than jiffies.) - */ - unsigned long long sum_sched_runtime; - /* * We don't bother to synchronize most readers of this at all, * because there is no reader checking a limit that actually needs @@ -2200,14 +2182,27 @@ static inline int spin_needbreak(spinlock_t *lock) /* * Thread group CPU time accounting. */ -void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times); -void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times); + +static inline +void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times) +{ + struct task_cputime *totals = &tsk->signal->cputime.totals; + unsigned long flags; + + spin_lock_irqsave(&totals->lock, flags); + *times = *totals; + spin_unlock_irqrestore(&totals->lock, flags); +} static inline void thread_group_cputime_init(struct signal_struct *sig) { - sig->cputimer.cputime = INIT_CPUTIME; - spin_lock_init(&sig->cputimer.lock); - sig->cputimer.running = 0; + sig->cputime.totals = (struct task_cputime){ + .utime = cputime_zero, + .stime = cputime_zero, + .sum_exec_runtime = 0, + }; + + spin_lock_init(&sig->cputime.totals.lock); } static inline void thread_group_cputime_free(struct signal_struct *sig) diff --git a/trunk/include/linux/seq_file.h b/trunk/include/linux/seq_file.h index f616f31576d7..40ea5058c2ec 100644 --- a/trunk/include/linux/seq_file.h +++ b/trunk/include/linux/seq_file.h @@ -19,7 +19,6 @@ struct seq_file { size_t from; size_t count; loff_t index; - loff_t read_pos; u64 version; struct mutex lock; const struct seq_operations *op; diff --git a/trunk/include/linux/serial_core.h b/trunk/include/linux/serial_core.h index df9245c7bd3b..90bbbf0b1161 100644 --- a/trunk/include/linux/serial_core.h +++ b/trunk/include/linux/serial_core.h @@ -296,7 +296,6 @@ struct uart_port { #define UPF_HARDPPS_CD ((__force upf_t) (1 << 11)) #define UPF_LOW_LATENCY ((__force upf_t) (1 << 13)) #define UPF_BUGGY_UART ((__force upf_t) (1 << 14)) -#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) diff --git a/trunk/include/linux/slab.h b/trunk/include/linux/slab.h index 24c5602bee99..f96d13c281e8 100644 --- a/trunk/include/linux/slab.h +++ b/trunk/include/linux/slab.h @@ -127,7 +127,6 @@ int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr); void * __must_check __krealloc(const void *, size_t, gfp_t); void * __must_check krealloc(const void *, size_t, gfp_t); void kfree(const void *); -void kzfree(const void *); size_t ksize(const void *); /* diff --git a/trunk/include/linux/soundcard.h b/trunk/include/linux/soundcard.h index 1904afedb82f..523d069c862c 100644 --- a/trunk/include/linux/soundcard.h +++ b/trunk/include/linux/soundcard.h @@ -1045,36 +1045,50 @@ typedef struct mixer_vol_table { */ #define LOCL_STARTAUDIO 1 -#if !defined(__KERNEL__) || defined(USE_SEQ_MACROS) +#if (!defined(__KERNEL__) && !defined(KERNEL) && !defined(INKERNEL) && !defined(_KERNEL)) || defined(USE_SEQ_MACROS) /* * Some convenience macros to simplify programming of the * /dev/sequencer interface * - * This is a legacy interface for applications written against - * the OSSlib-3.8 style interface. It is no longer possible - * to actually link against OSSlib with this header, but we - * still provide these macros for programs using them. - * - * If you want to use OSSlib, it is recommended that you get - * the GPL version of OSS-4.x and build against that version - * of the header. - * - * We redefine the extern keyword so that make headers_check - * does not complain about SEQ_USE_EXTBUF. + * These macros define the API which should be used when possible. */ #define SEQ_DECLAREBUF() SEQ_USE_EXTBUF() void seqbuf_dump(void); /* This function must be provided by programs */ -#define SEQ_PM_DEFINES int __foo_bar___ +extern int OSS_init(int seqfd, int buflen); +extern void OSS_seqbuf_dump(int fd, unsigned char *buf, int buflen); +extern void OSS_seq_advbuf(int len, int fd, unsigned char *buf, int buflen); +extern void OSS_seq_needbuf(int len, int fd, unsigned char *buf, int buflen); +extern void OSS_patch_caching(int dev, int chn, int patch, + int fd, unsigned char *buf, int buflen); +extern void OSS_drum_caching(int dev, int chn, int patch, + int fd, unsigned char *buf, int buflen); +extern void OSS_write_patch(int fd, unsigned char *buf, int len); +extern int OSS_write_patch2(int fd, unsigned char *buf, int len); -#define SEQ_LOAD_GMINSTR(dev, instr) -#define SEQ_LOAD_GMDRUM(dev, drum) - -#define _SEQ_EXTERN extern -#define SEQ_USE_EXTBUF() \ - _SEQ_EXTERN unsigned char _seqbuf[]; \ - _SEQ_EXTERN int _seqbuflen; _SEQ_EXTERN int _seqbufptr +#define SEQ_PM_DEFINES int __foo_bar___ +#ifdef OSSLIB +# define SEQ_USE_EXTBUF() \ + extern unsigned char *_seqbuf; \ + extern int _seqbuflen;extern int _seqbufptr +# define SEQ_DEFINEBUF(len) SEQ_USE_EXTBUF();static int _requested_seqbuflen=len +# define _SEQ_ADVBUF(len) OSS_seq_advbuf(len, seqfd, _seqbuf, _seqbuflen) +# define _SEQ_NEEDBUF(len) OSS_seq_needbuf(len, seqfd, _seqbuf, _seqbuflen) +# define SEQ_DUMPBUF() OSS_seqbuf_dump(seqfd, _seqbuf, _seqbuflen) + +# define SEQ_LOAD_GMINSTR(dev, instr) \ + OSS_patch_caching(dev, -1, instr, seqfd, _seqbuf, _seqbuflen) +# define SEQ_LOAD_GMDRUM(dev, drum) \ + OSS_drum_caching(dev, -1, drum, seqfd, _seqbuf, _seqbuflen) +#else /* !OSSLIB */ + +# define SEQ_LOAD_GMINSTR(dev, instr) +# define SEQ_LOAD_GMDRUM(dev, drum) + +# define SEQ_USE_EXTBUF() \ + extern unsigned char _seqbuf[]; \ + extern int _seqbuflen;extern int _seqbufptr #ifndef USE_SIMPLE_MACROS /* Sample seqbuf_dump() implementation: @@ -1117,6 +1131,7 @@ void seqbuf_dump(void); /* This function must be provided by programs */ */ #define _SEQ_NEEDBUF(len) /* empty */ #endif +#endif /* !OSSLIB */ #define SEQ_VOLUME_MODE(dev, mode) {_SEQ_NEEDBUF(8);\ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ @@ -1200,8 +1215,14 @@ void seqbuf_dump(void); /* This function must be provided by programs */ _CHN_COMMON(dev, MIDI_CHN_PRESSURE, chn, pressure, 0, 0) #define SEQ_SET_PATCH SEQ_PGM_CHANGE -#define SEQ_PGM_CHANGE(dev, chn, patch) \ +#ifdef OSSLIB +# define SEQ_PGM_CHANGE(dev, chn, patch) \ + {OSS_patch_caching(dev, chn, patch, seqfd, _seqbuf, _seqbuflen); \ + _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0);} +#else +# define SEQ_PGM_CHANGE(dev, chn, patch) \ _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0) +#endif #define SEQ_CONTROL(dev, chn, controller, value) \ _CHN_COMMON(dev, MIDI_CTL_CHANGE, chn, controller, 0, value) @@ -1279,12 +1300,19 @@ void seqbuf_dump(void); /* This function must be provided by programs */ /* * Patch loading. */ -#define SEQ_WRPATCH(patchx, len) \ +#ifdef OSSLIB +# define SEQ_WRPATCH(patchx, len) \ + OSS_write_patch(seqfd, (char*)(patchx), len) +# define SEQ_WRPATCH2(patchx, len) \ + OSS_write_patch2(seqfd, (char*)(patchx), len) +#else +# define SEQ_WRPATCH(patchx, len) \ {if (_seqbufptr) SEQ_DUMPBUF();\ if (write(seqfd, (char*)(patchx), len)==-1) \ perror("Write patch: /dev/sequencer");} -#define SEQ_WRPATCH2(patchx, len) \ +# define SEQ_WRPATCH2(patchx, len) \ (SEQ_DUMPBUF(), write(seqfd, (char*)(patchx), len)) +#endif #endif #endif diff --git a/trunk/include/linux/spi/spi_bitbang.h b/trunk/include/linux/spi/spi_bitbang.h index eed4254bd503..bf8de281b4ed 100644 --- a/trunk/include/linux/spi/spi_bitbang.h +++ b/trunk/include/linux/spi/spi_bitbang.h @@ -83,13 +83,6 @@ extern int spi_bitbang_stop(struct spi_bitbang *spi); * int getmiso(struct spi_device *); * void spidelay(unsigned); * - * setsck()'s is_on parameter is a zero/nonzero boolean. - * - * setmosi()'s is_on parameter is a zero/nonzero boolean. - * - * getmiso() is required to return 0 or 1 only. Any other value is invalid - * and will result in improper operation. - * * A non-inlined routine would call bitbang_txrx_*() routines. The * main loop could easily compile down to a handful of instructions, * especially if the delay is a NOP (to run at peak speed). diff --git a/trunk/include/linux/spinlock.h b/trunk/include/linux/spinlock.h index a0c66a2e00ad..e0c0fccced46 100644 --- a/trunk/include/linux/spinlock.h +++ b/trunk/include/linux/spinlock.h @@ -124,12 +124,7 @@ do { \ #ifdef CONFIG_GENERIC_LOCKBREAK #define spin_is_contended(lock) ((lock)->break_lock) #else - -#ifdef __raw_spin_is_contended #define spin_is_contended(lock) __raw_spin_is_contended(&(lock)->raw_lock) -#else -#define spin_is_contended(lock) (((void)(lock), 0)) -#endif /*__raw_spin_is_contended*/ #endif /** diff --git a/trunk/include/linux/syscalls.h b/trunk/include/linux/syscalls.h index f9f900cfd066..0eda02ff2414 100644 --- a/trunk/include/linux/syscalls.h +++ b/trunk/include/linux/syscalls.h @@ -95,13 +95,13 @@ struct old_linux_dirent; #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) -#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) -#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) -#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) -#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) -#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) -#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) -#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) +#define SYSCALL_DEFINE1(...) SYSCALL_DEFINEx(1, __VA_ARGS__) +#define SYSCALL_DEFINE2(...) SYSCALL_DEFINEx(2, __VA_ARGS__) +#define SYSCALL_DEFINE3(...) SYSCALL_DEFINEx(3, __VA_ARGS__) +#define SYSCALL_DEFINE4(...) SYSCALL_DEFINEx(4, __VA_ARGS__) +#define SYSCALL_DEFINE5(...) SYSCALL_DEFINEx(5, __VA_ARGS__) +#define SYSCALL_DEFINE6(...) SYSCALL_DEFINEx(6, __VA_ARGS__) #ifdef CONFIG_PPC64 #define SYSCALL_ALIAS(alias, name) \ @@ -121,21 +121,21 @@ struct old_linux_dirent; #define SYSCALL_DEFINE(name) static inline long SYSC_##name #define SYSCALL_DEFINEx(x, name, ...) \ - asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \ - static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \ - asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \ + asmlinkage long sys_##name(__SC_DECL##x(__VA_ARGS__)); \ + static inline long SYSC_##name(__SC_DECL##x(__VA_ARGS__)); \ + asmlinkage long SyS_##name(__SC_LONG##x(__VA_ARGS__)) \ { \ __SC_TEST##x(__VA_ARGS__); \ - return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__)); \ + return (long) SYSC_##name(__SC_CAST##x(__VA_ARGS__)); \ } \ - SYSCALL_ALIAS(sys##name, SyS##name); \ - static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)) + SYSCALL_ALIAS(sys_##name, SyS_##name); \ + static inline long SYSC_##name(__SC_DECL##x(__VA_ARGS__)) #else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ #define SYSCALL_DEFINE(name) asmlinkage long sys_##name #define SYSCALL_DEFINEx(x, name, ...) \ - asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)) + asmlinkage long sys_##name(__SC_DECL##x(__VA_ARGS__)) #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ diff --git a/trunk/include/linux/timerfd.h b/trunk/include/linux/timerfd.h index 2d0792983f8c..86cb0501d3e2 100644 --- a/trunk/include/linux/timerfd.h +++ b/trunk/include/linux/timerfd.h @@ -11,21 +11,13 @@ /* For O_CLOEXEC and O_NONBLOCK */ #include -/* - * CAREFUL: Check include/asm-generic/fcntl.h when defining - * new flags, since they might collide with O_* ones. We want - * to re-use O_* flags that couldn't possibly have a meaning - * from eventfd, in order to leave a free define-space for - * shared O_* flags. - */ +/* Flags for timerfd_settime. */ #define TFD_TIMER_ABSTIME (1 << 0) + +/* Flags for timerfd_create. */ #define TFD_CLOEXEC O_CLOEXEC #define TFD_NONBLOCK O_NONBLOCK -#define TFD_SHARED_FCNTL_FLAGS (TFD_CLOEXEC | TFD_NONBLOCK) -/* Flags for timerfd_create. */ -#define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS -/* Flags for timerfd_settime. */ -#define TFD_SETTIME_FLAGS TFD_TIMER_ABSTIME #endif /* _LINUX_TIMERFD_H */ + diff --git a/trunk/include/linux/user_namespace.h b/trunk/include/linux/user_namespace.h index cc4f45361dbb..315bcd375224 100644 --- a/trunk/include/linux/user_namespace.h +++ b/trunk/include/linux/user_namespace.h @@ -13,7 +13,6 @@ struct user_namespace { struct kref kref; struct hlist_head uidhash_table[UIDHASH_SZ]; struct user_struct *creator; - struct work_struct destroyer; }; extern struct user_namespace init_user_ns; diff --git a/trunk/include/linux/vmalloc.h b/trunk/include/linux/vmalloc.h index 9c0890c7a06a..506e7620a986 100644 --- a/trunk/include/linux/vmalloc.h +++ b/trunk/include/linux/vmalloc.h @@ -84,10 +84,6 @@ extern struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags, void *caller); extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, unsigned long start, unsigned long end); -extern struct vm_struct *__get_vm_area_caller(unsigned long size, - unsigned long flags, - unsigned long start, unsigned long end, - void *caller); extern struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, int node, gfp_t gfp_mask); diff --git a/trunk/include/linux/wait.h b/trunk/include/linux/wait.h index a210ede73b56..ef609f842fac 100644 --- a/trunk/include/linux/wait.h +++ b/trunk/include/linux/wait.h @@ -132,8 +132,6 @@ static inline void __remove_wait_queue(wait_queue_head_t *head, list_del(&old->task_list); } -void __wake_up_common(wait_queue_head_t *q, unsigned int mode, - int nr_exclusive, int sync, void *key); void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key); extern void __wake_up_locked(wait_queue_head_t *q, unsigned int mode); extern void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr); @@ -335,19 +333,16 @@ do { \ for (;;) { \ prepare_to_wait_exclusive(&wq, &__wait, \ TASK_INTERRUPTIBLE); \ - if (condition) { \ - finish_wait(&wq, &__wait); \ + if (condition) \ break; \ - } \ if (!signal_pending(current)) { \ schedule(); \ continue; \ } \ ret = -ERESTARTSYS; \ - abort_exclusive_wait(&wq, &__wait, \ - TASK_INTERRUPTIBLE, NULL); \ break; \ } \ + finish_wait(&wq, &__wait); \ } while (0) #define wait_event_interruptible_exclusive(wq, condition) \ @@ -436,8 +431,6 @@ extern long interruptible_sleep_on_timeout(wait_queue_head_t *q, void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state); void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state); void finish_wait(wait_queue_head_t *q, wait_queue_t *wait); -void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, - unsigned int mode, void *key); int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key); diff --git a/trunk/include/video/aty128.h b/trunk/include/video/aty128.h index 51ac69f05bdc..7079beb005e8 100644 --- a/trunk/include/video/aty128.h +++ b/trunk/include/video/aty128.h @@ -21,9 +21,9 @@ #define I2C_CNTL_1 0x0094 #define PALETTE_INDEX 0x00b0 #define PALETTE_DATA 0x00b4 -#define CNFG_CNTL 0x00e0 +#define CONFIG_CNTL 0x00e0 #define GEN_RESET_CNTL 0x00f0 -#define CNFG_MEMSIZE 0x00f8 +#define CONFIG_MEMSIZE 0x00f8 #define MEM_CNTL 0x0140 #define MEM_POWER_MISC 0x015c #define AGP_BASE 0x0170 diff --git a/trunk/include/video/mach64.h b/trunk/include/video/mach64.h index 89e91c0cb737..a8332e528ec1 100644 --- a/trunk/include/video/mach64.h +++ b/trunk/include/video/mach64.h @@ -103,7 +103,7 @@ #define CUR_HORZ_VERT_OFF 0x0070 /* Dword offset 0_1C */ #define CUR2_HORZ_VERT_OFF 0x0070 /* Dword offset 0_1C */ -#define CNFG_PANEL_LG 0x0074 /* Dword offset 0_1D (LG) */ +#define CONFIG_PANEL_LG 0x0074 /* Dword offset 0_1D (LG) */ /* General I/O Control */ #define GP_IO 0x0078 /* Dword offset 0_1E */ @@ -146,8 +146,8 @@ #define CLOCK_SEL_CNTL 0x0090 /* Dword offset 0_24 */ /* Configuration */ -#define CNFG_STAT1 0x0094 /* Dword offset 0_25 */ -#define CNFG_STAT2 0x0098 /* Dword offset 0_26 */ +#define CONFIG_STAT1 0x0094 /* Dword offset 0_25 */ +#define CONFIG_STAT2 0x0098 /* Dword offset 0_26 */ /* Bus Control */ #define BUS_CNTL 0x00A0 /* Dword offset 0_28 */ @@ -190,9 +190,9 @@ #define POWER_MANAGEMENT_LG 0x00D8 /* Dword offset 0_36 (LG) */ /* Configuration */ -#define CNFG_CNTL 0x00DC /* Dword offset 0_37 (CT, ET, VT) */ -#define CNFG_CHIP_ID 0x00E0 /* Dword offset 0_38 */ -#define CNFG_STAT0 0x00E4 /* Dword offset 0_39 */ +#define CONFIG_CNTL 0x00DC /* Dword offset 0_37 (CT, ET, VT) */ +#define CONFIG_CHIP_ID 0x00E0 /* Dword offset 0_38 */ +#define CONFIG_STAT0 0x00E4 /* Dword offset 0_39 */ /* Test and Debug */ #define CRC_SIG 0x00E8 /* Dword offset 0_3A */ @@ -851,17 +851,17 @@ #define PLL_YCLK_CNTL 0x29 #define PM_DYN_CLK_CNTL 0x2A -/* CNFG_CNTL register constants */ +/* CONFIG_CNTL register constants */ #define APERTURE_4M_ENABLE 1 #define APERTURE_8M_ENABLE 2 #define VGA_APERTURE_ENABLE 4 -/* CNFG_STAT0 register constants (GX, CX) */ +/* CONFIG_STAT0 register constants (GX, CX) */ #define CFG_BUS_TYPE 0x00000007 #define CFG_MEM_TYPE 0x00000038 #define CFG_INIT_DAC_TYPE 0x00000e00 -/* CNFG_STAT0 register constants (CT, ET, VT) */ +/* CONFIG_STAT0 register constants (CT, ET, VT) */ #define CFG_MEM_TYPE_xT 0x00000007 #define ISA 0 @@ -942,7 +942,7 @@ #define PCI_ATI_VENDOR_ID 0x1002 -/* CNFG_CHIP_ID register constants */ +/* CONFIG_CHIP_ID register constants */ #define CFG_CHIP_TYPE 0x0000FFFF #define CFG_CHIP_CLASS 0x00FF0000 #define CFG_CHIP_REV 0xFF000000 @@ -951,7 +951,7 @@ #define CFG_CHIP_MINOR 0xC0000000 -/* Chip IDs read from CNFG_CHIP_ID */ +/* Chip IDs read from CONFIG_CHIP_ID */ /* mach64GX family */ #define GX_CHIP_ID 0xD7 /* mach64GX (ATI888GX00) */ @@ -1254,7 +1254,7 @@ #define CRTC2_DISPLAY_DIS 0x00000400 /* LCD register indices */ -#define CNFG_PANEL 0x00 +#define CONFIG_PANEL 0x00 #define LCD_GEN_CNTL 0x01 #define DSTN_CONTROL 0x02 #define HFB_PITCH_ADDR 0x03 diff --git a/trunk/include/video/radeon.h b/trunk/include/video/radeon.h index e072b16b39ab..1cd09cc5b169 100644 --- a/trunk/include/video/radeon.h +++ b/trunk/include/video/radeon.h @@ -11,13 +11,13 @@ #define HI_STAT 0x004C #define BUS_CNTL1 0x0034 #define I2C_CNTL_1 0x0094 -#define CNFG_CNTL 0x00E0 -#define CNFG_MEMSIZE 0x00F8 -#define CNFG_APER_0_BASE 0x0100 -#define CNFG_APER_1_BASE 0x0104 -#define CNFG_APER_SIZE 0x0108 -#define CNFG_REG_1_BASE 0x010C -#define CNFG_REG_APER_SIZE 0x0110 +#define CONFIG_CNTL 0x00E0 +#define CONFIG_MEMSIZE 0x00F8 +#define CONFIG_APER_0_BASE 0x0100 +#define CONFIG_APER_1_BASE 0x0104 +#define CONFIG_APER_SIZE 0x0108 +#define CONFIG_REG_1_BASE 0x010C +#define CONFIG_REG_APER_SIZE 0x0110 #define PAD_AGPINPUT_DELAY 0x0164 #define PAD_CTLR_STRENGTH 0x0168 #define PAD_CTLR_UPDATE 0x016C @@ -509,7 +509,7 @@ /* CLOCK_CNTL_INDEX bit constants */ #define PLL_WR_EN 0x00000080 -/* CNFG_CNTL bit constants */ +/* CONFIG_CNTL bit constants */ #define CFG_VGA_RAM_EN 0x00000100 #define CFG_ATI_REV_ID_MASK (0xf << 16) #define CFG_ATI_REV_A11 (0 << 16) @@ -980,7 +980,7 @@ /* masks */ -#define CNFG_MEMSIZE_MASK 0x1f000000 +#define CONFIG_MEMSIZE_MASK 0x1f000000 #define MEM_CFG_TYPE 0x40000000 #define DST_OFFSET_MASK 0x003fffff #define DST_PITCH_MASK 0x3fc00000 diff --git a/trunk/init/do_mounts.c b/trunk/init/do_mounts.c index 8d4ff5afc1d8..708105e163df 100644 --- a/trunk/init/do_mounts.c +++ b/trunk/init/do_mounts.c @@ -370,14 +370,10 @@ void __init prepare_namespace(void) ssleep(root_delay); } - /* - * wait for the known devices to complete their probing - * - * Note: this is a potential source of long boot delays. - * For example, it is not atypical to wait 5 seconds here - * for the touchpad of a laptop to initialize. - */ - wait_for_device_probe(); + /* wait for the known devices to complete their probing */ + while (driver_probe_done() != 0) + msleep(100); + async_synchronize_full(); md_run_setup(); @@ -403,7 +399,6 @@ void __init prepare_namespace(void) while (driver_probe_done() != 0 || (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0) msleep(100); - async_synchronize_full(); } is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; diff --git a/trunk/init/do_mounts_md.c b/trunk/init/do_mounts_md.c index 9bdddbcb3d6a..ff95e3192884 100644 --- a/trunk/init/do_mounts_md.c +++ b/trunk/init/do_mounts_md.c @@ -281,9 +281,8 @@ static void __init autodetect_raid(void) */ printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n"); printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n"); - - wait_for_device_probe(); - + while (driver_probe_done() < 0) + msleep(100); fd = sys_open("/dev/md0", 0, 0); if (fd >= 0) { sys_ioctl(fd, RAID_AUTORUN, raid_autopart); diff --git a/trunk/ipc/shm.c b/trunk/ipc/shm.c index 05d51d2a792c..c0a021f7f41a 100644 --- a/trunk/ipc/shm.c +++ b/trunk/ipc/shm.c @@ -340,7 +340,6 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) struct file * file; char name[13]; int id; - int acctflag = 0; if (size < SHMMIN || size > ns->shm_ctlmax) return -EINVAL; @@ -365,12 +364,11 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) sprintf (name, "SYSV%08x", key); if (shmflg & SHM_HUGETLB) { - /* hugetlb_file_setup applies strict accounting */ - if (shmflg & SHM_NORESERVE) - acctflag = VM_NORESERVE; - file = hugetlb_file_setup(name, size, acctflag); + /* hugetlb_file_setup takes care of mlock user accounting */ + file = hugetlb_file_setup(name, size); shp->mlock_user = current_user(); } else { + int acctflag = 0; /* * Do not allow no accounting for OVERCOMMIT_NEVER, even * if it's asked for. @@ -567,15 +565,11 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, struct hstate *h = hstate_file(shp->shm_file); *rss += pages_per_huge_page(h) * mapping->nrpages; } else { -#ifdef CONFIG_SHMEM struct shmem_inode_info *info = SHMEM_I(inode); spin_lock(&info->lock); *rss += inode->i_mapping->nrpages; *swp += info->swapped; spin_unlock(&info->lock); -#else - *rss += inode->i_mapping->nrpages; -#endif } total++; diff --git a/trunk/kernel/Makefile b/trunk/kernel/Makefile index e4791b3ba55d..170a9213c1b6 100644 --- a/trunk/kernel/Makefile +++ b/trunk/kernel/Makefile @@ -51,7 +51,6 @@ obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_PM) += power/ -obj-$(CONFIG_FREEZER) += power/ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o diff --git a/trunk/kernel/async.c b/trunk/kernel/async.c index f565891f2c9b..608b32b42812 100644 --- a/trunk/kernel/async.c +++ b/trunk/kernel/async.c @@ -54,7 +54,6 @@ asynchronous and synchronous parts of the kernel. #include #include #include -#include #include static async_cookie_t next_cookie = 1; @@ -133,23 +132,21 @@ static void run_one_entry(void) entry = list_first_entry(&async_pending, struct async_entry, list); /* 2) move it to the running queue */ - list_move_tail(&entry->list, entry->running); + list_del(&entry->list); + list_add_tail(&entry->list, &async_running); spin_unlock_irqrestore(&async_lock, flags); /* 3) run it (and print duration)*/ if (initcall_debug && system_state == SYSTEM_BOOTING) { - printk("calling %lli_%pF @ %i\n", (long long)entry->cookie, - entry->func, task_pid_nr(current)); + printk("calling %lli_%pF @ %i\n", entry->cookie, entry->func, task_pid_nr(current)); calltime = ktime_get(); } entry->func(entry->data, entry->cookie); if (initcall_debug && system_state == SYSTEM_BOOTING) { rettime = ktime_get(); delta = ktime_sub(rettime, calltime); - printk("initcall %lli_%pF returned 0 after %lld usecs\n", - (long long)entry->cookie, - entry->func, - (long long)ktime_to_ns(delta) >> 10); + printk("initcall %lli_%pF returned 0 after %lld usecs\n", entry->cookie, + entry->func, ktime_to_ns(delta) >> 10); } /* 4) remove it from the running queue */ @@ -208,44 +205,18 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct l return newcookie; } -/** - * async_schedule - schedule a function for asynchronous execution - * @ptr: function to execute asynchronously - * @data: data pointer to pass to the function - * - * Returns an async_cookie_t that may be used for checkpointing later. - * Note: This function may be called from atomic or non-atomic contexts. - */ async_cookie_t async_schedule(async_func_ptr *ptr, void *data) { - return __async_schedule(ptr, data, &async_running); + return __async_schedule(ptr, data, &async_pending); } EXPORT_SYMBOL_GPL(async_schedule); -/** - * async_schedule_domain - schedule a function for asynchronous execution within a certain domain - * @ptr: function to execute asynchronously - * @data: data pointer to pass to the function - * @running: running list for the domain - * - * Returns an async_cookie_t that may be used for checkpointing later. - * @running may be used in the async_synchronize_*_domain() functions - * to wait within a certain synchronization domain rather than globally. - * A synchronization domain is specified via the running queue @running to use. - * Note: This function may be called from atomic or non-atomic contexts. - */ -async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, - struct list_head *running) +async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *running) { return __async_schedule(ptr, data, running); } -EXPORT_SYMBOL_GPL(async_schedule_domain); +EXPORT_SYMBOL_GPL(async_schedule_special); -/** - * async_synchronize_full - synchronize all asynchronous function calls - * - * This function waits until all asynchronous function calls have been done. - */ void async_synchronize_full(void) { do { @@ -254,30 +225,13 @@ void async_synchronize_full(void) } EXPORT_SYMBOL_GPL(async_synchronize_full); -/** - * async_synchronize_full_domain - synchronize all asynchronous function within a certain domain - * @list: running list to synchronize on - * - * This function waits until all asynchronous function calls for the - * synchronization domain specified by the running list @list have been done. - */ -void async_synchronize_full_domain(struct list_head *list) +void async_synchronize_full_special(struct list_head *list) { - async_synchronize_cookie_domain(next_cookie, list); + async_synchronize_cookie_special(next_cookie, list); } -EXPORT_SYMBOL_GPL(async_synchronize_full_domain); +EXPORT_SYMBOL_GPL(async_synchronize_full_special); -/** - * async_synchronize_cookie_domain - synchronize asynchronous function calls within a certain domain with cookie checkpointing - * @cookie: async_cookie_t to use as checkpoint - * @running: running list to synchronize on - * - * This function waits until all asynchronous function calls for the - * synchronization domain specified by the running list @list submitted - * prior to @cookie have been done. - */ -void async_synchronize_cookie_domain(async_cookie_t cookie, - struct list_head *running) +void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *running) { ktime_t starttime, delta, endtime; @@ -293,22 +247,14 @@ void async_synchronize_cookie_domain(async_cookie_t cookie, delta = ktime_sub(endtime, starttime); printk("async_continuing @ %i after %lli usec\n", - task_pid_nr(current), - (long long)ktime_to_ns(delta) >> 10); + task_pid_nr(current), ktime_to_ns(delta) >> 10); } } -EXPORT_SYMBOL_GPL(async_synchronize_cookie_domain); +EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); -/** - * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing - * @cookie: async_cookie_t to use as checkpoint - * - * This function waits until all asynchronous function calls prior to @cookie - * have been done. - */ void async_synchronize_cookie(async_cookie_t cookie) { - async_synchronize_cookie_domain(cookie, &async_running); + async_synchronize_cookie_special(cookie, &async_running); } EXPORT_SYMBOL_GPL(async_synchronize_cookie); @@ -369,11 +315,7 @@ static int async_manager_thread(void *unused) ec = atomic_read(&entry_count); while (tc < ec && tc < MAX_THREADS) { - if (IS_ERR(kthread_run(async_thread, NULL, "async/%i", - tc))) { - msleep(100); - continue; - } + kthread_run(async_thread, NULL, "async/%i", tc); atomic_inc(&thread_count); tc++; } @@ -388,9 +330,7 @@ static int async_manager_thread(void *unused) static int __init async_init(void) { if (async_enabled) - if (IS_ERR(kthread_run(async_manager_thread, NULL, - "async/mgr"))) - async_enabled = 0; + kthread_run(async_manager_thread, NULL, "async/mgr"); return 0; } diff --git a/trunk/kernel/cgroup.c b/trunk/kernel/cgroup.c index 9edb5c4b79b4..5a54ff42874e 100644 --- a/trunk/kernel/cgroup.c +++ b/trunk/kernel/cgroup.c @@ -1122,8 +1122,8 @@ static void cgroup_kill_sb(struct super_block *sb) { mutex_unlock(&cgroup_mutex); - kill_litter_super(sb); kfree(root); + kill_litter_super(sb); } static struct file_system_type cgroup_fs_type = { @@ -2351,7 +2351,7 @@ static void cgroup_lock_hierarchy(struct cgroupfs_root *root) for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { struct cgroup_subsys *ss = subsys[i]; if (ss->root == root) - mutex_lock(&ss->hierarchy_mutex); + mutex_lock_nested(&ss->hierarchy_mutex, i); } } @@ -2637,7 +2637,6 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss) BUG_ON(!list_empty(&init_task.tasks)); mutex_init(&ss->hierarchy_mutex); - lockdep_set_class(&ss->hierarchy_mutex, &ss->subsys_key); ss->active = 1; } diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index efd30ccf3858..f80dec3f1875 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -118,8 +118,6 @@ static void __exit_signal(struct task_struct *tsk) * We won't ever get here for the group leader, since it * will have been the last reference on the signal_struct. */ - sig->utime = cputime_add(sig->utime, task_utime(tsk)); - sig->stime = cputime_add(sig->stime, task_stime(tsk)); sig->gtime = cputime_add(sig->gtime, task_gtime(tsk)); sig->min_flt += tsk->min_flt; sig->maj_flt += tsk->maj_flt; @@ -128,7 +126,6 @@ static void __exit_signal(struct task_struct *tsk) sig->inblock += task_io_get_inblock(tsk); sig->oublock += task_io_get_oublock(tsk); task_io_accounting_add(&sig->ioac, &tsk->ioac); - sig->sum_sched_runtime += tsk->se.sum_exec_runtime; sig = NULL; /* Marker for below. */ } diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index a66fbde20715..242a706e7721 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -851,14 +851,13 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) sig->tty_old_pgrp = NULL; sig->tty = NULL; - sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; + sig->cutime = sig->cstime = cputime_zero; sig->gtime = cputime_zero; sig->cgtime = cputime_zero; sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; task_io_accounting_init(&sig->ioac); - sig->sum_sched_runtime = 0; taskstats_tgid_init(sig); task_lock(current->group_leader); @@ -1006,7 +1005,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, * triggers too late. This doesn't hurt, the check is only there * to stop root fork bombs. */ - retval = -EAGAIN; if (nr_threads >= max_threads) goto bad_fork_cleanup_count; @@ -1095,7 +1093,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, #ifdef CONFIG_DEBUG_MUTEXES p->blocked_on = NULL; /* not blocked yet */ #endif - if (unlikely(current->ptrace)) + if (unlikely(ptrace_reparented(current))) ptrace_fork(p, clone_flags); /* Perform scheduler related setup. Assign this task to a CPU. */ diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 438701adce23..f89d373a9c6d 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -1165,7 +1165,6 @@ static int futex_wait(u32 __user *uaddr, int fshared, u32 val, ktime_t *abs_time, u32 bitset, int clockrt) { struct task_struct *curr = current; - struct restart_block *restart; DECLARE_WAITQUEUE(wait, curr); struct futex_hash_bucket *hb; struct futex_q q; @@ -1217,13 +1216,11 @@ static int futex_wait(u32 __user *uaddr, int fshared, if (!ret) goto retry; - goto out; + return ret; } ret = -EWOULDBLOCK; - if (unlikely(uval != val)) { - queue_unlock(&q, hb); - goto out_put_key; - } + if (uval != val) + goto out_unlock_put_key; /* Only actually queue if *uaddr contained val. */ queue_me(&q, hb); @@ -1287,38 +1284,38 @@ static int futex_wait(u32 __user *uaddr, int fshared, */ /* If we were woken (and unqueued), we succeeded, whatever. */ - ret = 0; if (!unqueue_me(&q)) - goto out_put_key; - ret = -ETIMEDOUT; + return 0; if (rem) - goto out_put_key; + return -ETIMEDOUT; /* * We expect signal_pending(current), but another thread may * have handled it for us already. */ - ret = -ERESTARTSYS; if (!abs_time) - goto out_put_key; - - restart = ¤t_thread_info()->restart_block; - restart->fn = futex_wait_restart; - restart->futex.uaddr = (u32 *)uaddr; - restart->futex.val = val; - restart->futex.time = abs_time->tv64; - restart->futex.bitset = bitset; - restart->futex.flags = 0; - - if (fshared) - restart->futex.flags |= FLAGS_SHARED; - if (clockrt) - restart->futex.flags |= FLAGS_CLOCKRT; - - ret = -ERESTART_RESTARTBLOCK; + return -ERESTARTSYS; + else { + struct restart_block *restart; + restart = ¤t_thread_info()->restart_block; + restart->fn = futex_wait_restart; + restart->futex.uaddr = (u32 *)uaddr; + restart->futex.val = val; + restart->futex.time = abs_time->tv64; + restart->futex.bitset = bitset; + restart->futex.flags = 0; + + if (fshared) + restart->futex.flags |= FLAGS_SHARED; + if (clockrt) + restart->futex.flags |= FLAGS_CLOCKRT; + return -ERESTART_RESTARTBLOCK; + } -out_put_key: +out_unlock_put_key: + queue_unlock(&q, hb); put_futex_key(fshared, &q.key); + out: return ret; } diff --git a/trunk/kernel/irq/numa_migrate.c b/trunk/kernel/irq/numa_migrate.c index acd88356ac76..ecf765c6a77a 100644 --- a/trunk/kernel/irq/numa_migrate.c +++ b/trunk/kernel/irq/numa_migrate.c @@ -71,7 +71,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, desc = irq_desc_ptrs[irq]; if (desc && old_desc != desc) - goto out_unlock; + goto out_unlock; node = cpu_to_node(cpu); desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node); @@ -84,15 +84,10 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, init_copy_one_irq_desc(irq, old_desc, desc, cpu); irq_desc_ptrs[irq] = desc; - spin_unlock_irqrestore(&sparse_irq_lock, flags); /* free the old one */ free_one_irq_desc(old_desc, desc); - spin_unlock(&old_desc->lock); kfree(old_desc); - spin_lock(&desc->lock); - - return desc; out_unlock: spin_unlock_irqrestore(&sparse_irq_lock, flags); diff --git a/trunk/kernel/itimer.c b/trunk/kernel/itimer.c index 58762f7077ec..6a5fe93dd8bd 100644 --- a/trunk/kernel/itimer.c +++ b/trunk/kernel/itimer.c @@ -62,7 +62,7 @@ int do_getitimer(int which, struct itimerval *value) struct task_cputime cputime; cputime_t utime; - thread_group_cputimer(tsk, &cputime); + thread_group_cputime(tsk, &cputime); utime = cputime.utime; if (cputime_le(cval, utime)) { /* about to fire */ cval = jiffies_to_cputime(1); @@ -82,7 +82,7 @@ int do_getitimer(int which, struct itimerval *value) struct task_cputime times; cputime_t ptime; - thread_group_cputimer(tsk, ×); + thread_group_cputime(tsk, ×); ptime = cputime_add(times.utime, times.stime); if (cputime_le(cval, ptime)) { /* about to fire */ cval = jiffies_to_cputime(1); diff --git a/trunk/kernel/kexec.c b/trunk/kernel/kexec.c index 483899578259..8a6d7b08864e 100644 --- a/trunk/kernel/kexec.c +++ b/trunk/kernel/kexec.c @@ -1465,11 +1465,6 @@ int kernel_kexec(void) error = device_power_down(PMSG_FREEZE); if (error) goto Enable_irqs; - - /* Suspend system devices */ - error = sysdev_suspend(PMSG_FREEZE); - if (error) - goto Power_up_devices; } else #endif { @@ -1482,8 +1477,6 @@ int kernel_kexec(void) #ifdef CONFIG_KEXEC_JUMP if (kexec_image->preserve_context) { - sysdev_resume(); - Power_up_devices: device_power_up(PMSG_RESTORE); Enable_irqs: local_irq_enable(); diff --git a/trunk/kernel/posix-cpu-timers.c b/trunk/kernel/posix-cpu-timers.c index e976e505648d..fa07da94d7be 100644 --- a/trunk/kernel/posix-cpu-timers.c +++ b/trunk/kernel/posix-cpu-timers.c @@ -230,71 +230,6 @@ static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p, return 0; } -void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times) -{ - struct sighand_struct *sighand; - struct signal_struct *sig; - struct task_struct *t; - - *times = INIT_CPUTIME; - - rcu_read_lock(); - sighand = rcu_dereference(tsk->sighand); - if (!sighand) - goto out; - - sig = tsk->signal; - - t = tsk; - do { - times->utime = cputime_add(times->utime, t->utime); - times->stime = cputime_add(times->stime, t->stime); - times->sum_exec_runtime += t->se.sum_exec_runtime; - - t = next_thread(t); - } while (t != tsk); - - times->utime = cputime_add(times->utime, sig->utime); - times->stime = cputime_add(times->stime, sig->stime); - times->sum_exec_runtime += sig->sum_sched_runtime; -out: - rcu_read_unlock(); -} - -static void update_gt_cputime(struct task_cputime *a, struct task_cputime *b) -{ - if (cputime_gt(b->utime, a->utime)) - a->utime = b->utime; - - if (cputime_gt(b->stime, a->stime)) - a->stime = b->stime; - - if (b->sum_exec_runtime > a->sum_exec_runtime) - a->sum_exec_runtime = b->sum_exec_runtime; -} - -void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times) -{ - struct thread_group_cputimer *cputimer = &tsk->signal->cputimer; - struct task_cputime sum; - unsigned long flags; - - spin_lock_irqsave(&cputimer->lock, flags); - if (!cputimer->running) { - cputimer->running = 1; - /* - * The POSIX timer interface allows for absolute time expiry - * values through the TIMER_ABSTIME flag, therefore we have - * to synchronize the timer to the clock every time we start - * it. - */ - thread_group_cputime(tsk, &sum); - update_gt_cputime(&cputimer->cputime, &sum); - } - *times = cputimer->cputime; - spin_unlock_irqrestore(&cputimer->lock, flags); -} - /* * Sample a process (thread group) clock for the given group_leader task. * Must be called with tasklist_lock held for reading. @@ -522,7 +457,7 @@ void posix_cpu_timers_exit_group(struct task_struct *tsk) { struct task_cputime cputime; - thread_group_cputimer(tsk, &cputime); + thread_group_cputime(tsk, &cputime); cleanup_timers(tsk->signal->cpu_timers, cputime.utime, cputime.stime, cputime.sum_exec_runtime); } @@ -680,33 +615,6 @@ static void cpu_timer_fire(struct k_itimer *timer) } } -/* - * Sample a process (thread group) timer for the given group_leader task. - * Must be called with tasklist_lock held for reading. - */ -static int cpu_timer_sample_group(const clockid_t which_clock, - struct task_struct *p, - union cpu_time_count *cpu) -{ - struct task_cputime cputime; - - thread_group_cputimer(p, &cputime); - switch (CPUCLOCK_WHICH(which_clock)) { - default: - return -EINVAL; - case CPUCLOCK_PROF: - cpu->cpu = cputime_add(cputime.utime, cputime.stime); - break; - case CPUCLOCK_VIRT: - cpu->cpu = cputime.utime; - break; - case CPUCLOCK_SCHED: - cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p); - break; - } - return 0; -} - /* * Guts of sys_timer_settime for CPU timers. * This is called with the timer locked and interrupts disabled. @@ -768,7 +676,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags, if (CPUCLOCK_PERTHREAD(timer->it_clock)) { cpu_clock_sample(timer->it_clock, p, &val); } else { - cpu_timer_sample_group(timer->it_clock, p, &val); + cpu_clock_sample_group(timer->it_clock, p, &val); } if (old) { @@ -916,7 +824,7 @@ void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) read_unlock(&tasklist_lock); goto dead; } else { - cpu_timer_sample_group(timer->it_clock, p, &now); + cpu_clock_sample_group(timer->it_clock, p, &now); clear_dead = (unlikely(p->exit_state) && thread_group_empty(p)); } @@ -1056,19 +964,6 @@ static void check_thread_timers(struct task_struct *tsk, } } -static void stop_process_timers(struct task_struct *tsk) -{ - struct thread_group_cputimer *cputimer = &tsk->signal->cputimer; - unsigned long flags; - - if (!cputimer->running) - return; - - spin_lock_irqsave(&cputimer->lock, flags); - cputimer->running = 0; - spin_unlock_irqrestore(&cputimer->lock, flags); -} - /* * Check for any per-thread CPU timers that have fired and move them * off the tsk->*_timers list onto the firing list. Per-thread timers @@ -1092,15 +987,13 @@ static void check_process_timers(struct task_struct *tsk, sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY && list_empty(&timers[CPUCLOCK_VIRT]) && cputime_eq(sig->it_virt_expires, cputime_zero) && - list_empty(&timers[CPUCLOCK_SCHED])) { - stop_process_timers(tsk); + list_empty(&timers[CPUCLOCK_SCHED])) return; - } /* * Collect the current process totals. */ - thread_group_cputimer(tsk, &cputime); + thread_group_cputime(tsk, &cputime); utime = cputime.utime; ptime = cputime_add(utime, cputime.stime); sum_sched_runtime = cputime.sum_exec_runtime; @@ -1271,7 +1164,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer) clear_dead_task(timer, now); goto out_unlock; } - cpu_timer_sample_group(timer->it_clock, p, &now); + cpu_clock_sample_group(timer->it_clock, p, &now); bump_cpu_timer(timer, now); /* Leave the tasklist_lock locked for the call below. */ } @@ -1366,7 +1259,7 @@ static inline int fastpath_timer_check(struct task_struct *tsk) if (!task_cputime_zero(&sig->cputime_expires)) { struct task_cputime group_sample; - thread_group_cputimer(tsk, &group_sample); + thread_group_cputime(tsk, &group_sample); if (task_cputime_expired(&group_sample, &sig->cputime_expires)) return 1; } @@ -1448,7 +1341,7 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx, struct list_head *head; BUG_ON(clock_idx == CPUCLOCK_SCHED); - cpu_timer_sample_group(clock_idx, tsk, &now); + cpu_clock_sample_group(clock_idx, tsk, &now); if (oldval) { if (!cputime_eq(*oldval, cputime_zero)) { diff --git a/trunk/kernel/power/Makefile b/trunk/kernel/power/Makefile index 720ea4f781bd..d7a10167a25b 100644 --- a/trunk/kernel/power/Makefile +++ b/trunk/kernel/power/Makefile @@ -3,7 +3,7 @@ ifeq ($(CONFIG_PM_DEBUG),y) EXTRA_CFLAGS += -DDEBUG endif -obj-$(CONFIG_PM) += main.o +obj-y := main.o obj-$(CONFIG_PM_SLEEP) += console.o obj-$(CONFIG_FREEZER) += process.o obj-$(CONFIG_HIBERNATION) += swsusp.o disk.o snapshot.o swap.o user.o diff --git a/trunk/kernel/power/console.c b/trunk/kernel/power/console.c index a3961b205de7..b8628be2a465 100644 --- a/trunk/kernel/power/console.c +++ b/trunk/kernel/power/console.c @@ -78,12 +78,6 @@ void pm_restore_console(void) } set_console(orig_fgconsole); release_console_sem(); - - if (vt_waitactive(orig_fgconsole)) { - pr_debug("Resume: Can't switch VCs."); - return; - } - kmsg_redirect = orig_kmsg; } #endif diff --git a/trunk/kernel/power/disk.c b/trunk/kernel/power/disk.c index 4a4a206b1979..432ee575c9ee 100644 --- a/trunk/kernel/power/disk.c +++ b/trunk/kernel/power/disk.c @@ -227,12 +227,6 @@ static int create_image(int platform_mode) "aborting hibernation\n"); goto Enable_irqs; } - sysdev_suspend(PMSG_FREEZE); - if (error) { - printk(KERN_ERR "PM: Some devices failed to power down, " - "aborting hibernation\n"); - goto Power_up_devices; - } if (hibernation_test(TEST_CORE)) goto Power_up; @@ -248,11 +242,9 @@ static int create_image(int platform_mode) if (!in_suspend) platform_leave(platform_mode); Power_up: - sysdev_resume(); /* NOTE: device_power_up() is just a resume() for devices * that suspended with irqs off ... no overall powerup. */ - Power_up_devices: device_power_up(in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); Enable_irqs: @@ -343,7 +335,6 @@ static int resume_target_kernel(void) "aborting resume\n"); goto Enable_irqs; } - sysdev_suspend(PMSG_QUIESCE); /* We'll ignore saved state, but this gets preempt count (etc) right */ save_processor_state(); error = restore_highmem(); @@ -366,7 +357,6 @@ static int resume_target_kernel(void) swsusp_free(); restore_processor_state(); touch_softlockup_watchdog(); - sysdev_resume(); device_power_up(PMSG_RECOVER); Enable_irqs: local_irq_enable(); @@ -450,7 +440,6 @@ int hibernation_platform_enter(void) local_irq_disable(); error = device_power_down(PMSG_HIBERNATE); if (!error) { - sysdev_suspend(PMSG_HIBERNATE); hibernation_ops->enter(); /* We should never get here */ while (1); @@ -605,12 +594,6 @@ static int software_resume(void) int error; unsigned int flags; - /* - * If the user said "noresume".. bail out early. - */ - if (noresume) - return 0; - /* * name_to_dev_t() below takes a sysfs buffer mutex when sysfs * is configured into the kernel. Since the regular hibernate @@ -627,11 +610,6 @@ static int software_resume(void) mutex_unlock(&pm_mutex); return -ENOENT; } - /* - * Some device discovery might still be in progress; we need - * to wait for this to finish. - */ - wait_for_device_probe(); swsusp_resume_device = name_to_dev_t(resume_file); pr_debug("PM: Resume from partition %s\n", resume_file); } else { diff --git a/trunk/kernel/power/main.c b/trunk/kernel/power/main.c index c9632f841f64..239988873971 100644 --- a/trunk/kernel/power/main.c +++ b/trunk/kernel/power/main.c @@ -57,6 +57,16 @@ int pm_notifier_call_chain(unsigned long val) #ifdef CONFIG_PM_DEBUG int pm_test_level = TEST_NONE; +static int suspend_test(int level) +{ + if (pm_test_level == level) { + printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); + mdelay(5000); + return 1; + } + return 0; +} + static const char * const pm_tests[__TEST_AFTER_LAST] = { [TEST_NONE] = "none", [TEST_CORE] = "core", @@ -115,24 +125,14 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, } power_attr(pm_test); -#endif /* CONFIG_PM_DEBUG */ +#else /* !CONFIG_PM_DEBUG */ +static inline int suspend_test(int level) { return 0; } +#endif /* !CONFIG_PM_DEBUG */ #endif /* CONFIG_PM_SLEEP */ #ifdef CONFIG_SUSPEND -static int suspend_test(int level) -{ -#ifdef CONFIG_PM_DEBUG - if (pm_test_level == level) { - printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); - mdelay(5000); - return 1; - } -#endif /* !CONFIG_PM_DEBUG */ - return 0; -} - #ifdef CONFIG_PM_TEST_SUSPEND /* @@ -298,12 +298,8 @@ static int suspend_enter(suspend_state_t state) goto Done; } - error = sysdev_suspend(PMSG_SUSPEND); - if (!error) { - if (!suspend_test(TEST_CORE)) - error = suspend_ops->enter(state); - sysdev_resume(); - } + if (!suspend_test(TEST_CORE)) + error = suspend_ops->enter(state); device_power_up(PMSG_RESUME); Done: diff --git a/trunk/kernel/power/swap.c b/trunk/kernel/power/swap.c index 505f319e489c..6da14358537c 100644 --- a/trunk/kernel/power/swap.c +++ b/trunk/kernel/power/swap.c @@ -60,7 +60,6 @@ static struct block_device *resume_bdev; static int submit(int rw, pgoff_t page_off, struct page *page, struct bio **bio_chain) { - const int bio_rw = rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); struct bio *bio; bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1); @@ -81,7 +80,7 @@ static int submit(int rw, pgoff_t page_off, struct page *page, bio_get(bio); if (bio_chain == NULL) { - submit_bio(bio_rw, bio); + submit_bio(rw | (1 << BIO_RW_SYNC), bio); wait_on_page_locked(page); if (rw == READ) bio_set_pages_dirty(bio); @@ -91,7 +90,7 @@ static int submit(int rw, pgoff_t page_off, struct page *page, get_page(page); /* These pages are freed later */ bio->bi_private = *bio_chain; *bio_chain = bio; - submit_bio(bio_rw, bio); + submit_bio(rw | (1 << BIO_RW_SYNC), bio); } return 0; } diff --git a/trunk/kernel/power/user.c b/trunk/kernel/power/user.c index 6c85359364f2..005b93d839ba 100644 --- a/trunk/kernel/power/user.c +++ b/trunk/kernel/power/user.c @@ -95,15 +95,15 @@ static int snapshot_open(struct inode *inode, struct file *filp) data->swap = swsusp_resume_device ? swap_type_of(swsusp_resume_device, 0, NULL) : -1; data->mode = O_RDONLY; - error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); + error = pm_notifier_call_chain(PM_RESTORE_PREPARE); if (error) - pm_notifier_call_chain(PM_POST_HIBERNATION); + pm_notifier_call_chain(PM_POST_RESTORE); } else { data->swap = -1; data->mode = O_WRONLY; - error = pm_notifier_call_chain(PM_RESTORE_PREPARE); + error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); if (error) - pm_notifier_call_chain(PM_POST_RESTORE); + pm_notifier_call_chain(PM_POST_HIBERNATION); } if (error) atomic_inc(&snapshot_device_available); diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index e3602d0755b0..69188f226a93 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -73,6 +73,7 @@ EXPORT_SYMBOL(oops_in_progress); * driver system. */ static DECLARE_MUTEX(console_sem); +static DECLARE_MUTEX(secondary_console_sem); struct console *console_drivers; EXPORT_SYMBOL_GPL(console_drivers); @@ -890,14 +891,12 @@ void suspend_console(void) printk("Suspending console(s) (use no_console_suspend to debug)\n"); acquire_console_sem(); console_suspended = 1; - up(&console_sem); } void resume_console(void) { if (!console_suspend_enabled) return; - down(&console_sem); console_suspended = 0; release_console_sem(); } @@ -913,9 +912,11 @@ void resume_console(void) void acquire_console_sem(void) { BUG_ON(in_interrupt()); - down(&console_sem); - if (console_suspended) + if (console_suspended) { + down(&secondary_console_sem); return; + } + down(&console_sem); console_locked = 1; console_may_schedule = 1; } @@ -925,10 +926,6 @@ int try_acquire_console_sem(void) { if (down_trylock(&console_sem)) return -1; - if (console_suspended) { - up(&console_sem); - return -1; - } console_locked = 1; console_may_schedule = 0; return 0; @@ -982,7 +979,7 @@ void release_console_sem(void) unsigned wake_klogd = 0; if (console_suspended) { - up(&console_sem); + up(&secondary_console_sem); return; } diff --git a/trunk/kernel/profile.c b/trunk/kernel/profile.c index 7724e0409bae..784933acf5b8 100644 --- a/trunk/kernel/profile.c +++ b/trunk/kernel/profile.c @@ -114,15 +114,12 @@ int __ref profile_init(void) if (!slab_is_available()) { prof_buffer = alloc_bootmem(buffer_bytes); alloc_bootmem_cpumask_var(&prof_cpu_mask); - cpumask_copy(prof_cpu_mask, cpu_possible_mask); return 0; } if (!alloc_cpumask_var(&prof_cpu_mask, GFP_KERNEL)) return -ENOMEM; - cpumask_copy(prof_cpu_mask, cpu_possible_mask); - prof_buffer = kzalloc(buffer_bytes, GFP_KERNEL); if (prof_buffer) return 0; diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 410eec404133..242d0d47a70d 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -2266,6 +2266,16 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) if (!sched_feat(SYNC_WAKEUPS)) sync = 0; + if (!sync) { + if (current->se.avg_overlap < sysctl_sched_migration_cost && + p->se.avg_overlap < sysctl_sched_migration_cost) + sync = 1; + } else { + if (current->se.avg_overlap >= sysctl_sched_migration_cost || + p->se.avg_overlap >= sysctl_sched_migration_cost) + sync = 0; + } + #ifdef CONFIG_SMP if (sched_feat(LB_WAKEUP_UPDATE)) { struct sched_domain *sd; @@ -3880,24 +3890,19 @@ int select_nohz_load_balancer(int stop_tick) int cpu = smp_processor_id(); if (stop_tick) { + cpumask_set_cpu(cpu, nohz.cpu_mask); cpu_rq(cpu)->in_nohz_recently = 1; - if (!cpu_active(cpu)) { - if (atomic_read(&nohz.load_balancer) != cpu) - return 0; - - /* - * If we are going offline and still the leader, - * give up! - */ + /* + * If we are going offline and still the leader, give up! + */ + if (!cpu_active(cpu) && + atomic_read(&nohz.load_balancer) == cpu) { if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu) BUG(); - return 0; } - cpumask_set_cpu(cpu, nohz.cpu_mask); - /* time for ilb owner also to sleep */ if (cpumask_weight(nohz.cpu_mask) == num_online_cpus()) { if (atomic_read(&nohz.load_balancer) == cpu) @@ -4692,8 +4697,8 @@ EXPORT_SYMBOL(default_wake_function); * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns * zero in this (rare) case, and we handle it by continuing to scan the queue. */ -void __wake_up_common(wait_queue_head_t *q, unsigned int mode, - int nr_exclusive, int sync, void *key) +static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, + int nr_exclusive, int sync, void *key) { wait_queue_t *curr, *next; @@ -6944,26 +6949,20 @@ static void free_rootdomain(struct root_domain *rd) static void rq_attach_root(struct rq *rq, struct root_domain *rd) { - struct root_domain *old_rd = NULL; unsigned long flags; spin_lock_irqsave(&rq->lock, flags); if (rq->rd) { - old_rd = rq->rd; + struct root_domain *old_rd = rq->rd; if (cpumask_test_cpu(rq->cpu, old_rd->online)) set_rq_offline(rq); cpumask_clear_cpu(rq->cpu, old_rd->span); - /* - * If we dont want to free the old_rt yet then - * set old_rd to NULL to skip the freeing later - * in this function: - */ - if (!atomic_dec_and_test(&old_rd->refcount)) - old_rd = NULL; + if (atomic_dec_and_test(&old_rd->refcount)) + free_rootdomain(old_rd); } atomic_inc(&rd->refcount); @@ -6974,9 +6973,6 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd) set_rq_online(rq); spin_unlock_irqrestore(&rq->lock, flags); - - if (old_rd) - free_rootdomain(old_rd); } static int __init_refok init_rootdomain(struct root_domain *rd, bool bootmem) diff --git a/trunk/kernel/sched_fair.c b/trunk/kernel/sched_fair.c index 0566f2a03c42..a7e50ba185ac 100644 --- a/trunk/kernel/sched_fair.c +++ b/trunk/kernel/sched_fair.c @@ -1191,20 +1191,15 @@ wake_affine(struct sched_domain *this_sd, struct rq *this_rq, int idx, unsigned long load, unsigned long this_load, unsigned int imbalance) { - struct task_struct *curr = this_rq->curr; - struct task_group *tg; unsigned long tl = this_load; unsigned long tl_per_task; + struct task_group *tg; unsigned long weight; int balanced; if (!(this_sd->flags & SD_WAKE_AFFINE) || !sched_feat(AFFINE_WAKEUPS)) return 0; - if (sync && (curr->se.avg_overlap > sysctl_sched_migration_cost || - p->se.avg_overlap > sysctl_sched_migration_cost)) - sync = 0; - /* * If sync wakeup then subtract the (maximum possible) * effect of the currently running task from the load @@ -1431,9 +1426,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync) if (!sched_feat(WAKEUP_PREEMPT)) return; - if (sched_feat(WAKEUP_OVERLAP) && (sync || - (se->avg_overlap < sysctl_sched_migration_cost && - pse->avg_overlap < sysctl_sched_migration_cost))) { + if (sched_feat(WAKEUP_OVERLAP) && sync) { resched_task(curr); return; } diff --git a/trunk/kernel/sched_stats.h b/trunk/kernel/sched_stats.h index a8f93dd374e1..8ab0cef8ecab 100644 --- a/trunk/kernel/sched_stats.h +++ b/trunk/kernel/sched_stats.h @@ -296,21 +296,19 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next) static inline void account_group_user_time(struct task_struct *tsk, cputime_t cputime) { - struct thread_group_cputimer *cputimer; + struct task_cputime *times; + struct signal_struct *sig; /* tsk == current, ensure it is safe to use ->signal */ if (unlikely(tsk->exit_state)) return; - cputimer = &tsk->signal->cputimer; - - if (!cputimer->running) - return; + sig = tsk->signal; + times = &sig->cputime.totals; - spin_lock(&cputimer->lock); - cputimer->cputime.utime = - cputime_add(cputimer->cputime.utime, cputime); - spin_unlock(&cputimer->lock); + spin_lock(×->lock); + times->utime = cputime_add(times->utime, cputime); + spin_unlock(×->lock); } /** @@ -326,21 +324,19 @@ static inline void account_group_user_time(struct task_struct *tsk, static inline void account_group_system_time(struct task_struct *tsk, cputime_t cputime) { - struct thread_group_cputimer *cputimer; + struct task_cputime *times; + struct signal_struct *sig; /* tsk == current, ensure it is safe to use ->signal */ if (unlikely(tsk->exit_state)) return; - cputimer = &tsk->signal->cputimer; - - if (!cputimer->running) - return; + sig = tsk->signal; + times = &sig->cputime.totals; - spin_lock(&cputimer->lock); - cputimer->cputime.stime = - cputime_add(cputimer->cputime.stime, cputime); - spin_unlock(&cputimer->lock); + spin_lock(×->lock); + times->stime = cputime_add(times->stime, cputime); + spin_unlock(×->lock); } /** @@ -356,7 +352,7 @@ static inline void account_group_system_time(struct task_struct *tsk, static inline void account_group_exec_runtime(struct task_struct *tsk, unsigned long long ns) { - struct thread_group_cputimer *cputimer; + struct task_cputime *times; struct signal_struct *sig; sig = tsk->signal; @@ -365,12 +361,9 @@ static inline void account_group_exec_runtime(struct task_struct *tsk, if (unlikely(!sig)) return; - cputimer = &sig->cputimer; - - if (!cputimer->running) - return; + times = &sig->cputime.totals; - spin_lock(&cputimer->lock); - cputimer->cputime.sum_exec_runtime += ns; - spin_unlock(&cputimer->lock); + spin_lock(×->lock); + times->sum_exec_runtime += ns; + spin_unlock(×->lock); } diff --git a/trunk/kernel/seccomp.c b/trunk/kernel/seccomp.c index 57d4b13b631d..ad64fcb731f2 100644 --- a/trunk/kernel/seccomp.c +++ b/trunk/kernel/seccomp.c @@ -8,7 +8,6 @@ #include #include -#include /* #define SECCOMP_DEBUG 1 */ #define NR_SECCOMP_MODES 1 @@ -23,7 +22,7 @@ static int mode1_syscalls[] = { 0, /* null terminated */ }; -#ifdef CONFIG_COMPAT +#ifdef TIF_32BIT static int mode1_syscalls_32[] = { __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, 0, /* null terminated */ @@ -38,8 +37,8 @@ void __secure_computing(int this_syscall) switch (mode) { case 1: syscall = mode1_syscalls; -#ifdef CONFIG_COMPAT - if (is_compat_task()) +#ifdef TIF_32BIT + if (test_thread_flag(TIF_32BIT)) syscall = mode1_syscalls_32; #endif do { diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 2a74fe87c0dd..b6b36768b758 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -1367,6 +1367,7 @@ int do_notify_parent(struct task_struct *tsk, int sig) struct siginfo info; unsigned long flags; struct sighand_struct *psig; + struct task_cputime cputime; int ret = sig; BUG_ON(sig == -1); @@ -1396,10 +1397,9 @@ int do_notify_parent(struct task_struct *tsk, int sig) info.si_uid = __task_cred(tsk)->uid; rcu_read_unlock(); - info.si_utime = cputime_to_clock_t(cputime_add(tsk->utime, - tsk->signal->utime)); - info.si_stime = cputime_to_clock_t(cputime_add(tsk->stime, - tsk->signal->stime)); + thread_group_cputime(tsk, &cputime); + info.si_utime = cputime_to_jiffies(cputime.utime); + info.si_stime = cputime_to_jiffies(cputime.stime); info.si_status = tsk->exit_code & 0x7f; if (tsk->exit_code & 0x80) diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index f145c415bc16..e7dc0e10a485 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -1525,14 +1525,22 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) return -EINVAL; if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) return -EFAULT; - if (new_rlim.rlim_cur > new_rlim.rlim_max) - return -EINVAL; old_rlim = current->signal->rlim + resource; if ((new_rlim.rlim_max > old_rlim->rlim_max) && !capable(CAP_SYS_RESOURCE)) return -EPERM; - if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) - return -EPERM; + + if (resource == RLIMIT_NOFILE) { + if (new_rlim.rlim_max == RLIM_INFINITY) + new_rlim.rlim_max = sysctl_nr_open; + if (new_rlim.rlim_cur == RLIM_INFINITY) + new_rlim.rlim_cur = sysctl_nr_open; + if (new_rlim.rlim_max > sysctl_nr_open) + return -EPERM; + } + + if (new_rlim.rlim_cur > new_rlim.rlim_max) + return -EINVAL; retval = security_task_setrlimit(resource, &new_rlim); if (retval) diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index c5ef44ff850f..790f9d785663 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -101,7 +101,6 @@ static int two = 2; static int zero; static int one = 1; -static unsigned long one_ul = 1; static int one_hundred = 100; /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ @@ -975,7 +974,7 @@ static struct ctl_table vm_table[] = { .mode = 0644, .proc_handler = &dirty_background_bytes_handler, .strategy = &sysctl_intvec, - .extra1 = &one_ul, + .extra1 = &one, }, { .ctl_name = VM_DIRTY_RATIO, @@ -996,7 +995,7 @@ static struct ctl_table vm_table[] = { .mode = 0644, .proc_handler = &dirty_bytes_handler, .strategy = &sysctl_intvec, - .extra1 = &one_ul, + .extra1 = &one, }, { .procname = "dirty_writeback_centisecs", diff --git a/trunk/kernel/trace/Kconfig b/trunk/kernel/trace/Kconfig index 34e707e5ab87..e2a4ff6fc3a6 100644 --- a/trunk/kernel/trace/Kconfig +++ b/trunk/kernel/trace/Kconfig @@ -52,7 +52,6 @@ config FUNCTION_TRACER depends on HAVE_FUNCTION_TRACER depends on DEBUG_KERNEL select FRAME_POINTER - select KALLSYMS select TRACING select CONTEXT_SWITCH_TRACER help @@ -239,7 +238,6 @@ config STACK_TRACER depends on DEBUG_KERNEL select FUNCTION_TRACER select STACKTRACE - select KALLSYMS help This special tracer records the maximum stack footprint of the kernel and displays it in debugfs/tracing/stack_trace. @@ -304,27 +302,4 @@ config FTRACE_STARTUP_TEST functioning properly. It will do tests on all the configured tracers of ftrace. -config MMIOTRACE - bool "Memory mapped IO tracing" - depends on HAVE_MMIOTRACE_SUPPORT && DEBUG_KERNEL && PCI - select TRACING - help - Mmiotrace traces Memory Mapped I/O access and is meant for - debugging and reverse engineering. It is called from the ioremap - implementation and works via page faults. Tracing is disabled by - default and can be enabled at run-time. - - See Documentation/tracers/mmiotrace.txt. - If you are not helping to develop drivers, say N. - -config MMIOTRACE_TEST - tristate "Test module for mmiotrace" - depends on MMIOTRACE && m - help - This is a dumb module for testing mmiotrace. It is very dangerous - as it will write garbage to IO memory starting at a given address. - However, it should be safe to use on e.g. unused portion of VRAM. - - Say N, unless you absolutely know what you are doing. - endmenu diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index fdf913dfc7e8..7dcf6e9f2b04 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -1737,12 +1737,9 @@ static void clear_ftrace_pid(struct pid *pid) { struct task_struct *p; - rcu_read_lock(); do_each_pid_task(pid, PIDTYPE_PID, p) { clear_tsk_trace_trace(p); } while_each_pid_task(pid, PIDTYPE_PID, p); - rcu_read_unlock(); - put_pid(pid); } @@ -1750,11 +1747,9 @@ static void set_ftrace_pid(struct pid *pid) { struct task_struct *p; - rcu_read_lock(); do_each_pid_task(pid, PIDTYPE_PID, p) { set_tsk_trace_trace(p); } while_each_pid_task(pid, PIDTYPE_PID, p); - rcu_read_unlock(); } static void clear_ftrace_pid_task(struct pid **pid) @@ -2033,7 +2028,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) static int start_graph_tracing(void) { struct ftrace_ret_stack **ret_stack_list; - int ret, cpu; + int ret; ret_stack_list = kmalloc(FTRACE_RETSTACK_ALLOC_SIZE * sizeof(struct ftrace_ret_stack *), @@ -2042,10 +2037,6 @@ static int start_graph_tracing(void) if (!ret_stack_list) return -ENOMEM; - /* The cpu_boot init_task->ret_stack will never be freed */ - for_each_online_cpu(cpu) - ftrace_graph_init_task(idle_task(cpu)); - do { ret = alloc_retstack_tasklist(ret_stack_list); } while (ret == -EAGAIN); diff --git a/trunk/kernel/trace/trace_mmiotrace.c b/trunk/kernel/trace/trace_mmiotrace.c index 80e503ef6136..fffcb069f1dc 100644 --- a/trunk/kernel/trace/trace_mmiotrace.c +++ b/trunk/kernel/trace/trace_mmiotrace.c @@ -9,7 +9,6 @@ #include #include #include -#include #include "trace.h" @@ -20,7 +19,6 @@ struct header_iter { static struct trace_array *mmio_trace_array; static bool overrun_detected; static unsigned long prev_overruns; -static atomic_t dropped_count; static void mmio_reset_data(struct trace_array *tr) { @@ -123,11 +121,11 @@ static void mmio_close(struct trace_iterator *iter) static unsigned long count_overruns(struct trace_iterator *iter) { - unsigned long cnt = atomic_xchg(&dropped_count, 0); + unsigned long cnt = 0; unsigned long over = ring_buffer_overruns(iter->tr->buffer); if (over > prev_overruns) - cnt += over - prev_overruns; + cnt = over - prev_overruns; prev_overruns = over; return cnt; } @@ -312,10 +310,8 @@ static void __trace_mmiotrace_rw(struct trace_array *tr, event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry), &irq_flags); - if (!event) { - atomic_inc(&dropped_count); + if (!event) return; - } entry = ring_buffer_event_data(event); tracing_generic_entry_update(&entry->ent, 0, preempt_count()); entry->ent.type = TRACE_MMIO_RW; @@ -342,10 +338,8 @@ static void __trace_mmiotrace_map(struct trace_array *tr, event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry), &irq_flags); - if (!event) { - atomic_inc(&dropped_count); + if (!event) return; - } entry = ring_buffer_event_data(event); tracing_generic_entry_update(&entry->ent, 0, preempt_count()); entry->ent.type = TRACE_MMIO_MAP; diff --git a/trunk/kernel/trace/trace_selftest.c b/trunk/kernel/trace/trace_selftest.c index bc8e80a86bca..88c8eb70f54a 100644 --- a/trunk/kernel/trace/trace_selftest.c +++ b/trunk/kernel/trace/trace_selftest.c @@ -23,20 +23,10 @@ static int trace_test_buffer_cpu(struct trace_array *tr, int cpu) { struct ring_buffer_event *event; struct trace_entry *entry; - unsigned int loops = 0; while ((event = ring_buffer_consume(tr->buffer, cpu, NULL))) { entry = ring_buffer_event_data(event); - /* - * The ring buffer is a size of trace_buf_size, if - * we loop more than the size, there's something wrong - * with the ring buffer. - */ - if (loops++ > trace_buf_size) { - printk(KERN_CONT ".. bad ring buffer "); - goto failed; - } if (!trace_valid_entry(entry)) { printk(KERN_CONT ".. invalid entry %d ", entry->type); @@ -67,20 +57,11 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count) cnt = ring_buffer_entries(tr->buffer); - /* - * The trace_test_buffer_cpu runs a while loop to consume all data. - * If the calling tracer is broken, and is constantly filling - * the buffer, this will run forever, and hard lock the box. - * We disable the ring buffer while we do this test to prevent - * a hard lock up. - */ - tracing_off(); for_each_possible_cpu(cpu) { ret = trace_test_buffer_cpu(tr, cpu); if (ret) break; } - tracing_on(); __raw_spin_unlock(&ftrace_max_lock); local_irq_restore(flags); diff --git a/trunk/kernel/user.c b/trunk/kernel/user.c index 3551ac742395..477b6660f447 100644 --- a/trunk/kernel/user.c +++ b/trunk/kernel/user.c @@ -72,7 +72,6 @@ static void uid_hash_insert(struct user_struct *up, struct hlist_head *hashent) static void uid_hash_remove(struct user_struct *up) { hlist_del_init(&up->uidhash_node); - put_user_ns(up->user_ns); } static struct user_struct *uid_hash_find(uid_t uid, struct hlist_head *hashent) @@ -335,6 +334,7 @@ static void free_user(struct user_struct *up, unsigned long flags) atomic_inc(&up->__count); spin_unlock_irqrestore(&uidhash_lock, flags); + put_user_ns(up->user_ns); INIT_WORK(&up->work, remove_user_sysfs_dir); schedule_work(&up->work); } @@ -357,6 +357,7 @@ static void free_user(struct user_struct *up, unsigned long flags) sched_destroy_user(up); key_put(up->uid_keyring); key_put(up->session_keyring); + put_user_ns(up->user_ns); kmem_cache_free(uid_cachep, up); } diff --git a/trunk/kernel/user_namespace.c b/trunk/kernel/user_namespace.c index 076c7c8215b0..79084311ee57 100644 --- a/trunk/kernel/user_namespace.c +++ b/trunk/kernel/user_namespace.c @@ -60,25 +60,12 @@ int create_user_ns(struct cred *new) return 0; } -/* - * Deferred destructor for a user namespace. This is required because - * free_user_ns() may be called with uidhash_lock held, but we need to call - * back to free_uid() which will want to take the lock again. - */ -static void free_user_ns_work(struct work_struct *work) -{ - struct user_namespace *ns = - container_of(work, struct user_namespace, destroyer); - free_uid(ns->creator); - kfree(ns); -} - void free_user_ns(struct kref *kref) { - struct user_namespace *ns = - container_of(kref, struct user_namespace, kref); + struct user_namespace *ns; - INIT_WORK(&ns->destroyer, free_user_ns_work); - schedule_work(&ns->destroyer); + ns = container_of(kref, struct user_namespace, kref); + free_uid(ns->creator); + kfree(ns); } EXPORT_SYMBOL(free_user_ns); diff --git a/trunk/kernel/wait.c b/trunk/kernel/wait.c index 42a2dbc181c8..cd87131f2fc2 100644 --- a/trunk/kernel/wait.c +++ b/trunk/kernel/wait.c @@ -91,15 +91,6 @@ prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state) } EXPORT_SYMBOL(prepare_to_wait_exclusive); -/* - * finish_wait - clean up after waiting in a queue - * @q: waitqueue waited on - * @wait: wait descriptor - * - * Sets current thread back to running state and removes - * the wait descriptor from the given waitqueue if still - * queued. - */ void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) { unsigned long flags; @@ -126,39 +117,6 @@ void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) } EXPORT_SYMBOL(finish_wait); -/* - * abort_exclusive_wait - abort exclusive waiting in a queue - * @q: waitqueue waited on - * @wait: wait descriptor - * @state: runstate of the waiter to be woken - * @key: key to identify a wait bit queue or %NULL - * - * Sets current thread back to running state and removes - * the wait descriptor from the given waitqueue if still - * queued. - * - * Wakes up the next waiter if the caller is concurrently - * woken up through the queue. - * - * This prevents waiter starvation where an exclusive waiter - * aborts and is woken up concurrently and noone wakes up - * the next waiter. - */ -void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, - unsigned int mode, void *key) -{ - unsigned long flags; - - __set_current_state(TASK_RUNNING); - spin_lock_irqsave(&q->lock, flags); - if (!list_empty(&wait->task_list)) - list_del_init(&wait->task_list); - else if (waitqueue_active(q)) - __wake_up_common(q, mode, 1, 0, key); - spin_unlock_irqrestore(&q->lock, flags); -} -EXPORT_SYMBOL(abort_exclusive_wait); - int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) { int ret = default_wake_function(wait, mode, sync, key); @@ -219,20 +177,17 @@ int __sched __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, int (*action)(void *), unsigned mode) { - do { - int ret; + int ret = 0; + do { prepare_to_wait_exclusive(wq, &q->wait, mode); - if (!test_bit(q->key.bit_nr, q->key.flags)) - continue; - ret = action(q->key.flags); - if (!ret) - continue; - abort_exclusive_wait(wq, &q->wait, mode, &q->key); - return ret; + if (test_bit(q->key.bit_nr, q->key.flags)) { + if ((ret = (*action)(q->key.flags))) + break; + } } while (test_and_set_bit(q->key.bit_nr, q->key.flags)); finish_wait(wq, &q->wait); - return 0; + return ret; } EXPORT_SYMBOL(__wait_on_bit_lock); diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index 1bcf9cd4baa0..29044f500269 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -838,7 +838,7 @@ config FIREWIRE_OHCI_REMOTE_DMA If unsure, say N. -config BUILD_DOCSRC +menuconfig BUILD_DOCSRC bool "Build targets in Documentation/ tree" depends on HEADERS_CHECK help diff --git a/trunk/mm/fremap.c b/trunk/mm/fremap.c index b6ec85abbb39..736ba7f3306a 100644 --- a/trunk/mm/fremap.c +++ b/trunk/mm/fremap.c @@ -198,7 +198,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, flags &= MAP_NONBLOCK; get_file(file); addr = mmap_region(file, start, size, - flags, vma->vm_flags, pgoff); + flags, vma->vm_flags, pgoff, 1); fput(file); if (IS_ERR_VALUE(addr)) { err = addr; diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 107da3d809a8..618e98304080 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -2269,18 +2269,12 @@ void hugetlb_change_protection(struct vm_area_struct *vma, int hugetlb_reserve_pages(struct inode *inode, long from, long to, - struct vm_area_struct *vma, - int acctflag) + struct vm_area_struct *vma) { long ret, chg; struct hstate *h = hstate_inode(inode); - /* - * Only apply hugepage reservation if asked. At fault time, an - * attempt will be made for VM_NORESERVE to allocate a page - * and filesystem quota without using reserves - */ - if (acctflag & VM_NORESERVE) + if (vma && vma->vm_flags & VM_NORESERVE) return 0; /* @@ -2305,31 +2299,13 @@ int hugetlb_reserve_pages(struct inode *inode, if (chg < 0) return chg; - /* There must be enough filesystem quota for the mapping */ if (hugetlb_get_quota(inode->i_mapping, chg)) return -ENOSPC; - - /* - * Check enough hugepages are available for the reservation. - * Hand back the quota if there are not - */ ret = hugetlb_acct_memory(h, chg); if (ret < 0) { hugetlb_put_quota(inode->i_mapping, chg); return ret; } - - /* - * Account for the reservations made. Shared mappings record regions - * that have reservations as they are shared by multiple VMAs. - * When the last VMA disappears, the region map says how much - * the reservation was and the page cache tells how much of - * the reservation was consumed. Private mappings are per-VMA and - * only the consumed reservations are tracked. When the VMA - * disappears, the original reservation is the VMA size and the - * consumed reservations are stored in the map. Hence, nothing - * else has to be done for private mappings here - */ if (!vma || vma->vm_flags & VM_SHARED) region_add(&inode->i_mapping->private_list, from, to); return 0; diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index baa999e87cd2..22bfa7a47a0b 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -1999,7 +1999,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, * Don't let another task, with possibly unlocked vma, * keep the mlocked page. */ - if ((vma->vm_flags & VM_LOCKED) && old_page) { + if (vma->vm_flags & VM_LOCKED) { lock_page(old_page); /* for LRU manipulation */ clear_page_mlock(old_page); unlock_page(old_page); diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index a9eff3f092f6..2bb4e1d63520 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -1129,7 +1129,7 @@ int migrate_vmas(struct mm_struct *mm, const nodemask_t *to, struct vm_area_struct *vma; int err = 0; - for (vma = mm->mmap; vma && !err; vma = vma->vm_next) { + for(vma = mm->mmap; vma->vm_next && !err; vma = vma->vm_next) { if (vma->vm_ops && vma->vm_ops->migrate) { err = vma->vm_ops->migrate(vma, to, from, flags); if (err) diff --git a/trunk/mm/mlock.c b/trunk/mm/mlock.c index cbe9e0581b75..028ec482fdd4 100644 --- a/trunk/mm/mlock.c +++ b/trunk/mm/mlock.c @@ -311,10 +311,7 @@ long mlock_vma_pages_range(struct vm_area_struct *vma, is_vm_hugetlb_page(vma) || vma == get_gate_vma(current))) { - __mlock_vma_pages_range(vma, start, end, 1); - - /* Hide errors from mmap() and other callers */ - return 0; + return __mlock_vma_pages_range(vma, start, end, 1); } /* @@ -660,7 +657,7 @@ void *alloc_locked_buffer(size_t size) return buffer; } -void release_locked_buffer(void *buffer, size_t size) +void free_locked_buffer(void *buffer, size_t size) { unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT; @@ -670,11 +667,6 @@ void release_locked_buffer(void *buffer, size_t size) current->mm->locked_vm -= pgsz; up_write(¤t->mm->mmap_sem); -} - -void free_locked_buffer(void *buffer, size_t size) -{ - release_locked_buffer(buffer, size); kfree(buffer); } diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 00ced3ee49a8..214b6a258eeb 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -918,6 +918,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, struct inode *inode; unsigned int vm_flags; int error; + int accountable = 1; unsigned long reqprot = prot; /* @@ -1018,6 +1019,8 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, return -EPERM; vm_flags &= ~VM_MAYEXEC; } + if (is_file_hugepages(file)) + accountable = 0; if (!file->f_op || !file->f_op->mmap) return -ENODEV; @@ -1050,7 +1053,8 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, if (error) return error; - return mmap_region(file, addr, len, flags, vm_flags, pgoff); + return mmap_region(file, addr, len, flags, vm_flags, pgoff, + accountable); } EXPORT_SYMBOL(do_mmap_pgoff); @@ -1088,23 +1092,17 @@ int vma_wants_writenotify(struct vm_area_struct *vma) /* * We account for memory if it's a private writeable mapping, - * not hugepages and VM_NORESERVE wasn't set. + * and VM_NORESERVE wasn't set. */ -static inline int accountable_mapping(struct file *file, unsigned int vm_flags) +static inline int accountable_mapping(unsigned int vm_flags) { - /* - * hugetlb has its own accounting separate from the core VM - * VM_HUGETLB may not be set yet so we cannot check for that flag. - */ - if (file && is_file_hugepages(file)) - return 0; - return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE; } unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long len, unsigned long flags, - unsigned int vm_flags, unsigned long pgoff) + unsigned int vm_flags, unsigned long pgoff, + int accountable) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma, *prev; @@ -1130,22 +1128,18 @@ unsigned long mmap_region(struct file *file, unsigned long addr, /* * Set 'VM_NORESERVE' if we should not account for the - * memory use of this mapping. + * memory use of this mapping. We only honor MAP_NORESERVE + * if we're allowed to overcommit memory. */ - if ((flags & MAP_NORESERVE)) { - /* We honor MAP_NORESERVE if allowed to overcommit */ - if (sysctl_overcommit_memory != OVERCOMMIT_NEVER) - vm_flags |= VM_NORESERVE; - - /* hugetlb applies strict overcommit unless MAP_NORESERVE */ - if (file && is_file_hugepages(file)) - vm_flags |= VM_NORESERVE; - } + if ((flags & MAP_NORESERVE) && sysctl_overcommit_memory != OVERCOMMIT_NEVER) + vm_flags |= VM_NORESERVE; + if (!accountable) + vm_flags |= VM_NORESERVE; /* * Private writable mapping: check memory availability */ - if (accountable_mapping(file, vm_flags)) { + if (accountable_mapping(vm_flags)) { charged = len >> PAGE_SHIFT; if (security_vm_enough_memory(charged)) return -ENOMEM; @@ -2084,8 +2078,12 @@ void exit_mmap(struct mm_struct *mm) unsigned long end; /* mm's last user has gone, and its about to be pulled down */ + arch_exit_mmap(mm); mmu_notifier_release(mm); + if (!mm->mmap) /* Can happen if dup_mmap() received an OOM */ + return; + if (mm->locked_vm) { vma = mm->mmap; while (vma) { @@ -2094,13 +2092,7 @@ void exit_mmap(struct mm_struct *mm) vma = vma->vm_next; } } - - arch_exit_mmap(mm); - vma = mm->mmap; - if (!vma) /* Can happen if dup_mmap() received an OOM */ - return; - lru_add_drain(); flush_cache_mm(mm); tlb = tlb_gather_mmu(mm, 1); diff --git a/trunk/mm/mprotect.c b/trunk/mm/mprotect.c index 258197b76fb4..abe2694e13f4 100644 --- a/trunk/mm/mprotect.c +++ b/trunk/mm/mprotect.c @@ -151,11 +151,10 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, /* * If we make a private mapping writable we increase our commit; * but (without finer accounting) cannot reduce our commit if we - * make it unwritable again. hugetlb mapping were accounted for - * even if read-only so there is no need to account for them here + * make it unwritable again. */ if (newflags & VM_WRITE) { - if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB| + if (!(oldflags & (VM_ACCOUNT|VM_WRITE| VM_SHARED|VM_NORESERVE))) { charged = nrpages; if (security_vm_enough_memory(charged)) diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index 74dc57c74349..b493db7841dc 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -209,7 +209,7 @@ int dirty_bytes_handler(struct ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { - unsigned long old_bytes = vm_dirty_bytes; + int old_bytes = vm_dirty_bytes; int ret; ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); @@ -240,7 +240,7 @@ void bdi_writeout_inc(struct backing_dev_info *bdi) } EXPORT_SYMBOL_GPL(bdi_writeout_inc); -void task_dirty_inc(struct task_struct *tsk) +static inline void task_dirty_inc(struct task_struct *tsk) { prop_inc_single(&vm_dirties, &tsk->dirties); } @@ -1051,25 +1051,13 @@ int write_cache_pages(struct address_space *mapping, } } - if (nr_to_write > 0) { - nr_to_write--; - if (nr_to_write == 0 && - wbc->sync_mode == WB_SYNC_NONE) { - /* - * We stop writing back only if we are - * not doing integrity sync. In case of - * integrity sync we have to keep going - * because someone may be concurrently - * dirtying pages, and we might have - * synced a lot of newly appeared dirty - * pages, but have not synced all of the - * old dirty pages. - */ + if (wbc->sync_mode == WB_SYNC_NONE) { + wbc->nr_to_write--; + if (wbc->nr_to_write <= 0) { done = 1; break; } } - if (wbc->nonblocking && bdi_write_congested(bdi)) { wbc->encountered_congestion = 1; done = 1; @@ -1079,7 +1067,7 @@ int write_cache_pages(struct address_space *mapping, pagevec_release(&pvec); cond_resched(); } - if (!cycled && !done) { + if (!cycled) { /* * range_cyclic: * We hit the last page and there is more work to be done: wrap @@ -1230,7 +1218,6 @@ int __set_page_dirty_nobuffers(struct page *page) __inc_zone_page_state(page, NR_FILE_DIRTY); __inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); - task_dirty_inc(current); task_io_account_write(PAGE_CACHE_SIZE); } radix_tree_tag_set(&mapping->page_tree, @@ -1263,7 +1250,7 @@ EXPORT_SYMBOL(redirty_page_for_writepage); * If the mapping doesn't provide a set_page_dirty a_op, then * just fall through and assume that it wants buffer_heads. */ -int set_page_dirty(struct page *page) +static int __set_page_dirty(struct page *page) { struct address_space *mapping = page_mapping(page); @@ -1281,6 +1268,14 @@ int set_page_dirty(struct page *page) } return 0; } + +int set_page_dirty(struct page *page) +{ + int ret = __set_page_dirty(page); + if (ret) + task_dirty_inc(current); + return ret; +} EXPORT_SYMBOL(set_page_dirty); /* diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 5c44ed49ca93..5675b3073854 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -2989,7 +2989,7 @@ static int __meminit next_active_region_index_in_nid(int index, int nid) * was used and there are no special requirements, this is a convenient * alternative */ -int __meminit __early_pfn_to_nid(unsigned long pfn) +int __meminit early_pfn_to_nid(unsigned long pfn) { int i; @@ -3000,33 +3000,10 @@ int __meminit __early_pfn_to_nid(unsigned long pfn) if (start_pfn <= pfn && pfn < end_pfn) return early_node_map[i].nid; } - /* This is a memory hole */ - return -1; -} -#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ - -int __meminit early_pfn_to_nid(unsigned long pfn) -{ - int nid; - nid = __early_pfn_to_nid(pfn); - if (nid >= 0) - return nid; - /* just returns 0 */ return 0; } - -#ifdef CONFIG_NODES_SPAN_OTHER_NODES -bool __meminit early_pfn_in_nid(unsigned long pfn, int node) -{ - int nid; - - nid = __early_pfn_to_nid(pfn); - if (nid >= 0 && nid != node) - return false; - return true; -} -#endif +#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ /* Basic iterator support to walk early_node_map[] */ #define for_each_active_range_index_in_nid(i, nid) \ diff --git a/trunk/mm/page_cgroup.c b/trunk/mm/page_cgroup.c index ceecfbb143fa..7006a11350c8 100644 --- a/trunk/mm/page_cgroup.c +++ b/trunk/mm/page_cgroup.c @@ -114,8 +114,7 @@ static int __init_refok init_section_page_cgroup(unsigned long pfn) nid = page_to_nid(pfn_to_page(pfn)); table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION; if (slab_is_available()) { - base = kmalloc_node(table_size, - GFP_KERNEL | __GFP_NOWARN, nid); + base = kmalloc_node(table_size, GFP_KERNEL, nid); if (!base) base = vmalloc_node(table_size, nid); } else { diff --git a/trunk/mm/page_io.c b/trunk/mm/page_io.c index 3023c475e041..dc6ce0afbded 100644 --- a/trunk/mm/page_io.c +++ b/trunk/mm/page_io.c @@ -111,7 +111,7 @@ int swap_writepage(struct page *page, struct writeback_control *wbc) goto out; } if (wbc->sync_mode == WB_SYNC_ALL) - rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); + rw |= (1 << BIO_RW_SYNC); count_vm_event(PSWPOUT); set_page_writeback(page); unlock_page(page); diff --git a/trunk/mm/rmap.c b/trunk/mm/rmap.c index 16521664010d..ac4af8cffbf9 100644 --- a/trunk/mm/rmap.c +++ b/trunk/mm/rmap.c @@ -1072,8 +1072,7 @@ static int try_to_unmap_file(struct page *page, int unlock, int migration) spin_lock(&mapping->i_mmap_lock); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { if (MLOCK_PAGES && unlikely(unlock)) { - if (!((vma->vm_flags & VM_LOCKED) && - page_mapped_in_vma(page, vma))) + if (!(vma->vm_flags & VM_LOCKED)) continue; /* must visit all vmas */ ret = SWAP_MLOCK; } else { diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index 4103a239ce84..19d566ccdeea 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -169,13 +169,13 @@ static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb) */ static inline int shmem_acct_size(unsigned long flags, loff_t size) { - return (flags & VM_NORESERVE) ? - 0 : security_vm_enough_memory_kern(VM_ACCT(size)); + return (flags & VM_ACCOUNT) ? + security_vm_enough_memory_kern(VM_ACCT(size)) : 0; } static inline void shmem_unacct_size(unsigned long flags, loff_t size) { - if (!(flags & VM_NORESERVE)) + if (flags & VM_ACCOUNT) vm_unacct_memory(VM_ACCT(size)); } @@ -187,13 +187,13 @@ static inline void shmem_unacct_size(unsigned long flags, loff_t size) */ static inline int shmem_acct_block(unsigned long flags) { - return (flags & VM_NORESERVE) ? - security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)) : 0; + return (flags & VM_ACCOUNT) ? + 0 : security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)); } static inline void shmem_unacct_blocks(unsigned long flags, long pages) { - if (flags & VM_NORESERVE) + if (!(flags & VM_ACCOUNT)) vm_unacct_memory(pages * VM_ACCT(PAGE_CACHE_SIZE)); } @@ -1515,8 +1515,8 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static struct inode *shmem_get_inode(struct super_block *sb, int mode, - dev_t dev, unsigned long flags) +static struct inode * +shmem_get_inode(struct super_block *sb, int mode, dev_t dev) { struct inode *inode; struct shmem_inode_info *info; @@ -1537,7 +1537,6 @@ static struct inode *shmem_get_inode(struct super_block *sb, int mode, info = SHMEM_I(inode); memset(info, 0, (char *)inode - (char *)info); spin_lock_init(&info->lock); - info->flags = flags & VM_NORESERVE; INIT_LIST_HEAD(&info->swaplist); switch (mode & S_IFMT) { @@ -1780,10 +1779,9 @@ static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) static int shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { - struct inode *inode; + struct inode *inode = shmem_get_inode(dir->i_sb, mode, dev); int error = -ENOSPC; - inode = shmem_get_inode(dir->i_sb, mode, dev, VM_NORESERVE); if (inode) { error = security_inode_init_security(inode, dir, NULL, NULL, NULL); @@ -1922,7 +1920,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s if (len > PAGE_CACHE_SIZE) return -ENAMETOOLONG; - inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE); + inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0); if (!inode) return -ENOSPC; @@ -2334,7 +2332,7 @@ static int shmem_fill_super(struct super_block *sb, sb->s_flags |= MS_POSIXACL; #endif - inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE); + inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0); if (!inode) goto failed; inode->i_uid = sbinfo->uid; @@ -2576,12 +2574,12 @@ int shmem_unuse(swp_entry_t entry, struct page *page) return 0; } -#define shmem_vm_ops generic_file_vm_ops -#define shmem_file_operations ramfs_file_operations -#define shmem_get_inode(sb, mode, dev, flags) ramfs_get_inode(sb, mode, dev) -#define shmem_acct_size(flags, size) 0 -#define shmem_unacct_size(flags, size) do {} while (0) -#define SHMEM_MAX_BYTES LLONG_MAX +#define shmem_file_operations ramfs_file_operations +#define shmem_vm_ops generic_file_vm_ops +#define shmem_get_inode ramfs_get_inode +#define shmem_acct_size(a, b) 0 +#define shmem_unacct_size(a, b) do {} while (0) +#define SHMEM_MAX_BYTES LLONG_MAX #endif /* CONFIG_SHMEM */ @@ -2591,7 +2589,7 @@ int shmem_unuse(swp_entry_t entry, struct page *page) * shmem_file_setup - get an unlinked file living in tmpfs * @name: name for dentry (to be seen in /proc//maps * @size: size to be set for the file - * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size + * @flags: vm_flags */ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) { @@ -2625,10 +2623,13 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) goto put_dentry; error = -ENOSPC; - inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags); + inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0); if (!inode) goto close_file; +#ifdef CONFIG_SHMEM + SHMEM_I(inode)->flags = (flags & VM_NORESERVE) ? 0 : VM_ACCOUNT; +#endif d_instantiate(dentry, inode); inode->i_size = size; inode->i_nlink = 0; /* It is unlinked */ diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 4d00855629c4..ddc41f337d58 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -4457,4 +4457,3 @@ size_t ksize(const void *objp) return obj_size(virt_to_cache(objp)); } -EXPORT_SYMBOL(ksize); diff --git a/trunk/mm/slob.c b/trunk/mm/slob.c index 52bc8a2bd9ef..bf7e8fc3aed8 100644 --- a/trunk/mm/slob.c +++ b/trunk/mm/slob.c @@ -521,7 +521,6 @@ size_t ksize(const void *block) } else return sp->page.private; } -EXPORT_SYMBOL(ksize); struct kmem_cache { unsigned int size, align; diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index 0280eee6cf37..bdc9abb08a23 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -2736,7 +2736,6 @@ size_t ksize(const void *object) */ return s->size; } -EXPORT_SYMBOL(ksize); void kfree(const void *x) { diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index 312fafe0ab6e..7e6304dfafab 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -635,7 +635,7 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p) if (!bdev) { if (bdev_p) - *bdev_p = bdget(sis->bdev->bd_dev); + *bdev_p = sis->bdev; spin_unlock(&swap_lock); return i; @@ -647,7 +647,7 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p) struct swap_extent, list); if (se->start_block == offset) { if (bdev_p) - *bdev_p = bdget(sis->bdev->bd_dev); + *bdev_p = sis->bdev; spin_unlock(&swap_lock); bdput(bdev); diff --git a/trunk/mm/util.c b/trunk/mm/util.c index 37eaccdf3054..cb00b748ce47 100644 --- a/trunk/mm/util.c +++ b/trunk/mm/util.c @@ -129,26 +129,6 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags) } EXPORT_SYMBOL(krealloc); -/** - * kzfree - like kfree but zero memory - * @p: object to free memory of - * - * The memory of the object @p points to is zeroed before freed. - * If @p is %NULL, kzfree() does nothing. - */ -void kzfree(const void *p) -{ - size_t ks; - void *mem = (void *)p; - - if (unlikely(ZERO_OR_NULL_PTR(mem))) - return; - ks = ksize(mem); - memset(mem, 0, ks); - kfree(mem); -} -EXPORT_SYMBOL(kzfree); - /* * strndup_user - duplicate an existing string from user space * @s: The string to duplicate diff --git a/trunk/mm/vmalloc.c b/trunk/mm/vmalloc.c index 520a75980269..75f49d312e8c 100644 --- a/trunk/mm/vmalloc.c +++ b/trunk/mm/vmalloc.c @@ -323,7 +323,6 @@ static struct vmap_area *alloc_vmap_area(unsigned long size, unsigned long addr; int purged = 0; - BUG_ON(!size); BUG_ON(size & ~PAGE_MASK); va = kmalloc_node(sizeof(struct vmap_area), @@ -335,9 +334,6 @@ static struct vmap_area *alloc_vmap_area(unsigned long size, addr = ALIGN(vstart, align); spin_lock(&vmap_area_lock); - if (addr + size - 1 < addr) - goto overflow; - /* XXX: could have a last_hole cache */ n = vmap_area_root.rb_node; if (n) { @@ -369,8 +365,6 @@ static struct vmap_area *alloc_vmap_area(unsigned long size, while (addr + size > first->va_start && addr + size <= vend) { addr = ALIGN(first->va_end + PAGE_SIZE, align); - if (addr + size - 1 < addr) - goto overflow; n = rb_next(&first->rb_node); if (n) @@ -381,7 +375,6 @@ static struct vmap_area *alloc_vmap_area(unsigned long size, } found: if (addr + size > vend) { -overflow: spin_unlock(&vmap_area_lock); if (!purged) { purge_vmap_area_lazy(); @@ -505,7 +498,6 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, static DEFINE_SPINLOCK(purge_lock); LIST_HEAD(valist); struct vmap_area *va; - struct vmap_area *n_va; int nr = 0; /* @@ -545,7 +537,7 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, if (nr) { spin_lock(&vmap_area_lock); - list_for_each_entry_safe(va, n_va, &valist, purge_list) + list_for_each_entry(va, &valist, purge_list) __free_vmap_area(va); spin_unlock(&vmap_area_lock); } @@ -1020,8 +1012,6 @@ void __init vmalloc_init(void) void unmap_kernel_range(unsigned long addr, unsigned long size) { unsigned long end = addr + size; - - flush_cache_vunmap(addr, end); vunmap_page_range(addr, end); flush_tlb_kernel_range(addr, end); } @@ -1116,14 +1106,6 @@ struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, } EXPORT_SYMBOL_GPL(__get_vm_area); -struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags, - unsigned long start, unsigned long end, - void *caller) -{ - return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL, - caller); -} - /** * get_vm_area - reserve a contiguous kernel virtual area * @size: size of the area diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 6177e3bcd66b..9a27c44aa327 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -2057,31 +2057,31 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int prio, int pass, struct scan_control *sc) { struct zone *zone; - unsigned long ret = 0; + unsigned long nr_to_scan, ret = 0; + enum lru_list l; for_each_zone(zone) { - enum lru_list l; if (!populated_zone(zone)) continue; + if (zone_is_all_unreclaimable(zone) && prio != DEF_PRIORITY) continue; for_each_evictable_lru(l) { - enum zone_stat_item ls = NR_LRU_BASE + l; - unsigned long lru_pages = zone_page_state(zone, ls); - /* For pass = 0, we don't shrink the active list */ - if (pass == 0 && (l == LRU_ACTIVE_ANON || - l == LRU_ACTIVE_FILE)) + if (pass == 0 && + (l == LRU_ACTIVE || l == LRU_ACTIVE_FILE)) continue; - zone->lru[l].nr_scan += (lru_pages >> prio) + 1; + zone->lru[l].nr_scan += + (zone_page_state(zone, NR_LRU_BASE + l) + >> prio) + 1; if (zone->lru[l].nr_scan >= nr_pages || pass > 3) { - unsigned long nr_to_scan; - zone->lru[l].nr_scan = 0; - nr_to_scan = min(nr_pages, lru_pages); + nr_to_scan = min(nr_pages, + zone_page_state(zone, + NR_LRU_BASE + l)); ret += shrink_list(l, nr_to_scan, zone, sc, prio); if (ret >= nr_pages) @@ -2089,6 +2089,7 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int prio, } } } + return ret; } @@ -2111,6 +2112,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages) .may_swap = 0, .swap_cluster_max = nr_pages, .may_writepage = 1, + .swappiness = vm_swappiness, .isolate_pages = isolate_pages_global, }; @@ -2144,8 +2146,10 @@ unsigned long shrink_all_memory(unsigned long nr_pages) int prio; /* Force reclaiming mapped pages in the passes #3 and #4 */ - if (pass > 2) + if (pass > 2) { sc.may_swap = 1; + sc.swappiness = 100; + } for (prio = DEF_PRIORITY; prio >= 0; prio--) { unsigned long nr_to_scan = nr_pages - ret; diff --git a/trunk/net/ipv4/cipso_ipv4.c b/trunk/net/ipv4/cipso_ipv4.c index 7bc992976d29..6bb2635b5ded 100644 --- a/trunk/net/ipv4/cipso_ipv4.c +++ b/trunk/net/ipv4/cipso_ipv4.c @@ -3,16 +3,11 @@ * * This is an implementation of the CIPSO 2.2 protocol as specified in * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in - * FIPS-188. While CIPSO never became a full IETF RFC standard many vendors + * FIPS-188, copies of both documents can be found in the Documentation + * directory. While CIPSO never became a full IETF RFC standard many vendors * have chosen to adopt the protocol and over the years it has become a * de-facto standard for labeled networking. * - * The CIPSO draft specification can be found in the kernel's Documentation - * directory as well as the following URL: - * http://netlabel.sourceforge.net/files/draft-ietf-cipso-ipsecurity-01.txt - * The FIPS-188 specification can be found at the following URL: - * http://www.itl.nist.gov/fipspubs/fip188.htm - * * Author: Paul Moore * */ diff --git a/trunk/scripts/bootgraph.pl b/trunk/scripts/bootgraph.pl index 12caa822a232..b0246307aac4 100644 --- a/trunk/scripts/bootgraph.pl +++ b/trunk/scripts/bootgraph.pl @@ -51,7 +51,7 @@ while (<>) { my $line = $_; - if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_\.]+)\+/) { + if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_]+)\+/) { my $func = $2; if ($done == 0) { $start{$func} = $1; @@ -87,7 +87,7 @@ $count = $count + 1; } - if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_\.]+)\+.*returned/) { + if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_]+)\+.*returned/) { if ($done == 0) { $end{$2} = $1; $maxtime = $1; diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index 2d5ece798c4c..45eb0ae98eba 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -10,7 +10,7 @@ my $P = $0; $P =~ s@.*/@@g; -my $V = '0.28'; +my $V = '0.27'; use Getopt::Long qw(:config no_auto_abbrev); @@ -110,8 +110,7 @@ __iomem| __must_check| __init_refok| - __kprobes| - __ref + __kprobes }x; our $Attribute = qr{ const| @@ -1241,8 +1240,7 @@ sub process { $realfile =~ s@^([^/]*)/@@; $p1_prefix = $1; - if (!$file && $tree && $p1_prefix ne '' && - -e "$root/$p1_prefix") { + if ($tree && $p1_prefix ne '' && -e "$root/$p1_prefix") { WARN("patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); } @@ -1585,9 +1583,9 @@ sub process { } # TEST: allow direct testing of the attribute matcher. if ($dbg_attr) { - if ($line =~ /^.\s*$Modifier\s*$/) { + if ($line =~ /^.\s*$Attribute\s*$/) { ERROR("TEST: is attr\n" . $herecurr); - } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { + } elsif ($dbg_attr > 1 && $line =~ /^.+($Attribute)/) { ERROR("TEST: is not attr ($1 is)\n". $herecurr); } next; @@ -1659,7 +1657,7 @@ sub process { # * goes on variable not on type # (char*[ const]) - if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) { + if ($line =~ m{\($NonptrType(\s*\*[\s\*]*(?:$Modifier\s*)*)\)}) { my ($from, $to) = ($1, $1); # Should start with a space. @@ -1674,7 +1672,7 @@ sub process { if ($from ne $to) { ERROR("\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); } - } elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) { + } elsif ($line =~ m{\b$NonptrType(\s*\*[\s\*]*(?:$Modifier\s*)?)($Ident)}) { my ($from, $to, $ident) = ($1, $1, $2); # Should start with a space. @@ -1687,8 +1685,8 @@ sub process { # Modifiers should have spaces. $to =~ s/(\b$Modifier$)/$1 /; - #print "from<$from> to<$to> ident<$ident>\n"; - if ($from ne $to && $ident !~ /^$Modifier$/) { + #print "from<$from> to<$to>\n"; + if ($from ne $to) { ERROR("\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr); } } @@ -1887,11 +1885,11 @@ sub process { if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { ERROR("space required before that '$op' $at\n" . $hereptr); } - if ($op eq '*' && $cc =~/\s*$Modifier\b/) { + if ($op eq '*' && $cc =~/\s*const\b/) { # A unary '*' may be const } elsif ($ctx =~ /.xW/) { - ERROR("Aspace prohibited after that '$op' $at\n" . $hereptr); + ERROR("space prohibited after that '$op' $at\n" . $hereptr); } # unary ++ and unary -- are allowed no space on one side. @@ -2562,7 +2560,7 @@ sub process { if ($line =~ /\bin_atomic\s*\(/) { if ($realfile =~ m@^drivers/@) { ERROR("do not use in_atomic in drivers\n" . $herecurr); - } elsif ($realfile !~ m@^kernel/@) { + } else { WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); } } diff --git a/trunk/scripts/kernel-doc b/trunk/scripts/kernel-doc index 0f11870116dc..8bb83a100edb 100755 --- a/trunk/scripts/kernel-doc +++ b/trunk/scripts/kernel-doc @@ -1827,40 +1827,6 @@ sub reset_state { $state = 0; } -sub syscall_munge() { - my $void = 0; - - $prototype =~ s@[\r\n\t]+@ @gos; # strip newlines/CR's/tabs -## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { - if ($prototype =~ m/SYSCALL_DEFINE0/) { - $void = 1; -## $prototype = "long sys_$1(void)"; - } - - $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name - if ($prototype =~ m/long (sys_.*?),/) { - $prototype =~ s/,/\(/; - } elsif ($void) { - $prototype =~ s/\)/\(void\)/; - } - - # now delete all of the odd-number commas in $prototype - # so that arg types & arg names don't have a comma between them - my $count = 0; - my $len = length($prototype); - if ($void) { - $len = 0; # skip the for-loop - } - for (my $ix = 0; $ix < $len; $ix++) { - if (substr($prototype, $ix, 1) eq ',') { - $count++; - if ($count % 2 == 1) { - substr($prototype, $ix, 1) = ' '; - } - } - } -} - sub process_state3_function($$) { my $x = shift; my $file = shift; @@ -1873,15 +1839,11 @@ sub process_state3_function($$) { elsif ($x =~ /([^\{]*)/) { $prototype .= $1; } - if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) { $prototype =~ s@/\*.*?\*/@@gos; # strip comments. $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. $prototype =~ s@^\s+@@gos; # strip leading spaces - if ($prototype =~ /SYSCALL_DEFINE/) { - syscall_munge(); - } - dump_function($prototype, $file); + dump_function($prototype,$file); reset_state(); } } diff --git a/trunk/scripts/markup_oops.pl b/trunk/scripts/markup_oops.pl index 528492bcba5b..d40449cafa84 100644 --- a/trunk/scripts/markup_oops.pl +++ b/trunk/scripts/markup_oops.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w use File::Basename; @@ -29,151 +29,27 @@ my $target = "0"; my $function; my $module = ""; -my $func_offset = 0; +my $func_offset; my $vmaoffset = 0; -my %regs; - - -sub parse_x86_regs -{ - my ($line) = @_; - if ($line =~ /EAX: ([0-9a-f]+) EBX: ([0-9a-f]+) ECX: ([0-9a-f]+) EDX: ([0-9a-f]+)/) { - $regs{"%eax"} = $1; - $regs{"%ebx"} = $2; - $regs{"%ecx"} = $3; - $regs{"%edx"} = $4; - } - if ($line =~ /ESI: ([0-9a-f]+) EDI: ([0-9a-f]+) EBP: ([0-9a-f]+) ESP: ([0-9a-f]+)/) { - $regs{"%esi"} = $1; - $regs{"%edi"} = $2; - $regs{"%esp"} = $4; - } - if ($line =~ /RAX: ([0-9a-f]+) RBX: ([0-9a-f]+) RCX: ([0-9a-f]+)/) { - $regs{"%eax"} = $1; - $regs{"%ebx"} = $2; - $regs{"%ecx"} = $3; - } - if ($line =~ /RDX: ([0-9a-f]+) RSI: ([0-9a-f]+) RDI: ([0-9a-f]+)/) { - $regs{"%edx"} = $1; - $regs{"%esi"} = $2; - $regs{"%edi"} = $3; - } - if ($line =~ /RBP: ([0-9a-f]+) R08: ([0-9a-f]+) R09: ([0-9a-f]+)/) { - $regs{"%r08"} = $2; - $regs{"%r09"} = $3; - } - if ($line =~ /R10: ([0-9a-f]+) R11: ([0-9a-f]+) R12: ([0-9a-f]+)/) { - $regs{"%r10"} = $1; - $regs{"%r11"} = $2; - $regs{"%r12"} = $3; - } - if ($line =~ /R13: ([0-9a-f]+) R14: ([0-9a-f]+) R15: ([0-9a-f]+)/) { - $regs{"%r13"} = $1; - $regs{"%r14"} = $2; - $regs{"%r15"} = $3; - } -} - -sub reg_name -{ - my ($reg) = @_; - $reg =~ s/r(.)x/e\1x/; - $reg =~ s/r(.)i/e\1i/; - $reg =~ s/r(.)p/e\1p/; - return $reg; -} - -sub process_x86_regs -{ - my ($line, $cntr) = @_; - my $str = ""; - if (length($line) < 40) { - return ""; # not an asm istruction - } - - # find the arguments to the instruction - if ($line =~ /([0-9a-zA-Z\,\%\(\)\-\+]+)$/) { - $lastword = $1; - } else { - return ""; - } - - # we need to find the registers that get clobbered, - # since their value is no longer relevant for previous - # instructions in the stream. - - $clobber = $lastword; - # first, remove all memory operands, they're read only - $clobber =~ s/\([a-z0-9\%\,]+\)//g; - # then, remove everything before the comma, thats the read part - $clobber =~ s/.*\,//g; - - # if this is the instruction that faulted, we haven't actually done - # the write yet... nothing is clobbered. - if ($cntr == 0) { - $clobber = ""; - } - - foreach $reg (keys(%regs)) { - my $clobberprime = reg_name($clobber); - my $lastwordprime = reg_name($lastword); - my $val = $regs{$reg}; - if ($val =~ /^[0]+$/) { - $val = "0"; - } else { - $val =~ s/^0*//; - } - - # first check if we're clobbering this register; if we do - # we print it with a =>, and then delete its value - if ($clobber =~ /$reg/ || $clobberprime =~ /$reg/) { - if (length($val) > 0) { - $str = $str . " $reg => $val "; - } - $regs{$reg} = ""; - $val = ""; - } - # now check if we're reading this register - if ($lastword =~ /$reg/ || $lastwordprime =~ /$reg/) { - if (length($val) > 0) { - $str = $str . " $reg = $val "; - } - } - } - return $str; -} - -# parse the oops while () { my $line = $_; if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) { $target = $1; } - if ($line =~ /RIP: 0010:\[\<([a-z0-9]+)\>\]/) { - $target = $1; - } if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { $function = $1; $func_offset = $2; } - if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { - $function = $1; - $func_offset = $2; - } # check if it's a module if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) { $module = $3; } - if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) { - $module = $3; - } - parse_x86_regs($line); } my $decodestart = hex($target) - hex($func_offset); -my $decodestop = hex($target) + 8192; +my $decodestop = $decodestart + 8192; if ($target eq "0") { print "No oops found!\n"; print "Usage: \n"; @@ -208,7 +84,6 @@ sub process_x86_regs my $state = 0; my $center = 0; my @lines; -my @reglines; sub InRange { my ($address, $target) = @_; @@ -313,36 +188,16 @@ sub InRange { my $i; - -# start annotating the registers in the asm. -# this goes from the oopsing point back, so that the annotator -# can track (opportunistically) which registers got written and -# whos value no longer is relevant. - -$i = $center; -while ($i >= $start) { - $reglines[$i] = process_x86_regs($lines[$i], $center - $i); - $i = $i - 1; -} - +my $fulltext = ""; $i = $start; while ($i < $finish) { - my $line; if ($i == $center) { - $line = "*$lines[$i] "; + $fulltext = $fulltext . "*$lines[$i] <----- faulting instruction\n"; } else { - $line = " $lines[$i] "; - } - print $line; - if (defined($reglines[$i]) && length($reglines[$i]) > 0) { - my $c = 60 - length($line); - while ($c > 0) { print " "; $c = $c - 1; }; - print "| $reglines[$i]"; + $fulltext = $fulltext . " $lines[$i]\n"; } - if ($i == $center) { - print "<--- faulting instruction"; - } - print "\n"; $i = $i +1; } +print $fulltext; + diff --git a/trunk/scripts/mod/file2alias.c b/trunk/scripts/mod/file2alias.c index 4eea60b1693e..491b8b1b6abf 100644 --- a/trunk/scripts/mod/file2alias.c +++ b/trunk/scripts/mod/file2alias.c @@ -210,7 +210,6 @@ static void do_usb_table(void *symval, unsigned long size, static int do_hid_entry(const char *filename, struct hid_device_id *id, char *alias) { - id->bus = TO_NATIVE(id->bus); id->vendor = TO_NATIVE(id->vendor); id->product = TO_NATIVE(id->product); diff --git a/trunk/scripts/package/mkspec b/trunk/scripts/package/mkspec index ee448cdc6a2b..2500886fb90a 100755 --- a/trunk/scripts/package/mkspec +++ b/trunk/scripts/package/mkspec @@ -86,14 +86,6 @@ echo "%endif" echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE" echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$KERNELRELEASE" - -echo "%ifnarch ppc64" -echo 'cp vmlinux vmlinux.orig' -echo 'bzip2 -9 vmlinux' -echo 'mv vmlinux.bz2 $RPM_BUILD_ROOT'"/boot/vmlinux-$KERNELRELEASE.bz2" -echo 'mv vmlinux.orig vmlinux' -echo "%endif" - echo "" echo "%clean" echo '#echo -rf $RPM_BUILD_ROOT' diff --git a/trunk/scripts/setlocalversion b/trunk/scripts/setlocalversion index f1c4b35bc324..f6946cf99ce1 100755 --- a/trunk/scripts/setlocalversion +++ b/trunk/scripts/setlocalversion @@ -58,7 +58,14 @@ fi # Check for svn and a svn repo. if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then rev=`echo $rev | awk '{print $NF}'` - printf -- '-svn%s' "$rev" + changes=`svn status 2>/dev/null | grep '^[AMD]' | wc -l` + + # Are there uncommitted changes? + if [ $changes != 0 ]; then + printf -- '-svn%s%s' "$rev" -dirty + else + printf -- '-svn%s' "$rev" + fi # All done with svn exit diff --git a/trunk/scripts/tags.sh b/trunk/scripts/tags.sh index 5bd8b1003d44..fdbe78bb5e2b 100755 --- a/trunk/scripts/tags.sh +++ b/trunk/scripts/tags.sh @@ -76,10 +76,7 @@ all_sources() all_kconfigs() { - for arch in $ALLSOURCE_ARCHS; do - find_sources $arch 'Kconfig*' - done - find_other_sources 'Kconfig*' + find_sources $ALLSOURCE_ARCHS 'Kconfig*' } all_defconfigs() @@ -102,8 +99,7 @@ exuberant() -I ____cacheline_internodealigned_in_smp \ -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ --extra=+f --c-kinds=+px \ - --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ - --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' + --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' all_kconfigs | xargs $1 -a \ --langdef=kconfig --language-force=kconfig \ @@ -121,9 +117,7 @@ exuberant() emacs() { - all_sources | xargs $1 -a \ - --regex='/^ENTRY(\([^)]*\)).*/\1/' \ - --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' + all_sources | xargs $1 -a all_kconfigs | xargs $1 -a \ --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' diff --git a/trunk/security/selinux/netlabel.c b/trunk/security/selinux/netlabel.c index 350794ab9b42..f58701a7b728 100644 --- a/trunk/security/selinux/netlabel.c +++ b/trunk/security/selinux/netlabel.c @@ -386,12 +386,11 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask) if (!S_ISSOCK(inode->i_mode) || ((mask & (MAY_WRITE | MAY_APPEND)) == 0)) return 0; + sock = SOCKET_I(inode); sk = sock->sk; - if (sk == NULL) - return 0; sksec = sk->sk_security; - if (sksec == NULL || sksec->nlbl_state != NLBL_REQUIRE) + if (sksec->nlbl_state != NLBL_REQUIRE) return 0; local_bh_disable(); @@ -491,10 +490,8 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, lock_sock(sk); rc = netlbl_sock_getattr(sk, &secattr); release_sock(sk); - if (rc == 0) + if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) rc = -EACCES; - else if (rc == -ENOMSG) - rc = 0; netlbl_secattr_destroy(&secattr); } diff --git a/trunk/sound/arm/aaci.c b/trunk/sound/arm/aaci.c index 772901e41ecb..89096e811a4b 100644 --- a/trunk/sound/arm/aaci.c +++ b/trunk/sound/arm/aaci.c @@ -90,7 +90,7 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, */ do { v = readl(aaci->base + AACI_SLFR); - } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout); + } while ((v & (SLFR_1TXB|SLFR_2TXB)) && timeout--); if (!timeout) dev_err(&aaci->dev->dev, @@ -126,7 +126,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) */ do { v = readl(aaci->base + AACI_SLFR); - } while ((v & SLFR_1TXB) && --timeout); + } while ((v & SLFR_1TXB) && timeout--); if (!timeout) { dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n"); @@ -147,7 +147,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) do { cond_resched(); v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV); - } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout); + } while ((v != (SLFR_1RXV|SLFR_2RXV)) && timeout--); if (!timeout) { dev_err(&aaci->dev->dev, "timeout on RX valid\n"); diff --git a/trunk/sound/core/jack.c b/trunk/sound/core/jack.c index 077a85262c1c..dd4a12dc09aa 100644 --- a/trunk/sound/core/jack.c +++ b/trunk/sound/core/jack.c @@ -47,7 +47,7 @@ static int snd_jack_dev_register(struct snd_device *device) int err; snprintf(jack->name, sizeof(jack->name), "%s %s", - card->shortname, jack->id); + card->longname, jack->id); jack->input_dev->name = jack->name; /* Default to the sound card device. */ diff --git a/trunk/sound/core/oss/pcm_oss.c b/trunk/sound/core/oss/pcm_oss.c index 0a1798eafb0b..e17836680f49 100644 --- a/trunk/sound/core/oss/pcm_oss.c +++ b/trunk/sound/core/oss/pcm_oss.c @@ -1767,7 +1767,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) AFMT_S8 | AFMT_U16_LE | AFMT_U16_BE | AFMT_S32_LE | AFMT_S32_BE | - AFMT_S24_LE | AFMT_S24_BE | + AFMT_S24_LE | AFMT_S24_LE | AFMT_S24_PACKED; params = kmalloc(sizeof(*params), GFP_KERNEL); if (!params) diff --git a/trunk/sound/core/oss/rate.c b/trunk/sound/core/oss/rate.c index 2fa9299a440d..a466443c4a26 100644 --- a/trunk/sound/core/oss/rate.c +++ b/trunk/sound/core/oss/rate.c @@ -157,7 +157,7 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, while (dst_frames1 > 0) { S1 = S2; if (src_frames1-- > 0) { - S2 = *src; + S1 = *src; src += src_step; } if (pos & ~R_MASK) { diff --git a/trunk/sound/drivers/mtpav.c b/trunk/sound/drivers/mtpav.c index 48b64e6b2670..5b89c0883d60 100644 --- a/trunk/sound/drivers/mtpav.c +++ b/trunk/sound/drivers/mtpav.c @@ -706,6 +706,7 @@ static int __devinit snd_mtpav_probe(struct platform_device *dev) mtp_card->card = card; mtp_card->irq = -1; mtp_card->share_irq = 0; + mtp_card->inmidiport = 0xffffffff; mtp_card->inmidistate = 0; mtp_card->outmidihwport = 0xffffffff; init_timer(&mtp_card->timer); @@ -718,8 +719,6 @@ static int __devinit snd_mtpav_probe(struct platform_device *dev) if (err < 0) goto __error; - mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST; - err = snd_mtpav_get_ISA(mtp_card); if (err < 0) goto __error; diff --git a/trunk/sound/oss/dmasound/dmasound_atari.c b/trunk/sound/oss/dmasound/dmasound_atari.c index 38931f2f6967..57d9f154c88b 100644 --- a/trunk/sound/oss/dmasound/dmasound_atari.c +++ b/trunk/sound/oss/dmasound/dmasound_atari.c @@ -847,23 +847,23 @@ static int __init AtaIrqInit(void) of events. So all we need to keep the music playing is to provide the sound hardware with new data upon an interrupt from timer A. */ - st_mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */ - st_mfp.tim_dt_a = 1; /* Cause interrupt after first event. */ - st_mfp.tim_ct_a = 8; /* Turn on event counting. */ + mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */ + mfp.tim_dt_a = 1; /* Cause interrupt after first event. */ + mfp.tim_ct_a = 8; /* Turn on event counting. */ /* Register interrupt handler. */ if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound", AtaInterrupt)) return 0; - st_mfp.int_en_a |= 0x20; /* Turn interrupt on. */ - st_mfp.int_mk_a |= 0x20; + mfp.int_en_a |= 0x20; /* Turn interrupt on. */ + mfp.int_mk_a |= 0x20; return 1; } #ifdef MODULE static void AtaIrqCleanUp(void) { - st_mfp.tim_ct_a = 0; /* stop timer */ - st_mfp.int_en_a &= ~0x20; /* turn interrupt off */ + mfp.tim_ct_a = 0; /* stop timer */ + mfp.int_en_a &= ~0x20; /* turn interrupt off */ free_irq(IRQ_MFP_TIMA, AtaInterrupt); } #endif /* MODULE */ @@ -1599,7 +1599,7 @@ static int __init dmasound_atari_init(void) is_falcon = 0; } else return -ENODEV; - if ((st_mfp.int_en_a & st_mfp.int_mk_a & 0x20) == 0) + if ((mfp.int_en_a & mfp.int_mk_a & 0x20) == 0) return dmasound_init(); else { printk("DMA sound driver: Timer A interrupt already in use\n"); diff --git a/trunk/sound/pci/aw2/aw2-alsa.c b/trunk/sound/pci/aw2/aw2-alsa.c index c7c54e7748e9..3f00ddf450f8 100644 --- a/trunk/sound/pci/aw2/aw2-alsa.c +++ b/trunk/sound/pci/aw2/aw2-alsa.c @@ -165,7 +165,7 @@ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); static struct pci_device_id snd_aw2_ids[] = { - {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, + {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0} }; diff --git a/trunk/sound/pci/emu10k1/emu10k1_main.c b/trunk/sound/pci/emu10k1/emu10k1_main.c index 101a1c13a20d..7958006a1d66 100644 --- a/trunk/sound/pci/emu10k1/emu10k1_main.c +++ b/trunk/sound/pci/emu10k1/emu10k1_main.c @@ -1528,7 +1528,6 @@ static struct snd_emu_chip_details emu_chip_details[] = { .ca0151_chip = 1, .spk71 = 1, .spdif_bug = 1, - .invert_shared_spdif = 1, /* digital/analog switch swapped */ .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]", diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index d03f99298be9..b7bba7dc7cf1 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -487,6 +487,7 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card, { struct hda_bus *bus; int err; + char qname[8]; static struct snd_device_ops dev_ops = { .dev_register = snd_hda_bus_dev_register, .dev_free = snd_hda_bus_dev_free, @@ -516,12 +517,10 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card, mutex_init(&bus->cmd_mutex); INIT_LIST_HEAD(&bus->codec_list); - snprintf(bus->workq_name, sizeof(bus->workq_name), - "hd-audio%d", card->number); - bus->workq = create_singlethread_workqueue(bus->workq_name); + snprintf(qname, sizeof(qname), "hda%d", card->number); + bus->workq = create_workqueue(qname); if (!bus->workq) { - snd_printk(KERN_ERR "cannot create workqueue %s\n", - bus->workq_name); + snd_printk(KERN_ERR "cannot create workqueue %s\n", qname); kfree(bus); return -ENOMEM; } @@ -3088,16 +3087,6 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, } EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare); -int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, - struct hda_multi_out *mout) -{ - mutex_lock(&codec->spdif_mutex); - cleanup_dig_out_stream(codec, mout->dig_out_nid); - mutex_unlock(&codec->spdif_mutex); - return 0; -} -EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup); - /* * release the digital out */ diff --git a/trunk/sound/pci/hda/hda_codec.h b/trunk/sound/pci/hda/hda_codec.h index 09a332ada0c6..5810ef588402 100644 --- a/trunk/sound/pci/hda/hda_codec.h +++ b/trunk/sound/pci/hda/hda_codec.h @@ -614,7 +614,6 @@ struct hda_bus { /* unsolicited event queue */ struct hda_bus_unsolicited *unsol; - char workq_name[16]; struct workqueue_struct *workq; /* common workqueue for codecs */ /* assigned PCMs */ diff --git a/trunk/sound/pci/hda/hda_hwdep.c b/trunk/sound/pci/hda/hda_hwdep.c index 4ae51dcb81af..300ab407cf42 100644 --- a/trunk/sound/pci/hda/hda_hwdep.c +++ b/trunk/sound/pci/hda/hda_hwdep.c @@ -175,7 +175,7 @@ static int reconfig_codec(struct hda_codec *codec) err = snd_hda_codec_build_controls(codec); if (err < 0) return err; - return snd_card_register(codec->bus->card); + return 0; } /* @@ -277,19 +277,18 @@ static ssize_t init_verbs_store(struct device *dev, { struct snd_hwdep *hwdep = dev_get_drvdata(dev); struct hda_codec *codec = hwdep->private_data; - struct hda_verb *v; - int nid, verb, param; + char *p; + struct hda_verb verb, *v; - if (sscanf(buf, "%i %i %i", &nid, &verb, ¶m) != 3) - return -EINVAL; - if (!nid || !verb) + verb.nid = simple_strtoul(buf, &p, 0); + verb.verb = simple_strtoul(p, &p, 0); + verb.param = simple_strtoul(p, &p, 0); + if (!verb.nid || !verb.verb || !verb.param) return -EINVAL; v = snd_array_new(&codec->init_verbs); if (!v) return -ENOMEM; - v->nid = nid; - v->verb = verb; - v->param = param; + *v = verb; return count; } diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index c8d9178f47e5..11e791b965f6 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -1947,13 +1947,16 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) return 0; } +static int azx_resume_early(struct pci_dev *pci) +{ + return pci_restore_state(pci); +} + static int azx_resume(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); struct azx *chip = card->private_data; - pci_set_power_state(pci, PCI_D0); - pci_restore_state(pci); if (pci_enable_device(pci) < 0) { printk(KERN_ERR "hda-intel: pci_enable_device failed, " "disabling device\n"); @@ -2465,6 +2468,7 @@ static struct pci_driver driver = { .remove = __devexit_p(azx_remove), #ifdef CONFIG_PM .suspend = azx_suspend, + .resume_early = azx_resume_early, .resume = azx_resume, #endif }; diff --git a/trunk/sound/pci/hda/hda_local.h b/trunk/sound/pci/hda/hda_local.h index 44f189cb97ae..1dd8716c387f 100644 --- a/trunk/sound/pci/hda/hda_local.h +++ b/trunk/sound/pci/hda/hda_local.h @@ -251,8 +251,6 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream); -int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, - struct hda_multi_out *mout); int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, struct snd_pcm_substream *substream, diff --git a/trunk/sound/pci/hda/hda_proc.c b/trunk/sound/pci/hda/hda_proc.c index 144b85276d5a..7ca66d654148 100644 --- a/trunk/sound/pci/hda/hda_proc.c +++ b/trunk/sound/pci/hda/hda_proc.c @@ -399,8 +399,7 @@ static void print_conn_list(struct snd_info_buffer *buffer, { int c, curr = -1; - if (conn_len > 1 && wid_type != AC_WID_AUD_MIX && - wid_type != AC_WID_VOL_KNB) + if (conn_len > 1 && wid_type != AC_WID_AUD_MIX) curr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); snd_iprintf(buffer, " Connection: %d\n", conn_len); diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index e48612323aa0..2e7371ec2e23 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -275,14 +275,6 @@ static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, format, substream); } -static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct ad198x_spec *spec = codec->spec; - return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); -} - /* * Analog capture */ @@ -341,8 +333,7 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { .ops = { .open = ad198x_dig_playback_pcm_open, .close = ad198x_dig_playback_pcm_close, - .prepare = ad198x_dig_playback_pcm_prepare, - .cleanup = ad198x_dig_playback_pcm_cleanup + .prepare = ad198x_dig_playback_pcm_prepare }, }; @@ -1894,8 +1885,8 @@ static hda_nid_t ad1988_capsrc_nids[3] = { #define AD1988_SPDIF_OUT_HDMI 0x0b #define AD1988_SPDIF_IN 0x07 -static hda_nid_t ad1989b_slave_dig_outs[] = { - AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 +static hda_nid_t ad1989b_slave_dig_outs[2] = { + AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI }; static struct hda_input_mux ad1988_6stack_capture_source = { diff --git a/trunk/sound/pci/hda/patch_intelhdmi.c b/trunk/sound/pci/hda/patch_intelhdmi.c index fcc77fec4487..3564f4e4b74c 100644 --- a/trunk/sound/pci/hda/patch_intelhdmi.c +++ b/trunk/sound/pci/hda/patch_intelhdmi.c @@ -49,6 +49,11 @@ static struct hda_verb pinout_enable_verb[] = { {} /* terminator */ }; +static struct hda_verb pinout_disable_verb[] = { + {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00}, + {} +}; + static struct hda_verb unsolicited_response_verb[] = { {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | INTEL_HDMI_EVENT_TAG}, @@ -243,6 +248,10 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid, static void hdmi_enable_output(struct hda_codec *codec) { + /* Enable Audio InfoFrame Transmission */ + hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); + snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, + AC_DIPXMIT_BEST); /* Unmute */ if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) snd_hda_codec_write(codec, PIN_NID, 0, @@ -251,24 +260,17 @@ static void hdmi_enable_output(struct hda_codec *codec) snd_hda_sequence_write(codec, pinout_enable_verb); } -/* - * Enable Audio InfoFrame Transmission - */ -static void hdmi_start_infoframe_trans(struct hda_codec *codec) +static void hdmi_disable_output(struct hda_codec *codec) { - hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); - snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, - AC_DIPXMIT_BEST); -} + snd_hda_sequence_write(codec, pinout_disable_verb); + if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) + snd_hda_codec_write(codec, PIN_NID, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); -/* - * Disable Audio InfoFrame Transmission - */ -static void hdmi_stop_infoframe_trans(struct hda_codec *codec) -{ - hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); - snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, - AC_DIPXMIT_DISABLE); + /* + * FIXME: noises may arise when playing music after reloading the + * kernel module, until the next X restart or monitor repower. + */ } static int hdmi_get_channel_count(struct hda_codec *codec) @@ -366,16 +368,11 @@ static void hdmi_fill_audio_infoframe(struct hda_codec *codec, struct hdmi_audio_infoframe *ai) { u8 *params = (u8 *)ai; - u8 sum = 0; int i; hdmi_debug_dip_size(codec); hdmi_clear_dip_buffers(codec); /* be paranoid */ - for (i = 0; i < sizeof(ai); i++) - sum += params[i]; - ai->checksum = - sum; - hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); for (i = 0; i < sizeof(ai); i++) hdmi_write_dip_byte(codec, PIN_NID, params[i]); @@ -422,16 +419,12 @@ static int hdmi_setup_channel_allocation(struct hda_codec *codec, /* * CA defaults to 0 for basic stereo audio */ - if (channels <= 2) + if (!eld->eld_ver) return 0; - - /* - * HDMI sink's ELD info cannot always be retrieved for now, e.g. - * in console or for audio devices. Assume the highest speakers - * configuration, to _not_ prohibit multi-channel audio playback. - */ if (!eld->spk_alloc) - eld->spk_alloc = 0xffff; + return 0; + if (channels <= 2) + return 0; /* * expand ELD's speaker allocation mask @@ -492,7 +485,6 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hdmi_setup_channel_mapping(codec, &ai); hdmi_fill_audio_infoframe(codec, &ai); - hdmi_start_infoframe_trans(codec); } @@ -570,7 +562,7 @@ static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo, { struct intel_hdmi_spec *spec = codec->spec; - hdmi_stop_infoframe_trans(codec); + hdmi_disable_output(codec); return snd_hda_multi_out_dig_close(codec, &spec->multiout); } @@ -590,6 +582,8 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, hdmi_setup_audio_infoframe(codec, substream); + hdmi_enable_output(codec); + return 0; } @@ -634,7 +628,8 @@ static int intel_hdmi_build_controls(struct hda_codec *codec) static int intel_hdmi_init(struct hda_codec *codec) { - hdmi_enable_output(codec); + /* disable audio output as early as possible */ + hdmi_disable_output(codec); snd_hda_sequence_write(codec, unsolicited_response_verb); @@ -684,7 +679,6 @@ static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, - { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, {} /* terminator */ }; @@ -693,7 +687,6 @@ MODULE_ALIAS("snd-hda-codec-id:808629fb"); MODULE_ALIAS("snd-hda-codec-id:80862801"); MODULE_ALIAS("snd-hda-codec-id:80862802"); MODULE_ALIAS("snd-hda-codec-id:80862803"); -MODULE_ALIAS("snd-hda-codec-id:80862804"); MODULE_ALIAS("snd-hda-codec-id:10951392"); MODULE_LICENSE("GPL"); diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index a680be0d4534..7884a4e07061 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -1037,7 +1037,6 @@ static void alc_subsystem_id(struct hda_codec *codec, case 0x10ec0267: case 0x10ec0268: case 0x10ec0269: - case 0x10ec0272: case 0x10ec0660: case 0x10ec0662: case 0x10ec0663: @@ -1066,7 +1065,6 @@ static void alc_subsystem_id(struct hda_codec *codec, case 0x10ec0882: case 0x10ec0883: case 0x10ec0885: - case 0x10ec0887: case 0x10ec0889: snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); @@ -7014,10 +7012,8 @@ static int patch_alc882(struct hda_codec *codec) break; case 0x106b1000: /* iMac 24 */ case 0x106b2800: /* AppleTV */ - case 0x106b3e00: /* iMac 24 Aluminium */ board_config = ALC885_IMAC24; break; - case 0x106b00a0: /* MacBookPro3,1 - Another revision */ case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ case 0x106b00a4: /* MacbookPro4,1 */ case 0x106b2c00: /* Macbook Pro rev3 */ @@ -8470,8 +8466,6 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { ALC888_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", ALC888_ACER_ASPIRE_4930G), - SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", - ALC888_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), @@ -8481,7 +8475,6 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), - SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), @@ -8521,8 +8514,6 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), - SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550", - ALC883_FUJITSU_PI2515), SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530", ALC888_FUJITSU_XA3530), diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 8027edf3c8f2..b787b3cc096f 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -1799,13 +1799,11 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, "HP dv5", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, - "HP dv7", STAC_HP_DV5), + "HP dv7", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7, "HP dv4", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, "HP dv7", STAC_HP_M4), - SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3600, - "HP dv5", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, "HP dv5", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, @@ -2442,14 +2440,6 @@ static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, stream_tag, format, substream); } -static int stac92xx_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct sigmatel_spec *spec = codec->spec; - return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); -} - /* * Analog capture callbacks @@ -2494,8 +2484,7 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { .ops = { .open = stac92xx_dig_playback_pcm_open, .close = stac92xx_dig_playback_pcm_close, - .prepare = stac92xx_dig_playback_pcm_prepare, - .cleanup = stac92xx_dig_playback_pcm_cleanup + .prepare = stac92xx_dig_playback_pcm_prepare }, }; diff --git a/trunk/sound/pci/intel8x0.c b/trunk/sound/pci/intel8x0.c index e900cdc84849..19d3391e229f 100644 --- a/trunk/sound/pci/intel8x0.c +++ b/trunk/sound/pci/intel8x0.c @@ -617,7 +617,7 @@ static int snd_intel8x0_ali_codec_semaphore(struct intel8x0 *chip) int time = 100; if (chip->buggy_semaphore) return 0; /* just ignore ... */ - while (--time && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY)) + while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY)) udelay(1); if (! time && ! chip->in_ac97_init) snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n"); diff --git a/trunk/sound/pci/oxygen/virtuoso.c b/trunk/sound/pci/oxygen/virtuoso.c index 6c870c12a177..18c7c91786bc 100644 --- a/trunk/sound/pci/oxygen/virtuoso.c +++ b/trunk/sound/pci/oxygen/virtuoso.c @@ -26,7 +26,7 @@ * SPI 0 -> 1st PCM1796 (front) * SPI 1 -> 2nd PCM1796 (surround) * SPI 2 -> 3rd PCM1796 (center/LFE) - * SPI 4 -> 4th PCM1796 (back) + * SPI 4 -> 4th PCM1796 (back) and EEPROM self-destruct (do not use!) * * GPIO 2 -> M0 of CS5381 * GPIO 3 -> M1 of CS5381 @@ -207,6 +207,12 @@ static void xonar_gpio_changed(struct oxygen *chip); static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec, u8 reg, u8 value) { + /* + * We don't want to do writes on SPI 4 because the EEPROM, which shares + * the same pin, might get confused and broken. We'd better take care + * that the driver works with the default register values ... + */ +#if 0 /* maps ALSA channel pair number to SPI output */ static const u8 codec_map[4] = { 0, 1, 2, 4 @@ -217,6 +223,7 @@ static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec, (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) | OXYGEN_SPI_CEN_LATCH_CLOCK_HI, (reg << 8) | value); +#endif } static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec, @@ -750,6 +757,9 @@ static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -12700, 100, 0); static int xonar_d2_control_filter(struct snd_kcontrol_new *template) { + if (!strncmp(template->name, "Master Playback ", 16)) + /* disable volume/mute because they would require SPI writes */ + return 1; if (!strncmp(template->name, "CD Capture ", 11)) /* CD in is actually connected to the video in pin */ template->private_value ^= AC97_CD ^ AC97_VIDEO; @@ -840,9 +850,8 @@ static const struct oxygen_model model_xonar_d2 = { .dac_volume_min = 0x0f, .dac_volume_max = 0xff, .misc_flags = OXYGEN_MISC_MIDI, - .function_flags = OXYGEN_FUNCTION_SPI | - OXYGEN_FUNCTION_ENABLE_SPI_4_5, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .function_flags = OXYGEN_FUNCTION_SPI, + .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; diff --git a/trunk/sound/pci/pcxhr/pcxhr.h b/trunk/sound/pci/pcxhr/pcxhr.h index 69d87dee6995..84131a916c92 100644 --- a/trunk/sound/pci/pcxhr/pcxhr.h +++ b/trunk/sound/pci/pcxhr/pcxhr.h @@ -97,12 +97,12 @@ struct pcxhr_mgr { int capture_chips; int fw_file_set; int firmware_num; - unsigned int is_hr_stereo:1; - unsigned int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */ - unsigned int board_has_analog:1; /* if 0 the board is digital only */ - unsigned int board_has_mic:1; /* if 1 the board has microphone input */ - unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ - unsigned int mono_capture:1; /* if 1 the board does mono capture */ + int is_hr_stereo:1; + int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */ + int board_has_analog:1; /* if 0 the board is digital only */ + int board_has_mic:1; /* if 1 the board has microphone input */ + int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ + int mono_capture:1; /* if 1 the board does mono capture */ struct snd_dma_buffer hostport; diff --git a/trunk/sound/soc/atmel/atmel_ssc_dai.c b/trunk/sound/soc/atmel/atmel_ssc_dai.c index ff0054b76502..c5d67900d666 100644 --- a/trunk/sound/soc/atmel/atmel_ssc_dai.c +++ b/trunk/sound/soc/atmel/atmel_ssc_dai.c @@ -10,7 +10,7 @@ * Based on at91-ssc.c by * Frank Mandarino * Based on pxa2xx Platform drivers by - * Liam Girdwood + * Liam Girdwood * * 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 diff --git a/trunk/sound/soc/atmel/atmel_ssc_dai.h b/trunk/sound/soc/atmel/atmel_ssc_dai.h index 391135f9c6c1..a828746e8a2f 100644 --- a/trunk/sound/soc/atmel/atmel_ssc_dai.h +++ b/trunk/sound/soc/atmel/atmel_ssc_dai.h @@ -10,7 +10,7 @@ * Based on at91-ssc.c by * Frank Mandarino * Based on pxa2xx Platform drivers by - * Liam Girdwood + * Liam Girdwood * * 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 diff --git a/trunk/sound/soc/codecs/tlv320aic3x.c b/trunk/sound/soc/codecs/tlv320aic3x.c index aea0cb72d80a..b47a749c5ea2 100644 --- a/trunk/sound/soc/codecs/tlv320aic3x.c +++ b/trunk/sound/soc/codecs/tlv320aic3x.c @@ -165,13 +165,10 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int shift = mc->shift; - int max = mc->max; - unsigned int mask = (1 << fls(max)) - 1; - unsigned int invert = mc->invert; + int reg = kcontrol->private_value & 0xff; + int shift = (kcontrol->private_value >> 8) & 0x0f; + int mask = (kcontrol->private_value >> 16) & 0xff; + int invert = (kcontrol->private_value >> 24) & 0x01; unsigned short val, val_mask; int ret; struct snd_soc_dapm_path *path; diff --git a/trunk/sound/soc/codecs/wm8350.c b/trunk/sound/soc/codecs/wm8350.c index 35d99750c383..e3989d406f54 100644 --- a/trunk/sound/soc/codecs/wm8350.c +++ b/trunk/sound/soc/codecs/wm8350.c @@ -3,7 +3,7 @@ * * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. * - * Author: Liam Girdwood + * Author: Liam Girdwood * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/trunk/sound/soc/codecs/wm8990.c b/trunk/sound/soc/codecs/wm8990.c index a5731faa150c..5b5afc144478 100644 --- a/trunk/sound/soc/codecs/wm8990.c +++ b/trunk/sound/soc/codecs/wm8990.c @@ -2,7 +2,8 @@ * wm8990.c -- WM8990 ALSA Soc Audio driver * * Copyright 2008 Wolfson Microelectronics PLC. - * Author: Liam Girdwood + * Author: Liam Girdwood + * lg@opensource.wolfsonmicro.com or linux@wolfsonmicro.com * * 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 @@ -176,9 +177,7 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - int reg = mc->reg; + int reg = kcontrol->private_value & 0xff; int ret; u16 val; diff --git a/trunk/sound/soc/omap/omap-pcm.c b/trunk/sound/soc/omap/omap-pcm.c index dd3bb2933762..b0362dfd5b71 100644 --- a/trunk/sound/soc/omap/omap-pcm.c +++ b/trunk/sound/soc/omap/omap-pcm.c @@ -175,10 +175,9 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_pcm_runtime *runtime = substream->runtime; struct omap_runtime_data *prtd = runtime->private_data; - unsigned long flags; int ret = 0; - spin_lock_irqsave(&prtd->lock, flags); + spin_lock_irq(&prtd->lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: @@ -196,7 +195,7 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) default: ret = -EINVAL; } - spin_unlock_irqrestore(&prtd->lock, flags); + spin_unlock_irq(&prtd->lock); return ret; } diff --git a/trunk/sound/soc/omap/sdp3430.c b/trunk/sound/soc/omap/sdp3430.c index e226fa75669c..ad97836818b1 100644 --- a/trunk/sound/soc/omap/sdp3430.c +++ b/trunk/sound/soc/omap/sdp3430.c @@ -91,7 +91,7 @@ static struct snd_soc_dai_link sdp3430_dai = { }; /* Audio machine driver */ -static struct snd_soc_card snd_soc_sdp3430 = { +static struct snd_soc_machine snd_soc_machine_sdp3430 = { .name = "SDP3430", .platform = &omap_soc_platform, .dai_link = &sdp3430_dai, @@ -100,7 +100,7 @@ static struct snd_soc_card snd_soc_sdp3430 = { /* Audio subsystem */ static struct snd_soc_device sdp3430_snd_devdata = { - .card = &snd_soc_sdp3430, + .machine = &snd_soc_machine_sdp3430, .codec_dev = &soc_codec_dev_twl4030, }; diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index ec3f8bb4b51d..55fdb4abb179 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -1385,10 +1385,7 @@ int snd_soc_init_card(struct snd_soc_device *socdev) mutex_lock(&codec->mutex); #ifdef CONFIG_SND_SOC_AC97_BUS - /* Only instantiate AC97 if not already done by the adaptor - * for the generic AC97 subsystem. - */ - if (ac97 && strcmp(codec->name, "AC97") != 0) { + if (ac97) { ret = soc_ac97_dev_register(codec); if (ret < 0) { printk(KERN_ERR "asoc: AC97 device register failed\n"); diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index 19e37451c216..c709b9563226 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -2524,6 +2524,7 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform * build the rate table and bitmap flags */ int r, idx; + unsigned int nonzero_rates = 0; fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); if (fp->rate_table == NULL) { @@ -2531,27 +2532,24 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform return -1; } - fp->nr_rates = 0; - fp->rate_min = fp->rate_max = 0; + fp->nr_rates = nr_rates; + fp->rate_min = fp->rate_max = combine_triple(&fmt[8]); for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { unsigned int rate = combine_triple(&fmt[idx]); - if (!rate) - continue; /* C-Media CM6501 mislabels its 96 kHz altsetting */ if (rate == 48000 && nr_rates == 1 && - (chip->usb_id == USB_ID(0x0d8c, 0x0201) || - chip->usb_id == USB_ID(0x0d8c, 0x0102)) && + chip->usb_id == USB_ID(0x0d8c, 0x0201) && fp->altsetting == 5 && fp->maxpacksize == 392) rate = 96000; - fp->rate_table[fp->nr_rates] = rate; - if (!fp->rate_min || rate < fp->rate_min) + fp->rate_table[r] = rate; + nonzero_rates |= rate; + if (rate < fp->rate_min) fp->rate_min = rate; - if (!fp->rate_max || rate > fp->rate_max) + else if (rate > fp->rate_max) fp->rate_max = rate; fp->rates |= snd_pcm_rate_to_rate_bit(rate); - fp->nr_rates++; } - if (!fp->nr_rates) { + if (!nonzero_rates) { hwc_debug("All rates were zero. Skipping format!\n"); return -1; } @@ -2968,7 +2966,6 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, return -EINVAL; } alts = &iface->altsetting[fp->altset_idx]; - fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); usb_set_interface(chip->dev, fp->iface, 0); init_usb_pitch(chip->dev, fp->iface, alts, fp); init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max); diff --git a/trunk/sound/usb/usbmidi.c b/trunk/sound/usb/usbmidi.c index 26bad373fe65..320641ab5be7 100644 --- a/trunk/sound/usb/usbmidi.c +++ b/trunk/sound/usb/usbmidi.c @@ -1625,7 +1625,6 @@ static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi, } ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - ep_info.out_interval = 0; ep_info.out_cables = endpoint->out_cables & 0x5555; err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); if (err < 0) diff --git a/trunk/virt/kvm/iommu.c b/trunk/virt/kvm/iommu.c index 4c4037503600..e9693a29d00e 100644 --- a/trunk/virt/kvm/iommu.c +++ b/trunk/virt/kvm/iommu.c @@ -73,13 +73,14 @@ static int kvm_iommu_map_memslots(struct kvm *kvm) { int i, r = 0; + down_read(&kvm->slots_lock); for (i = 0; i < kvm->nmemslots; i++) { r = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, kvm->memslots[i].npages); if (r) break; } - + up_read(&kvm->slots_lock); return r; } @@ -189,11 +190,12 @@ static void kvm_iommu_put_pages(struct kvm *kvm, static int kvm_iommu_unmap_memslots(struct kvm *kvm) { int i; - + down_read(&kvm->slots_lock); for (i = 0; i < kvm->nmemslots; i++) { kvm_iommu_put_pages(kvm, kvm->memslots[i].base_gfn, kvm->memslots[i].npages); } + up_read(&kvm->slots_lock); return 0; } diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index 29a667ce35b0..3a5a08298aab 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -173,6 +173,7 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) assigned_dev->host_irq_disabled = false; } mutex_unlock(&assigned_dev->kvm->lock); + kvm_put_kvm(assigned_dev->kvm); } static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) @@ -180,6 +181,8 @@ static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) struct kvm_assigned_dev_kernel *assigned_dev = (struct kvm_assigned_dev_kernel *) dev_id; + kvm_get_kvm(assigned_dev->kvm); + schedule_work(&assigned_dev->interrupt_work); disable_irq_nosync(irq); @@ -210,7 +213,6 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian) } } -/* The function implicit hold kvm->lock mutex due to cancel_work_sync() */ static void kvm_free_assigned_irq(struct kvm *kvm, struct kvm_assigned_dev_kernel *assigned_dev) { @@ -226,24 +228,11 @@ static void kvm_free_assigned_irq(struct kvm *kvm, if (!assigned_dev->irq_requested_type) return; - /* - * In kvm_free_device_irq, cancel_work_sync return true if: - * 1. work is scheduled, and then cancelled. - * 2. work callback is executed. - * - * The first one ensured that the irq is disabled and no more events - * would happen. But for the second one, the irq may be enabled (e.g. - * for MSI). So we disable irq here to prevent further events. - * - * Notice this maybe result in nested disable if the interrupt type is - * INTx, but it's OK for we are going to free it. - * - * If this function is a part of VM destroy, please ensure that till - * now, the kvm state is still legal for probably we also have to wait - * interrupt_work done. - */ - disable_irq_nosync(assigned_dev->host_irq); - cancel_work_sync(&assigned_dev->interrupt_work); + if (cancel_work_sync(&assigned_dev->interrupt_work)) + /* We had pending work. That means we will have to take + * care of kvm_put_kvm. + */ + kvm_put_kvm(kvm); free_irq(assigned_dev->host_irq, (void *)assigned_dev); @@ -296,8 +285,8 @@ static int assigned_device_update_intx(struct kvm *kvm, if (irqchip_in_kernel(kvm)) { if (!msi2intx && - (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI)) { - free_irq(adev->host_irq, (void *)adev); + adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI) { + free_irq(adev->host_irq, (void *)kvm); pci_disable_msi(adev->dev); } @@ -466,7 +455,6 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, struct kvm_assigned_dev_kernel *match; struct pci_dev *dev; - down_read(&kvm->slots_lock); mutex_lock(&kvm->lock); match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head, @@ -528,7 +516,6 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, out: mutex_unlock(&kvm->lock); - up_read(&kvm->slots_lock); return r; out_list_del: list_del(&match->list); @@ -540,7 +527,6 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, out_free: kfree(match); mutex_unlock(&kvm->lock); - up_read(&kvm->slots_lock); return r; } #endif @@ -803,19 +789,11 @@ static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn, return young; } -static void kvm_mmu_notifier_release(struct mmu_notifier *mn, - struct mm_struct *mm) -{ - struct kvm *kvm = mmu_notifier_to_kvm(mn); - kvm_arch_flush_shadow(kvm); -} - static const struct mmu_notifier_ops kvm_mmu_notifier_ops = { .invalidate_page = kvm_mmu_notifier_invalidate_page, .invalidate_range_start = kvm_mmu_notifier_invalidate_range_start, .invalidate_range_end = kvm_mmu_notifier_invalidate_range_end, .clear_flush_young = kvm_mmu_notifier_clear_flush_young, - .release = kvm_mmu_notifier_release, }; #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */ @@ -905,7 +883,6 @@ static void kvm_destroy_vm(struct kvm *kvm) { struct mm_struct *mm = kvm->mm; - kvm_arch_sync_events(kvm); spin_lock(&kvm_lock); list_del(&kvm->vm_list); spin_unlock(&kvm_lock);