aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Documentation/00-INDEX2
-rw-r--r--Documentation/DocBook/kernel-api.tmpl2
-rw-r--r--Documentation/atomic_ops.txt3
-rw-r--r--Documentation/cdrom/ide-cd18
-rw-r--r--Documentation/cgroups.txt66
-rw-r--r--Documentation/controllers/memory.txt38
-rw-r--r--Documentation/cpusets.txt2
-rw-r--r--Documentation/debugging-via-ohci1394.txt17
-rw-r--r--Documentation/feature-removal-schedule.txt22
-rw-r--r--Documentation/gpio.txt16
-rw-r--r--Documentation/hwmon/adt747379
-rw-r--r--Documentation/hwmon/coretemp6
-rw-r--r--Documentation/i2c/busses/i2c-i8013
-rw-r--r--Documentation/i386/IO-APIC.txt32
-rw-r--r--Documentation/ide/00-INDEX12
-rw-r--r--Documentation/ide/ide.txt (renamed from Documentation/ide.txt)69
-rw-r--r--Documentation/ja_JP/stable_kernel_rules.txt106
-rw-r--r--Documentation/kernel-parameters.txt45
-rw-r--r--Documentation/kprobes.txt243
-rw-r--r--Documentation/laptops/thinkpad-acpi.txt63
-rw-r--r--Documentation/memory-barriers.txt2
-rw-r--r--Documentation/networking/tcp.txt8
-rw-r--r--Documentation/pci.txt6
-rw-r--r--Documentation/power/devices.txt13
-rw-r--r--Documentation/scsi/ChangeLog.arcmsr6
-rw-r--r--Documentation/stable_kernel_rules.txt7
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx2
-rw-r--r--Documentation/video4linux/CARDLIST.saa71346
-rw-r--r--Documentation/video4linux/zr364xx.txt4
-rw-r--r--Documentation/vm/slabinfo.c2
-rw-r--r--Documentation/vm/slub.txt4
-rw-r--r--MAINTAINERS92
-rw-r--r--Makefile15
-rw-r--r--arch/Kconfig7
-rw-r--r--arch/alpha/kernel/pci_iommu.c72
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/mach-omap1/board-sx1.c2
-rw-r--r--arch/arm/mach-orion/ts209-setup.c15
-rw-r--r--arch/arm/mach-pxa/clock.c23
-rw-r--r--arch/arm/mach-pxa/cpu-pxa.c10
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c8
-rw-r--r--arch/arm/mach-pxa/zylonite.c2
-rw-r--r--arch/arm/mm/mmap.c2
-rw-r--r--arch/arm/mm/pgd.c6
-rw-r--r--arch/avr32/boards/atstk1000/atstk1004.c2
-rw-r--r--arch/avr32/kernel/process.c4
-rw-r--r--arch/avr32/mm/fault.c2
-rw-r--r--arch/blackfin/Makefile5
-rw-r--r--arch/blackfin/configs/BF527-EZKIT_defconfig18
-rw-r--r--arch/blackfin/configs/BF533-EZKIT_defconfig6
-rw-r--r--arch/blackfin/configs/BF533-STAMP_defconfig6
-rw-r--r--arch/blackfin/configs/BF537-STAMP_defconfig6
-rw-r--r--arch/blackfin/configs/BF548-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF561-EZKIT_defconfig1
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c15
-rw-r--r--arch/blackfin/kernel/fixed_code.S12
-rw-r--r--arch/blackfin/kernel/gptimers.c8
-rw-r--r--arch/blackfin/kernel/setup.c5
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S34
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c60
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c21
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c43
-rw-r--r--arch/blackfin/mach-bf537/boards/generic_board.c18
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c45
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c29
-rw-r--r--arch/blackfin/mach-bf548/dma.c2
-rw-r--r--arch/blackfin/mach-bf548/head.S9
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c16
-rw-r--r--arch/blackfin/mach-common/dpmc.S137
-rw-r--r--arch/blackfin/mach-common/entry.S5
-rw-r--r--arch/blackfin/mach-common/ints-priority.c174
-rw-r--r--arch/blackfin/mm/init.c4
-rw-r--r--arch/cris/arch-v10/kernel/time.c2
-rw-r--r--arch/cris/arch-v10/lib/string.c337
-rw-r--r--arch/cris/arch-v10/lib/usercopy.c2
-rw-r--r--arch/cris/arch-v32/lib/string.c325
-rw-r--r--arch/cris/arch-v32/lib/usercopy.c2
-rw-r--r--arch/frv/kernel/entry.S4
-rw-r--r--arch/frv/kernel/vmlinux.lds.S3
-rw-r--r--arch/h8300/defconfig263
-rw-r--r--arch/h8300/kernel/irq.c4
-rw-r--r--arch/h8300/kernel/signal.c4
-rw-r--r--arch/h8300/platform/h8300h/Makefile2
-rw-r--r--arch/h8300/platform/h8300h/irq.c82
-rw-r--r--arch/h8300/platform/h8s/ints.c304
-rw-r--r--arch/h8300/platform/h8s/irq.c (renamed from arch/h8300/platform/h8s/ints_h8s.c)8
-rw-r--r--arch/ia64/Kconfig3
-rw-r--r--arch/ia64/Makefile2
-rw-r--r--arch/ia64/configs/generic_defconfig (renamed from arch/ia64/defconfig)0
-rw-r--r--arch/ia64/hp/common/hwsw_iommu.c2
-rw-r--r--arch/ia64/hp/common/sba_iommu.c36
-rw-r--r--arch/ia64/hp/sim/simeth.c2
-rw-r--r--arch/ia64/hp/sim/simserial.c2
-rw-r--r--arch/ia64/ia32/ia32_signal.c13
-rw-r--r--arch/ia64/ia32/sys_ia32.c7
-rw-r--r--arch/ia64/kernel/crash.c2
-rw-r--r--arch/ia64/kernel/efi.c32
-rw-r--r--arch/ia64/kernel/iosapic.c28
-rw-r--r--arch/ia64/kernel/irq_ia64.c142
-rw-r--r--arch/ia64/kernel/kprobes.c7
-rw-r--r--arch/ia64/kernel/mca.c73
-rw-r--r--arch/ia64/kernel/module.c22
-rw-r--r--arch/ia64/kernel/msi_ia64.c3
-rw-r--r--arch/ia64/kernel/perfmon.c4
-rw-r--r--arch/ia64/kernel/perfmon_default_smpl.c4
-rw-r--r--arch/ia64/kernel/ptrace.c327
-rw-r--r--arch/ia64/kernel/sal.c7
-rw-r--r--arch/ia64/kernel/setup.c8
-rw-r--r--arch/ia64/kernel/signal.c36
-rw-r--r--arch/ia64/kernel/unaligned.c6
-rw-r--r--arch/ia64/kernel/unwind.c102
-rw-r--r--arch/ia64/mm/fault.c2
-rw-r--r--arch/ia64/mm/init.c2
-rw-r--r--arch/ia64/pci/fixup.c2
-rw-r--r--arch/ia64/pci/pci.c4
-rw-r--r--arch/ia64/sn/kernel/huberror.c4
-rw-r--r--arch/ia64/sn/kernel/io_acpi_init.c36
-rw-r--r--arch/ia64/sn/kernel/io_common.c2
-rw-r--r--arch/ia64/sn/kernel/io_init.c4
-rw-r--r--arch/ia64/sn/kernel/mca.c2
-rw-r--r--arch/ia64/sn/pci/pci_dma.c6
-rw-r--r--arch/ia64/sn/pci/tioca_provider.c12
-rw-r--r--arch/ia64/sn/pci/tioce_provider.c4
-rw-r--r--arch/m68k/kernel/entry.S4
-rw-r--r--arch/m68knommu/defconfig112
-rw-r--r--arch/m68knommu/kernel/syscalltable.S4
-rw-r--r--arch/m68knommu/platform/68328/timers.c10
-rw-r--r--arch/mips/bcm47xx/setup.c12
-rw-r--r--arch/mips/bcm47xx/wgt634u.c71
-rw-r--r--arch/mips/configs/bcm47xx_defconfig1939
-rw-r--r--arch/mips/configs/ip28_defconfig891
-rw-r--r--arch/mips/configs/qemu_defconfig800
-rw-r--r--arch/mips/kernel/irq-rm7000.c1
-rw-r--r--arch/mips/kernel/irq-rm9000.c1
-rw-r--r--arch/mips/kernel/mips-mt-fpaff.c2
-rw-r--r--arch/mips/kernel/scall32-o32.S3
-rw-r--r--arch/mips/kernel/scall64-64.S3
-rw-r--r--arch/mips/kernel/scall64-n32.S3
-rw-r--r--arch/mips/kernel/scall64-o32.S3
-rw-r--r--arch/mips/kernel/sysirix.c2
-rw-r--r--arch/mips/mm/c-r4k.c9
-rw-r--r--arch/mips/mm/cache.c15
-rw-r--r--arch/mips/mm/init.c9
-rw-r--r--arch/mips/mm/pg-sb1.c14
-rw-r--r--arch/mips/pci/pci.c14
-rw-r--r--arch/mips/sibyte/bcm1480/smp.c1
-rw-r--r--arch/mn10300/Kconfig4
-rw-r--r--arch/mn10300/configs/asb2303_defconfig33
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm.c2
-rw-r--r--arch/mn10300/kernel/time.c4
-rw-r--r--arch/mn10300/kernel/traps.c2
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/Makefile2
-rw-r--r--arch/powerpc/boot/Makefile8
-rw-r--r--arch/powerpc/boot/cuboot-bamboo.c1
-rw-r--r--arch/powerpc/boot/cuboot-ebony.c1
-rw-r--r--arch/powerpc/boot/cuboot-katmai.c1
-rw-r--r--arch/powerpc/boot/cuboot-taishan.c2
-rw-r--r--arch/powerpc/boot/cuboot-warp.c1
-rw-r--r--arch/powerpc/boot/dts/bamboo.dts3
-rw-r--r--arch/powerpc/boot/dts/ebony.dts2
-rw-r--r--arch/powerpc/boot/dts/haleakala.dts2
-rw-r--r--arch/powerpc/boot/dts/katmai.dts60
-rw-r--r--arch/powerpc/boot/dts/kilauea.dts3
-rw-r--r--arch/powerpc/boot/dts/makalu.dts3
-rw-r--r--arch/powerpc/boot/dts/rainier.dts4
-rw-r--r--arch/powerpc/boot/dts/sequoia.dts4
-rw-r--r--arch/powerpc/boot/dts/taishan.dts4
-rw-r--r--arch/powerpc/configs/bamboo_defconfig81
-rw-r--r--arch/powerpc/configs/ebony_defconfig79
-rw-r--r--arch/powerpc/configs/ep405_defconfig92
-rw-r--r--arch/powerpc/configs/kilauea_defconfig69
-rw-r--r--arch/powerpc/configs/makalu_defconfig69
-rw-r--r--arch/powerpc/configs/ppc44x_defconfig904
-rw-r--r--arch/powerpc/configs/rainier_defconfig82
-rw-r--r--arch/powerpc/configs/sequoia_defconfig77
-rw-r--r--arch/powerpc/configs/taishan_defconfig81
-rw-r--r--arch/powerpc/configs/walnut_defconfig81
-rw-r--r--arch/powerpc/configs/warp_defconfig139
-rw-r--r--arch/powerpc/kernel/kprobes.c9
-rw-r--r--arch/powerpc/kernel/prom.c13
-rw-r--r--arch/powerpc/oprofile/op_model_cell.c2
-rw-r--r--arch/powerpc/platforms/44x/Kconfig10
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c1
-rw-r--r--arch/powerpc/platforms/cell/iommu.c151
-rw-r--r--arch/powerpc/platforms/cell/setup.c7
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c28
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c7
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c12
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c10
-rw-r--r--arch/powerpc/platforms/cell/spufs/sputrace.c7
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c12
-rw-r--r--arch/powerpc/platforms/celleb/beat.h3
-rw-r--r--arch/powerpc/platforms/pasemi/Makefile2
-rw-r--r--arch/powerpc/platforms/pasemi/misc.c97
-rw-r--r--arch/powerpc/platforms/pseries/power.c2
-rw-r--r--arch/powerpc/sysdev/mpic_pasemi_msi.c5
-rw-r--r--arch/ppc/platforms/4xx/ibm440ep.c6
-rw-r--r--arch/s390/Kconfig8
-rw-r--r--arch/s390/defconfig18
-rw-r--r--arch/s390/kernel/Makefile5
-rw-r--r--arch/s390/kernel/early.c8
-rw-r--r--arch/s390/kernel/ipl.c1
-rw-r--r--arch/s390/kernel/process.c19
-rw-r--r--arch/s390/kernel/smp.c47
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/lib/uaccess_std.c8
-rw-r--r--arch/sh/Kconfig8
-rw-r--r--arch/sh/Makefile1
-rw-r--r--arch/sh/boards/hp6xx/hp6xx_apm.c22
-rw-r--r--arch/sh/boards/renesas/sh7710voipgw/Makefile1
-rw-r--r--arch/sh/boards/renesas/sh7710voipgw/setup.c94
-rw-r--r--arch/sh/boards/renesas/x3proto/ilsel.c2
-rw-r--r--arch/sh/boards/superh/microdev/io.c2
-rw-r--r--arch/sh/configs/r7780mp_defconfig91
-rw-r--r--arch/sh/configs/se7780_defconfig646
-rw-r--r--arch/sh/configs/sh7710voipgw_defconfig595
-rw-r--r--arch/sh/drivers/dma/dma-sh.c2
-rw-r--r--arch/sh/drivers/heartbeat.c2
-rw-r--r--arch/sh/drivers/pci/ops-dreamcast.c44
-rw-r--r--arch/sh/kernel/cpu/init.c2
-rw-r--r--arch/sh/kernel/cpu/sh2/setup-sh7619.c2
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7203.c4
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7203.c2
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c2
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c4
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c2
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh770x.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c2
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7720.c2
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh4-202.c2
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c2
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c2
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c4
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7343.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7366.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7763.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7770.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-shx3.c2
-rw-r--r--arch/sh/kernel/cpu/sh5/unwind.c2
-rw-r--r--arch/sh/kernel/io_trapped.c2
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c5
-rw-r--r--arch/sh/kernel/sh_ksyms_64.c1
-rw-r--r--arch/sh/kernel/timers/timer-cmt.c2
-rw-r--r--arch/sh/kernel/timers/timer-mtu2.c2
-rw-r--r--arch/sh/kernel/topology.c2
-rw-r--r--arch/sh/kernel/traps_64.c2
-rw-r--r--arch/sh/lib64/c-checksum.c2
-rw-r--r--arch/sh/lib64/udelay.c21
-rw-r--r--arch/sh/mm/Kconfig2
-rw-r--r--arch/sh/mm/init.c2
-rw-r--r--arch/sh/mm/ioremap_32.c2
-rw-r--r--arch/sh/mm/ioremap_64.c4
-rw-r--r--arch/sh/mm/pg-sh7705.c1
-rw-r--r--arch/sh/mm/tlbflush_64.c6
-rw-r--r--arch/sh/tools/mach-types1
-rw-r--r--arch/sparc/kernel/Makefile5
-rw-r--r--arch/sparc/kernel/cpu.c4
-rw-r--r--arch/sparc/kernel/ebus.c6
-rw-r--r--arch/sparc/kernel/led.c3
-rw-r--r--arch/sparc/kernel/process.c8
-rw-r--r--arch/sparc/kernel/setup.c4
-rw-r--r--arch/sparc/kernel/una_asm.S153
-rw-r--r--arch/sparc/kernel/unaligned.c252
-rw-r--r--arch/sparc/mm/sun4c.c4
-rw-r--r--arch/sparc/prom/misc.c7
-rw-r--r--arch/sparc64/Kconfig1
-rw-r--r--arch/sparc64/Kconfig.debug4
-rw-r--r--arch/sparc64/Makefile36
-rw-r--r--arch/sparc64/defconfig33
-rw-r--r--arch/sparc64/kernel/cpu.c4
-rw-r--r--arch/sparc64/kernel/ds.c14
-rw-r--r--arch/sparc64/kernel/hvtramp.S4
-rw-r--r--arch/sparc64/kernel/iommu.c6
-rw-r--r--arch/sparc64/kernel/kprobes.c2
-rw-r--r--arch/sparc64/kernel/mdesc.c2
-rw-r--r--arch/sparc64/kernel/pci.c21
-rw-r--r--arch/sparc64/kernel/power.c3
-rw-r--r--arch/sparc64/kernel/process.c94
-rw-r--r--arch/sparc64/kernel/prom.c1
-rw-r--r--arch/sparc64/kernel/setup.c29
-rw-r--r--arch/sparc64/kernel/smp.c2
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c3
-rw-r--r--arch/sparc64/kernel/trampoline.S4
-rw-r--r--arch/sparc64/kernel/traps.c2
-rw-r--r--arch/sparc64/kernel/unaligned.c3
-rw-r--r--arch/sparc64/mm/fault.c14
-rw-r--r--arch/sparc64/mm/init.c52
-rw-r--r--arch/sparc64/prom/misc.c9
-rw-r--r--arch/sparc64/solaris/conv.h2
-rw-r--r--arch/sparc64/solaris/timod.c2
-rw-r--r--arch/um/defconfig280
-rw-r--r--arch/um/drivers/harddog_user.c4
-rw-r--r--arch/um/include/registers.h2
-rw-r--r--arch/um/include/sysdep-i386/ptrace_user.h3
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace_user.h3
-rw-r--r--arch/um/kernel/initrd.c2
-rw-r--r--arch/um/kernel/mem.c6
-rw-r--r--arch/um/kernel/process.c2
-rw-r--r--arch/um/os-Linux/skas/process.c15
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c16
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c10
-rw-r--r--arch/um/sys-i386/user-offsets.c27
-rw-r--r--arch/um/sys-x86_64/user-offsets.c28
-rw-r--r--arch/x86/Kconfig5
-rw-r--r--arch/x86/Kconfig.cpu14
-rw-r--r--arch/x86/Kconfig.debug2
-rw-r--r--arch/x86/Makefile2
-rw-r--r--arch/x86/boot/memory.c9
-rw-r--r--arch/x86/boot/vesa.h9
-rw-r--r--arch/x86/boot/video-vesa.c2
-rw-r--r--arch/x86/ia32/ia32_signal.c4
-rw-r--r--arch/x86/kernel/Makefile10
-rw-r--r--arch/x86/kernel/acpi/boot.c3
-rw-r--r--arch/x86/kernel/asm-offsets_32.c6
-rw-r--r--arch/x86/kernel/cpu/bugs.c8
-rw-r--r--arch/x86/kernel/cpu/common.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/e_powersaver.c8
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c9
-rw-r--r--arch/x86/kernel/cpu/transmeta.c7
-rw-r--r--arch/x86/kernel/efi.c2
-rw-r--r--arch/x86/kernel/efi_32.c1
-rw-r--r--arch/x86/kernel/entry_32.S2
-rw-r--r--arch/x86/kernel/entry_64.S8
-rw-r--r--arch/x86/kernel/head64.c3
-rw-r--r--arch/x86/kernel/head_32.S4
-rw-r--r--arch/x86/kernel/head_64.S31
-rw-r--r--arch/x86/kernel/hpet.c4
-rw-r--r--arch/x86/kernel/i387.c12
-rw-r--r--arch/x86/kernel/i8259_32.c25
-rw-r--r--arch/x86/kernel/init_task.c1
-rw-r--r--arch/x86/kernel/io_delay.c1
-rw-r--r--arch/x86/kernel/kprobes.c4
-rw-r--r--arch/x86/kernel/nmi_32.c21
-rw-r--r--arch/x86/kernel/nmi_64.c21
-rw-r--r--arch/x86/kernel/process_32.c2
-rw-r--r--arch/x86/kernel/process_64.c8
-rw-r--r--arch/x86/kernel/ptrace.c26
-rw-r--r--arch/x86/kernel/reboot.c6
-rw-r--r--arch/x86/kernel/setup_32.c1
-rw-r--r--arch/x86/kernel/setup_64.c8
-rw-r--r--arch/x86/kernel/signal_32.c4
-rw-r--r--arch/x86/kernel/signal_64.c2
-rw-r--r--arch/x86/kernel/smpboot_64.c2
-rw-r--r--arch/x86/kernel/stacktrace.c4
-rw-r--r--arch/x86/kernel/step.c4
-rw-r--r--arch/x86/kernel/tls.c8
-rw-r--r--arch/x86/kernel/topology.c2
-rw-r--r--arch/x86/kernel/tsc_32.c3
-rw-r--r--arch/x86/kernel/vmlinux_32.lds.S26
-rw-r--r--arch/x86/kernel/vmlinux_64.lds.S30
-rw-r--r--arch/x86/kernel/vsyscall_64.c49
-rw-r--r--arch/x86/kvm/lapic.c4
-rw-r--r--arch/x86/kvm/mmu.c38
-rw-r--r--arch/x86/kvm/paging_tmpl.h20
-rw-r--r--arch/x86/kvm/svm.c26
-rw-r--r--arch/x86/kvm/vmx.c14
-rw-r--r--arch/x86/kvm/x86.c114
-rw-r--r--arch/x86/lguest/boot.c12
-rw-r--r--arch/x86/lib/csum-wrappers_64.c147
-rw-r--r--arch/x86/lib/io_64.c18
-rw-r--r--arch/x86/mm/init_64.c36
-rw-r--r--arch/x86/mm/ioremap.c28
-rw-r--r--arch/x86/mm/numa_64.c13
-rw-r--r--arch/x86/mm/pageattr.c316
-rw-r--r--arch/x86/mm/srat_64.c3
-rw-r--r--arch/x86/pci/common.c2
-rw-r--r--arch/x86/pci/irq.c4
-rw-r--r--arch/x86/power/hibernate_asm_64.S5
-rw-r--r--arch/x86/vdso/Makefile4
-rw-r--r--arch/x86/xen/enlighten.c1
-rw-r--r--arch/x86/xen/setup.c3
-rw-r--r--arch/xtensa/Makefile2
-rw-r--r--arch/xtensa/boot/boot-elf/Makefile9
-rw-r--r--arch/xtensa/boot/boot-elf/boot.lds.S (renamed from arch/xtensa/boot/boot-elf/boot.ld)4
-rw-r--r--arch/xtensa/boot/boot-redboot/Makefile2
-rw-r--r--arch/xtensa/boot/boot-redboot/boot.ld2
-rw-r--r--arch/xtensa/kernel/asm-offsets.c17
-rw-r--r--arch/xtensa/kernel/coprocessor.S443
-rw-r--r--arch/xtensa/kernel/entry.S355
-rw-r--r--arch/xtensa/kernel/module.c2
-rw-r--r--arch/xtensa/kernel/process.c306
-rw-r--r--arch/xtensa/kernel/ptrace.c351
-rw-r--r--arch/xtensa/kernel/setup.c5
-rw-r--r--arch/xtensa/kernel/signal.c89
-rw-r--r--arch/xtensa/kernel/traps.c20
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S6
-rw-r--r--arch/xtensa/mm/cache.c7
-rw-r--r--arch/xtensa/mm/init.c2
-rw-r--r--arch/xtensa/mm/misc.S2
-rw-r--r--arch/xtensa/platforms/iss/Makefile (renamed from arch/xtensa/platform-iss/Makefile)0
-rw-r--r--arch/xtensa/platforms/iss/console.c (renamed from arch/xtensa/platform-iss/console.c)1
-rw-r--r--arch/xtensa/platforms/iss/io.c (renamed from arch/xtensa/platform-iss/io.c)0
-rw-r--r--arch/xtensa/platforms/iss/network.c (renamed from arch/xtensa/platform-iss/network.c)2
-rw-r--r--arch/xtensa/platforms/iss/setup.c (renamed from arch/xtensa/platform-iss/setup.c)0
-rw-r--r--block/blk-barrier.c9
-rw-r--r--block/blk-core.c7
-rw-r--r--block/blk-ioc.c37
-rw-r--r--block/blk-map.c27
-rw-r--r--block/blk-merge.c6
-rw-r--r--block/blk-settings.c29
-rw-r--r--block/blk-tag.c2
-rw-r--r--block/blk.h2
-rw-r--r--block/cfq-iosched.c38
-rw-r--r--block/elevator.c15
-rw-r--r--block/genhd.c10
-rw-r--r--block/scsi_ioctl.c1
-rw-r--r--drivers/acorn/char/defkeymap-l7200.c68
-rw-r--r--drivers/acpi/ec.c6
-rw-r--r--drivers/acpi/executer/exregion.c5
-rw-r--r--drivers/acpi/fan.c30
-rw-r--r--drivers/acpi/processor_core.c39
-rw-r--r--drivers/acpi/processor_idle.c10
-rw-r--r--drivers/acpi/utils.c18
-rw-r--r--drivers/acpi/video.c3
-rw-r--r--drivers/ata/ahci.c44
-rw-r--r--drivers/ata/ata_piix.c4
-rw-r--r--drivers/ata/libata-core.c646
-rw-r--r--drivers/ata/libata-eh.c8
-rw-r--r--drivers/ata/libata-pmp.c4
-rw-r--r--drivers/ata/libata-scsi.c94
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--drivers/ata/pata_acpi.c4
-rw-r--r--drivers/ata/pata_amd.c7
-rw-r--r--drivers/ata/pata_atiixp.c4
-rw-r--r--drivers/ata/pata_cs5536.c10
-rw-r--r--drivers/ata/pata_hpt366.c6
-rw-r--r--drivers/ata/pata_hpt37x.c6
-rw-r--r--drivers/ata/pata_icside.c8
-rw-r--r--drivers/ata/pata_jmicron.c3
-rw-r--r--drivers/ata/pata_legacy.c46
-rw-r--r--drivers/ata/pata_marvell.c4
-rw-r--r--drivers/ata/pata_scc.c2
-rw-r--r--drivers/ata/pata_serverworks.c2
-rw-r--r--drivers/ata/sata_fsl.c21
-rw-r--r--drivers/ata/sata_mv.c19
-rw-r--r--drivers/ata/sata_promise.c2
-rw-r--r--drivers/ata/sata_sil24.c5
-rw-r--r--drivers/ata/sata_svw.c77
-rw-r--r--drivers/ata/sata_via.c4
-rw-r--r--drivers/base/bus.c9
-rw-r--r--drivers/base/core.c14
-rw-r--r--drivers/base/driver.c3
-rw-r--r--drivers/base/power/main.c112
-rw-r--r--drivers/base/transport_class.c4
-rw-r--r--drivers/block/cciss.c256
-rw-r--r--drivers/block/cciss_scsi.c10
-rw-r--r--drivers/block/nbd.c6
-rw-r--r--drivers/block/pktcdvd.c21
-rw-r--r--drivers/block/xen-blkfront.c18
-rw-r--r--drivers/bluetooth/hci_ldisc.c1
-rw-r--r--drivers/bluetooth/hci_usb.c1
-rw-r--r--drivers/cdrom/cdrom.c4
-rw-r--r--drivers/char/agp/amd-k7-agp.c9
-rw-r--r--drivers/char/agp/ati-agp.c16
-rw-r--r--drivers/char/agp/generic.c9
-rw-r--r--drivers/char/agp/sis-agp.c47
-rw-r--r--drivers/char/agp/sworks-agp.c18
-rw-r--r--drivers/char/defkeymap.c_shipped68
-rw-r--r--drivers/char/drm/drmP.h2
-rw-r--r--drivers/char/drm/drm_pciids.h3
-rw-r--r--drivers/char/drm/drm_sysfs.c2
-rw-r--r--drivers/char/drm/drm_vm.c125
-rw-r--r--drivers/char/drm/i915_dma.c5
-rw-r--r--drivers/char/drm/i915_drv.c52
-rw-r--r--drivers/char/drm/i915_drv.h17
-rw-r--r--drivers/char/drm/radeon_cp.c81
-rw-r--r--drivers/char/drm/radeon_drv.h38
-rw-r--r--drivers/char/esp.c1
-rw-r--r--drivers/char/isicom.c2
-rw-r--r--drivers/char/pcmcia/ipwireless/network.c5
-rw-r--r--drivers/char/rtc.c4
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/vt.c1
-rw-r--r--drivers/char/xilinx_hwicap/buffer_icap.c80
-rw-r--r--drivers/char/xilinx_hwicap/fifo_icap.c60
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c138
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.h24
-rw-r--r--drivers/connector/connector.c2
-rw-r--r--drivers/cpufreq/cpufreq.c28
-rw-r--r--drivers/cpufreq/cpufreq_stats.c2
-rw-r--r--drivers/dma/Kconfig19
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/fsldma.c1067
-rw-r--r--drivers/dma/fsldma.h189
-rw-r--r--drivers/dma/ioat_dma.c2
-rw-r--r--drivers/firewire/fw-card.c61
-rw-r--r--drivers/firewire/fw-cdev.c17
-rw-r--r--drivers/firewire/fw-device.c69
-rw-r--r--drivers/firewire/fw-device.h18
-rw-r--r--drivers/firewire/fw-sbp2.c392
-rw-r--r--drivers/firewire/fw-topology.c1
-rw-r--r--drivers/firewire/fw-transaction.h2
-rw-r--r--drivers/firmware/dmi_scan.c82
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/ad7418.c2
-rw-r--r--drivers/hwmon/adm1021.c6
-rw-r--r--drivers/hwmon/adm1025.c2
-rw-r--r--drivers/hwmon/adm1026.c4
-rw-r--r--drivers/hwmon/adm1029.c6
-rw-r--r--drivers/hwmon/adm1031.c2
-rw-r--r--drivers/hwmon/adm9240.c2
-rw-r--r--drivers/hwmon/ads7828.c2
-rw-r--r--drivers/hwmon/adt7470.c2
-rw-r--r--drivers/hwmon/adt7473.c1157
-rw-r--r--drivers/hwmon/applesmc.c29
-rw-r--r--drivers/hwmon/asb100.c2
-rw-r--r--drivers/hwmon/atxp1.c2
-rw-r--r--drivers/hwmon/coretemp.c119
-rw-r--r--drivers/hwmon/dme1737.c2
-rw-r--r--drivers/hwmon/ds1621.c2
-rw-r--r--drivers/hwmon/f75375s.c2
-rw-r--r--drivers/hwmon/fscher.c2
-rw-r--r--drivers/hwmon/fschmd.c2
-rw-r--r--drivers/hwmon/fscpos.c2
-rw-r--r--drivers/hwmon/gl518sm.c2
-rw-r--r--drivers/hwmon/gl520sm.c2
-rw-r--r--drivers/hwmon/lm63.c2
-rw-r--r--drivers/hwmon/lm75.c2
-rw-r--r--drivers/hwmon/lm77.c3
-rw-r--r--drivers/hwmon/lm78.c4
-rw-r--r--drivers/hwmon/lm80.c4
-rw-r--r--drivers/hwmon/lm83.c6
-rw-r--r--drivers/hwmon/lm85.c2
-rw-r--r--drivers/hwmon/lm87.c2
-rw-r--r--drivers/hwmon/lm90.c6
-rw-r--r--drivers/hwmon/lm92.c20
-rw-r--r--drivers/hwmon/lm93.c2
-rw-r--r--drivers/hwmon/max1619.c23
-rw-r--r--drivers/hwmon/max6650.c3
-rw-r--r--drivers/hwmon/smsc47m1.c25
-rw-r--r--drivers/hwmon/smsc47m192.c2
-rw-r--r--drivers/hwmon/thmc50.c8
-rw-r--r--drivers/hwmon/via686a.c28
-rw-r--r--drivers/hwmon/vt8231.c44
-rw-r--r--drivers/hwmon/w83781d.c4
-rw-r--r--drivers/hwmon/w83791d.c3
-rw-r--r--drivers/hwmon/w83792d.c3
-rw-r--r--drivers/hwmon/w83793.c3
-rw-r--r--drivers/hwmon/w83l785ts.c2
-rw-r--r--drivers/hwmon/w83l786ng.c2
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-i801.c10
-rw-r--r--drivers/i2c/busses/i2c-pca-isa.c7
-rw-r--r--drivers/i2c/busses/i2c-pmcmsp.c4
-rw-r--r--drivers/i2c/busses/i2c-pxa.c29
-rw-r--r--drivers/ide/Kconfig30
-rw-r--r--drivers/ide/ide-cd.c36
-rw-r--r--drivers/ide/ide-cd_ioctl.c4
-rw-r--r--drivers/ide/ide-disk.c6
-rw-r--r--drivers/ide/ide-dma.c54
-rw-r--r--drivers/ide/ide-generic.c6
-rw-r--r--drivers/ide/ide-probe.c3
-rw-r--r--drivers/ide/ide-tape.c5
-rw-r--r--drivers/ide/ide.c26
-rw-r--r--drivers/ide/legacy/falconide.c4
-rw-r--r--drivers/ide/legacy/ht6560b.c25
-rw-r--r--drivers/ide/legacy/macide.c2
-rw-r--r--drivers/ide/legacy/qd65xx.c43
-rw-r--r--drivers/ide/pci/cmd640.c3
-rw-r--r--drivers/ide/pci/hpt366.c12
-rw-r--r--drivers/ide/pci/via82cxxx.c1
-rw-r--r--drivers/ide/ppc/pmac.c4
-rw-r--r--drivers/ieee1394/sbp2.c15
-rw-r--r--drivers/ieee1394/sbp2.h2
-rw-r--r--drivers/infiniband/core/sysfs.c4
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_mem.c10
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c2
-rw-r--r--drivers/infiniband/hw/nes/nes.c2
-rw-r--r--drivers/infiniband/hw/nes/nes.h15
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c15
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c13
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c62
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c12
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c10
-rw-r--r--drivers/input/misc/Kconfig6
-rw-r--r--drivers/isdn/gigaset/common.c6
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c34
-rw-r--r--drivers/isdn/i4l/isdn_ttyfax.c3
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c6
-rw-r--r--drivers/macintosh/mediabay.c3
-rw-r--r--drivers/md/bitmap.c19
-rw-r--r--drivers/md/dm-raid1.c7
-rw-r--r--drivers/md/md.c48
-rw-r--r--drivers/md/raid1.c73
-rw-r--r--drivers/md/raid10.c87
-rw-r--r--drivers/media/Kconfig18
-rw-r--r--drivers/media/common/Kconfig2
-rw-r--r--drivers/media/common/ir-keymaps.c46
-rw-r--r--drivers/media/common/saa7146_vbi.c1
-rw-r--r--drivers/media/common/saa7146_video.c2
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c23
-rw-r--r--drivers/media/dvb/dvb-usb/ttusb2.c1
-rw-r--r--drivers/media/dvb/frontends/tda10086.c28
-rw-r--r--drivers/media/dvb/frontends/tda10086.h3
-rw-r--r--drivers/media/dvb/frontends/tda18271-common.c2
-rw-r--r--drivers/media/dvb/frontends/xc5000.h3
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c15
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c8
-rw-r--r--drivers/media/dvb/ttpci/budget.c1
-rw-r--r--drivers/media/radio/Kconfig4
-rw-r--r--drivers/media/radio/radio-sf16fmi.c1
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c5
-rw-r--r--drivers/media/radio/radio-si470x.c597
-rw-r--r--drivers/media/video/Kconfig4
-rw-r--r--drivers/media/video/Makefile5
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c51
-rw-r--r--drivers/media/video/bt8xx/bttv-vbi.c4
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c16
-rw-r--r--drivers/media/video/cx88/cx88.h1
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c6
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c8
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c111
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c79
-rw-r--r--drivers/media/video/em28xx/em28xx.h5
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c123
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c28
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c20
-rw-r--r--drivers/media/video/saa7134/saa7134.h2
-rw-r--r--drivers/media/video/stk-sensor.c23
-rw-r--r--drivers/media/video/stk-webcam.c104
-rw-r--r--drivers/media/video/stk-webcam.h3
-rw-r--r--drivers/media/video/tcm825x.c2
-rw-r--r--drivers/media/video/tuner-core.c2
-rw-r--r--drivers/media/video/tuner-xc2028.c3
-rw-r--r--drivers/media/video/tvaudio.c10
-rw-r--r--drivers/media/video/tveeprom.c2
-rw-r--r--drivers/media/video/v4l2-common.c393
-rw-r--r--drivers/media/video/videobuf-core.c78
-rw-r--r--drivers/media/video/videobuf-dma-sg.c4
-rw-r--r--drivers/media/video/videobuf-vmalloc.c20
-rw-r--r--drivers/media/video/videodev.c444
-rw-r--r--drivers/media/video/zoran.h22
-rw-r--r--drivers/media/video/zoran_device.c12
-rw-r--r--drivers/media/video/zr364xx.c2
-rw-r--r--drivers/message/fusion/mptbase.c29
-rw-r--r--drivers/message/fusion/mptbase.h2
-rw-r--r--drivers/message/fusion/mptsas.c5
-rw-r--r--drivers/message/fusion/mptscsih.c14
-rw-r--r--drivers/mfd/sm501.c208
-rw-r--r--drivers/misc/Kconfig17
-rw-r--r--drivers/misc/acer-wmi.c9
-rw-r--r--drivers/misc/intel_menlow.c11
-rw-r--r--drivers/misc/thinkpad_acpi.c124
-rw-r--r--drivers/mtd/ubi/build.c4
-rw-r--r--drivers/mtd/ubi/ubi.h10
-rw-r--r--drivers/mtd/ubi/vmt.c4
-rw-r--r--drivers/mtd/ubi/vtbl.c1
-rw-r--r--drivers/net/8139too.c2
-rw-r--r--drivers/net/Kconfig24
-rw-r--r--drivers/net/Makefile3
-rw-r--r--drivers/net/bnx2.c50
-rw-r--r--drivers/net/bnx2.h1
-rw-r--r--drivers/net/bnx2x.c2663
-rw-r--r--drivers/net/bnx2x.h56
-rw-r--r--drivers/net/bnx2x_fw_defs.h2
-rw-r--r--drivers/net/bnx2x_hsi.h428
-rw-r--r--drivers/net/bnx2x_init.h12
-rw-r--r--drivers/net/bnx2x_reg.h212
-rw-r--r--drivers/net/cs89x0.c12
-rw-r--r--drivers/net/cxgb3/l2t.c2
-rw-r--r--drivers/net/cxgb3/sge.c35
-rw-r--r--drivers/net/dm9000.c654
-rw-r--r--drivers/net/e1000/e1000_ethtool.c2
-rw-r--r--drivers/net/e1000/e1000_main.c26
-rw-r--r--drivers/net/e1000e/82571.c22
-rw-r--r--drivers/net/e1000e/defines.h10
-rw-r--r--drivers/net/e1000e/e1000.h3
-rw-r--r--drivers/net/e1000e/hw.h4
-rw-r--r--drivers/net/e1000e/ich8lan.c24
-rw-r--r--drivers/net/e1000e/lib.c50
-rw-r--r--drivers/net/e1000e/netdev.c52
-rw-r--r--drivers/net/e1000e/phy.c10
-rw-r--r--drivers/net/ehea/ehea.h34
-rw-r--r--drivers/net/ehea/ehea_main.c281
-rw-r--r--drivers/net/fec.c8
-rw-r--r--drivers/net/forcedeth.c132
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c7
-rw-r--r--drivers/net/gianfar.c18
-rw-r--r--drivers/net/gianfar_mii.c4
-rw-r--r--drivers/net/hamradio/mkiss.c5
-rw-r--r--drivers/net/ibm_newemac/rgmii.c1
-rw-r--r--drivers/net/igb/igb_ethtool.c2
-rw-r--r--drivers/net/igb/igb_main.c43
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c3
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c41
-rw-r--r--drivers/net/macb.c2
-rw-r--r--drivers/net/netconsole.c4
-rw-r--r--drivers/net/ni52.c1142
-rw-r--r--drivers/net/ni52.h158
-rw-r--r--drivers/net/niu.c20
-rw-r--r--drivers/net/niu.h2
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c10
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c12
-rw-r--r--drivers/net/pcnet32.c48
-rw-r--r--drivers/net/phy/fixed.c4
-rw-r--r--drivers/net/phy/mdio_bus.c4
-rw-r--r--drivers/net/pppol2tp.c8
-rw-r--r--drivers/net/ps3_gelic_net.c1215
-rw-r--r--drivers/net/ps3_gelic_net.h415
-rw-r--r--drivers/net/ps3_gelic_wireless.c2754
-rw-r--r--drivers/net/ps3_gelic_wireless.h329
-rw-r--r--drivers/net/r6040.c233
-rw-r--r--drivers/net/sis190.c18
-rw-r--r--drivers/net/sky2.c123
-rw-r--r--drivers/net/sky2.h27
-rw-r--r--drivers/net/tg3.c2
-rw-r--r--drivers/net/tlan.c64
-rw-r--r--drivers/net/tsi108_eth.c72
-rw-r--r--drivers/net/tulip/uli526x.c12
-rw-r--r--drivers/net/tun.c6
-rw-r--r--drivers/net/veth.c53
-rw-r--r--drivers/net/via-rhine.c2
-rw-r--r--drivers/net/virtio_net.c2
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h2
-rw-r--r--drivers/net/wireless/ath5k/base.c24
-rw-r--r--drivers/net/wireless/ath5k/hw.c42
-rw-r--r--drivers/net/wireless/b43/Kconfig1
-rw-r--r--drivers/net/wireless/b43/b43.h6
-rw-r--r--drivers/net/wireless/b43/main.c40
-rw-r--r--drivers/net/wireless/b43legacy/Kconfig1
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h4
-rw-r--r--drivers/net/wireless/b43legacy/dma.c167
-rw-r--r--drivers/net/wireless/b43legacy/dma.h33
-rw-r--r--drivers/net/wireless/b43legacy/main.c41
-rw-r--r--drivers/net/wireless/bcm43xx/Kconfig2
-rw-r--r--drivers/net/wireless/ipw2200.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c17
-rw-r--r--drivers/net/wireless/libertas/cmd.c2
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c8
-rw-r--r--drivers/net/wireless/libertas/decl.h1
-rw-r--r--drivers/net/wireless/libertas/main.c17
-rw-r--r--drivers/net/wireless/p54common.c20
-rw-r--r--drivers/net/wireless/p54common.h8
-rw-r--r--drivers/net/wireless/p54usb.c2
-rw-r--r--drivers/net/wireless/rndis_wlan.c36
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c73
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c6
-rw-r--r--drivers/net/wireless/rtl8180_dev.c4
-rw-r--r--drivers/net/wireless/rtl8187_dev.c4
-rw-r--r--drivers/net/wireless/wavelan.h6
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c12
-rw-r--r--drivers/parisc/Kconfig5
-rw-r--r--drivers/parisc/ccio-dma.c27
-rw-r--r--drivers/parisc/iommu-helpers.h6
-rw-r--r--drivers/parisc/sba_iommu.c52
-rw-r--r--drivers/pci/bus.c10
-rw-r--r--drivers/pci/dmar.c9
-rw-r--r--drivers/pci/hotplug-pci.c2
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c6
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c2
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c33
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_pci.c2
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c5
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c2
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c2
-rw-r--r--drivers/pci/intel-iommu.c7
-rw-r--r--drivers/pci/intel-iommu.h5
-rw-r--r--drivers/pci/iova.c3
-rw-r--r--drivers/pci/iova.h3
-rw-r--r--drivers/pci/pci-acpi.c3
-rw-r--r--drivers/pci/pci.c1
-rw-r--r--drivers/pci/probe.c8
-rw-r--r--drivers/pci/proc.c2
-rw-r--r--drivers/pci/quirks.c110
-rw-r--r--drivers/pci/rom.c3
-rw-r--r--drivers/pci/setup-bus.c6
-rw-r--r--drivers/pcmcia/i82092.c7
-rw-r--r--drivers/rapidio/rio-driver.c8
-rw-r--r--drivers/rtc/Kconfig9
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-cmos.c2
-rw-r--r--drivers/rtc/rtc-s35390a.c316
-rw-r--r--drivers/s390/block/dasd.c12
-rw-r--r--drivers/s390/block/dasd_3990_erp.c6
-rw-r--r--drivers/s390/block/dasd_proc.c4
-rw-r--r--drivers/s390/block/dcssblk.c2
-rw-r--r--drivers/s390/char/defkeymap.c4
-rw-r--r--drivers/s390/char/sclp.c12
-rw-r--r--drivers/s390/char/sclp.h6
-rw-r--r--drivers/s390/char/sclp_config.c2
-rw-r--r--drivers/s390/char/sclp_cpi_sys.c2
-rw-r--r--drivers/s390/char/sclp_rw.c4
-rw-r--r--drivers/s390/char/sclp_vt220.c4
-rw-r--r--drivers/s390/cio/device.c15
-rw-r--r--drivers/s390/cio/qdio.c13
-rw-r--r--drivers/s390/cio/qdio.h2
-rw-r--r--drivers/s390/crypto/ap_bus.c12
-rw-r--r--drivers/s390/net/claw.c39
-rw-r--r--drivers/s390/net/claw.h19
-rw-r--r--drivers/s390/net/lcs.c2
-rw-r--r--drivers/s390/net/lcs.h16
-rw-r--r--drivers/s390/net/netiucv.c29
-rw-r--r--drivers/scsi/Kconfig10
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm_pci.c2
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_core.c11
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm_pci.c2
-rw-r--r--drivers/scsi/aic94xx/aic94xx.h1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_hwi.h3
-rw-r--r--drivers/scsi/aic94xx/aic94xx_init.c2
-rw-r--r--drivers/scsi/aic94xx/aic94xx_scb.c14
-rw-r--r--drivers/scsi/aic94xx/aic94xx_task.c4
-rw-r--r--drivers/scsi/aic94xx/aic94xx_tmf.c308
-rw-r--r--drivers/scsi/arcmsr/arcmsr.h2
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c26
-rw-r--r--drivers/scsi/arm/fas216.h2
-rw-r--r--drivers/scsi/gdth.c112
-rw-r--r--drivers/scsi/gdth.h1
-rw-r--r--drivers/scsi/gdth_proc.c6
-rw-r--r--drivers/scsi/ibmvscsi/ibmvstgt.c9
-rw-r--r--drivers/scsi/ipr.c4
-rw-r--r--drivers/scsi/ips.c2
-rw-r--r--drivers/scsi/libiscsi.c4
-rw-r--r--drivers/scsi/libsas/sas_ata.c43
-rw-r--r--drivers/scsi/libsas/sas_port.c11
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c102
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c18
-rw-r--r--drivers/scsi/megaraid.c10
-rw-r--r--drivers/scsi/mesh.c1
-rw-r--r--drivers/scsi/mvsas.c2969
-rw-r--r--drivers/scsi/ps3rom.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_dfs.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c11
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c5
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c3
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c39
-rw-r--r--drivers/scsi/qlogicpti.c12
-rw-r--r--drivers/scsi/scsi.c2
-rw-r--r--drivers/scsi/scsi_debug.c2
-rw-r--r--drivers/scsi/scsi_lib.c8
-rw-r--r--drivers/scsi/scsi_scan.c3
-rw-r--r--drivers/scsi/scsi_tgt_lib.c6
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c80
-rw-r--r--drivers/scsi/sd.c3
-rw-r--r--drivers/scsi/ses.c126
-rw-r--r--drivers/scsi/st.c11
-rw-r--r--drivers/scsi/st.h1
-rw-r--r--drivers/scsi/stex.c44
-rw-r--r--drivers/serial/8250_pnp.c2
-rw-r--r--drivers/serial/Kconfig6
-rw-r--r--drivers/serial/atmel_serial.c2
-rw-r--r--drivers/serial/bfin_5xx.c281
-rw-r--r--drivers/serial/m32r_sio.c2
-rw-r--r--drivers/serial/sh-sci.c2
-rw-r--r--drivers/sh/maple/maple.c66
-rw-r--r--drivers/spi/atmel_spi.c10
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c11
-rw-r--r--drivers/spi/pxa2xx_spi.c41
-rw-r--r--drivers/ssb/Kconfig11
-rw-r--r--drivers/ssb/Makefile3
-rw-r--r--drivers/ssb/driver_chipcommon.c65
-rw-r--r--drivers/ssb/driver_extif.c25
-rw-r--r--drivers/ssb/driver_pcicore.c52
-rw-r--r--drivers/ssb/embedded.c132
-rw-r--r--drivers/ssb/main.c4
-rw-r--r--drivers/ssb/ssb_private.h4
-rw-r--r--drivers/thermal/thermal.c39
-rw-r--r--drivers/uio/uio.c54
-rw-r--r--drivers/usb/class/cdc-acm.c10
-rw-r--r--drivers/usb/class/usblp.c1
-rw-r--r--drivers/usb/core/Kconfig9
-rw-r--r--drivers/usb/core/quirks.c25
-rw-r--r--drivers/usb/core/usb.c8
-rw-r--r--drivers/usb/gadget/ether.c1
-rw-r--r--drivers/usb/gadget/printer.c3
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c88
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.h4
-rw-r--r--drivers/usb/host/Kconfig5
-rw-r--r--drivers/usb/host/ehci-hcd.c26
-rw-r--r--drivers/usb/host/ehci-q.c2
-rw-r--r--drivers/usb/host/isp116x-hcd.c15
-rw-r--r--drivers/usb/host/isp116x.h1
-rw-r--r--drivers/usb/host/sl811-hcd.c1
-rw-r--r--drivers/usb/host/u132-hcd.c15
-rw-r--r--drivers/usb/misc/ldusb.c2
-rw-r--r--drivers/usb/misc/trancevibrator.c4
-rw-r--r--drivers/usb/serial/ftdi_sio.c29
-rw-r--r--drivers/usb/serial/ftdi_sio.h7
-rw-r--r--drivers/usb/serial/mos7840.c15
-rw-r--r--drivers/usb/serial/option.c47
-rw-r--r--drivers/usb/serial/sierra.c1
-rw-r--r--drivers/usb/storage/protocol.c27
-rw-r--r--drivers/usb/storage/transport.c11
-rw-r--r--drivers/usb/storage/unusual_devs.h34
-rw-r--r--drivers/video/aty/atyfb_base.c64
-rw-r--r--drivers/video/cg14.c1
-rw-r--r--drivers/video/chipsfb.c2
-rw-r--r--drivers/video/hitfb.c4
-rw-r--r--drivers/video/nvidia/nvidia.c2
-rw-r--r--drivers/video/pvr2fb.c12
-rw-r--r--drivers/video/pxafb.c8
-rw-r--r--drivers/video/sbuslib.c1
-rw-r--r--drivers/video/sm501fb.c20
-rw-r--r--drivers/video/tridentfb.c65
-rw-r--r--drivers/video/uvesafb.c2
-rw-r--r--drivers/w1/masters/ds1wm.c23
-rw-r--r--drivers/watchdog/Kconfig25
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/bfin_wdt.c7
-rw-r--r--drivers/watchdog/hpwdt.c926
-rw-r--r--drivers/watchdog/mtx-1_wdt.c35
-rw-r--r--drivers/watchdog/sb_wdog.c353
-rw-r--r--fs/binfmt_elf.c15
-rw-r--r--fs/bio.c2
-rw-r--r--fs/block_dev.c201
-rw-r--r--fs/buffer.c5
-rw-r--r--fs/cifs/CHANGES4
-rw-r--r--fs/cifs/README2
-rw-r--r--fs/cifs/cifs_debug.c17
-rw-r--r--fs/cifs/cifs_debug.h9
-rw-r--r--fs/cifs/cifs_dfs_ref.c2
-rw-r--r--fs/cifs/cifs_spnego.c2
-rw-r--r--fs/cifs/cifs_unicode.c4
-rw-r--r--fs/cifs/cifs_unicode.h9
-rw-r--r--fs/cifs/cifsacl.c57
-rw-r--r--fs/cifs/cifsfs.c15
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/cifsproto.h22
-rw-r--r--fs/cifs/cifssmb.c218
-rw-r--r--fs/cifs/connect.c50
-rw-r--r--fs/cifs/dir.c20
-rw-r--r--fs/cifs/dns_resolve.h2
-rw-r--r--fs/cifs/fcntl.c6
-rw-r--r--fs/cifs/file.c33
-rw-r--r--fs/cifs/inode.c399
-rw-r--r--fs/cifs/ioctl.c2
-rw-r--r--fs/cifs/md4.c4
-rw-r--r--fs/cifs/md5.c9
-rw-r--r--fs/cifs/misc.c14
-rw-r--r--fs/cifs/netmisc.c23
-rw-r--r--fs/cifs/readdir.c54
-rw-r--r--fs/cifs/sess.c4
-rw-r--r--fs/cifs/smbdes.c22
-rw-r--r--fs/cifs/transport.c11
-rw-r--r--fs/cifs/xattr.c9
-rw-r--r--fs/compat.c3
-rw-r--r--fs/debugfs/inode.c4
-rw-r--r--fs/dlm/rcom.c2
-rw-r--r--fs/ecryptfs/mmap.c102
-rw-r--r--fs/efs/dir.c2
-rw-r--r--fs/efs/efs.h140
-rw-r--r--fs/efs/file.c2
-rw-r--r--fs/efs/inode.c4
-rw-r--r--fs/efs/namei.c2
-rw-r--r--fs/efs/super.c7
-rw-r--r--fs/efs/symlink.c2
-rw-r--r--fs/exec.c10
-rw-r--r--fs/ext3/super.c2
-rw-r--r--fs/ext4/dir.c2
-rw-r--r--fs/ext4/extents.c59
-rw-r--r--fs/ext4/ialloc.c22
-rw-r--r--fs/ext4/inode.c56
-rw-r--r--fs/ext4/mballoc.c80
-rw-r--r--fs/ext4/migrate.c5
-rw-r--r--fs/ext4/namei.c18
-rw-r--r--fs/ext4/resize.c1
-rw-r--r--fs/fuse/dir.c2
-rw-r--r--fs/jbd/transaction.c17
-rw-r--r--fs/lockd/svc.c2
-rw-r--r--fs/mpage.c11
-rw-r--r--fs/nfs/callback.c21
-rw-r--r--fs/nfs/callback_xdr.c6
-rw-r--r--fs/nfs/delegation.c2
-rw-r--r--fs/nfs/dir.c10
-rw-r--r--fs/nfs/idmap.c2
-rw-r--r--fs/nfs/inode.c6
-rw-r--r--fs/nfs/internal.h3
-rw-r--r--fs/nfs/nfs4state.c6
-rw-r--r--fs/nfs/super.c68
-rw-r--r--fs/nfs/write.c2
-rw-r--r--fs/nfsd/nfsfh.c2
-rw-r--r--fs/ocfs2/aops.c2
-rw-r--r--fs/ocfs2/dir.c5
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c6
-rw-r--r--fs/ocfs2/dlmglue.c8
-rw-r--r--fs/ocfs2/dlmglue.h2
-rw-r--r--fs/ocfs2/heartbeat.c26
-rw-r--r--fs/ocfs2/heartbeat.h5
-rw-r--r--fs/ocfs2/localalloc.c6
-rw-r--r--fs/proc/base.c28
-rw-r--r--fs/proc/proc_misc.c3
-rw-r--r--fs/proc/task_mmu.c2
-rw-r--r--fs/reiserfs/super.c2
-rw-r--r--fs/splice.c12
-rw-r--r--fs/super.c4
-rw-r--r--fs/ufs/util.h2
-rw-r--r--fs/xfs/Kbuild6
-rw-r--r--fs/xfs/Makefile118
-rw-r--r--fs/xfs/Makefile-linux-2.6117
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c14
-rw-r--r--fs/xfs/xfs_bit.c103
-rw-r--r--fs/xfs/xfs_bit.h27
-rw-r--r--fs/xfs/xfs_clnt.h2
-rw-r--r--fs/xfs/xfs_ialloc.c2
-rw-r--r--fs/xfs/xfs_iget.c1
-rw-r--r--fs/xfs/xfs_mount.h2
-rw-r--r--fs/xfs/xfs_rtalloc.c19
-rw-r--r--fs/xfs/xfs_trans_ail.c17
-rw-r--r--fs/xfs/xfs_vfsops.c4
-rw-r--r--include/asm-arm/arch-pxa/entry-macro.S2
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h3
-rw-r--r--include/asm-arm/arch-pxa/regs-ssp.h1
-rw-r--r--include/asm-arm/kexec.h2
-rw-r--r--include/asm-arm/kprobes.h1
-rw-r--r--include/asm-arm/mach/arch.h2
-rw-r--r--include/asm-arm/unaligned.h8
-rw-r--r--include/asm-avr32/pgtable.h1
-rw-r--r--include/asm-blackfin/gptimers.h7
-rw-r--r--include/asm-blackfin/irq.h2
-rw-r--r--include/asm-blackfin/mach-bf527/bfin_serial_5xx.h22
-rw-r--r--include/asm-blackfin/mach-bf533/bfin_serial_5xx.h24
-rw-r--r--include/asm-blackfin/mach-bf537/bfin_serial_5xx.h22
-rw-r--r--include/asm-blackfin/mach-bf548/bfin_serial_5xx.h7
-rw-r--r--include/asm-blackfin/mach-bf561/bfin_serial_5xx.h24
-rw-r--r--include/asm-blackfin/mach-bf561/blackfin.h3
-rw-r--r--include/asm-blackfin/mach-bf561/cdefBF561.h2
-rw-r--r--include/asm-blackfin/mmu_context.h2
-rw-r--r--include/asm-blackfin/unistd.h6
-rw-r--r--include/asm-cris/uaccess.h53
-rw-r--r--include/asm-cris/unistd.h6
-rw-r--r--include/asm-frv/unistd.h4
-rw-r--r--include/asm-generic/percpu.h2
-rw-r--r--include/asm-generic/vmlinux.lds.h3
-rw-r--r--include/asm-h8300/hardirq.h2
-rw-r--r--include/asm-h8300/irq.h19
-rw-r--r--include/asm-h8300/uaccess.h4
-rw-r--r--include/asm-ia64/Kbuild2
-rw-r--r--include/asm-ia64/hw_irq.h12
-rw-r--r--include/asm-ia64/kprobes.h7
-rw-r--r--include/asm-ia64/ptrace.h9
-rw-r--r--include/asm-ia64/sal.h4
-rw-r--r--include/asm-m68k/unistd.h6
-rw-r--r--include/asm-m68knommu/machdep.h2
-rw-r--r--include/asm-m68knommu/unistd.h6
-rw-r--r--include/asm-mips/mach-db1x00/db1200.h1
-rw-r--r--include/asm-mips/mach-db1x00/db1x00.h1
-rw-r--r--include/asm-mips/mach-ip27/dma-coherence.h2
-rw-r--r--include/asm-mips/mach-pb1x00/pb1200.h1
-rw-r--r--include/asm-mips/mach-pb1x00/pb1550.h1
-rw-r--r--include/asm-mips/qemu.h30
-rw-r--r--include/asm-mips/sni.h7
-rw-r--r--include/asm-mips/unistd.h21
-rw-r--r--include/asm-mn10300/Kbuild4
-rw-r--r--include/asm-mn10300/param.h2
-rw-r--r--include/asm-mn10300/socket.h2
-rw-r--r--include/asm-powerpc/kprobes.h1
-rw-r--r--include/asm-powerpc/percpu.h2
-rw-r--r--include/asm-powerpc/reg.h3
-rw-r--r--include/asm-powerpc/spu.h3
-rw-r--r--include/asm-s390/bitops.h20
-rw-r--r--include/asm-s390/kprobes.h1
-rw-r--r--include/asm-sh/cpu-sh3/cache.h2
-rw-r--r--include/asm-sh/delay.h5
-rw-r--r--include/asm-sh/entry-macros.S4
-rw-r--r--include/asm-sparc/system.h2
-rw-r--r--include/asm-sparc64/kprobes.h2
-rw-r--r--include/asm-sparc64/ptrace.h2
-rw-r--r--include/asm-sparc64/reboot.h6
-rw-r--r--include/asm-sparc64/syscalls.h13
-rw-r--r--include/asm-sparc64/system.h3
-rw-r--r--include/asm-x86/Kbuild1
-rw-r--r--include/asm-x86/desc_64.h1
-rw-r--r--include/asm-x86/futex.h7
-rw-r--r--include/asm-x86/i387.h1
-rw-r--r--include/asm-x86/kprobes.h1
-rw-r--r--include/asm-x86/lguest.h11
-rw-r--r--include/asm-x86/nops.h66
-rw-r--r--include/asm-x86/page_64.h8
-rw-r--r--include/asm-x86/pgtable_64.h2
-rw-r--r--include/asm-x86/processor.h5
-rw-r--r--include/asm-x86/ptrace-abi.h8
-rw-r--r--include/asm-xtensa/cacheflush.h2
-rw-r--r--include/asm-xtensa/coprocessor.h214
-rw-r--r--include/asm-xtensa/elf.h110
-rw-r--r--include/asm-xtensa/module.h4
-rw-r--r--include/asm-xtensa/pgalloc.h2
-rw-r--r--include/asm-xtensa/pgtable.h8
-rw-r--r--include/asm-xtensa/processor.h13
-rw-r--r--include/asm-xtensa/ptrace.h44
-rw-r--r--include/asm-xtensa/regs.h9
-rw-r--r--include/asm-xtensa/sigcontext.h4
-rw-r--r--include/asm-xtensa/stat.h36
-rw-r--r--include/asm-xtensa/system.h39
-rw-r--r--include/asm-xtensa/thread_info.h21
-rw-r--r--include/asm-xtensa/timex.h8
-rw-r--r--include/asm-xtensa/uaccess.h99
-rw-r--r--include/asm-xtensa/variant-fsf/tie-asm.h70
-rw-r--r--include/asm-xtensa/variant-fsf/tie.h75
-rw-r--r--include/linux/Kbuild3
-rw-r--r--include/linux/aio.h1
-rw-r--r--include/linux/ata.h5
-rw-r--r--include/linux/bio.h1
-rw-r--r--include/linux/blkdev.h10
-rw-r--r--include/linux/cgroup.h50
-rw-r--r--include/linux/cgroup_subsys.h2
-rw-r--r--include/linux/compiler.h6
-rw-r--r--include/linux/connector.h2
-rw-r--r--include/linux/debugfs.h5
-rw-r--r--include/linux/delay.h8
-rw-r--r--include/linux/dm9000.h2
-rw-r--r--include/linux/dmaengine.h2
-rw-r--r--include/linux/efs_dir.h42
-rw-r--r--include/linux/efs_fs.h56
-rw-r--r--include/linux/efs_fs_i.h68
-rw-r--r--include/linux/elfcore-compat.h4
-rw-r--r--include/linux/ext4_fs_extents.h1
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/futex.h1
-rw-r--r--include/linux/genhd.h5
-rw-r--r--include/linux/gpio.h95
-rw-r--r--include/linux/hardirq.h10
-rw-r--r--include/linux/hdsmart.h4
-rw-r--r--include/linux/i2c.h11
-rw-r--r--include/linux/init.h2
-rw-r--r--include/linux/iocontext.h2
-rw-r--r--include/linux/iommu-helper.h3
-rw-r--r--include/linux/kprobes.h6
-rw-r--r--include/linux/kvm.h4
-rw-r--r--include/linux/kvm_host.h1
-rw-r--r--include/linux/libata.h31
-rw-r--r--include/linux/maple.h1
-rw-r--r--include/linux/marker.h8
-rw-r--r--include/linux/memcontrol.h44
-rw-r--r--include/linux/mm.h8
-rw-r--r--include/linux/mm_types.h9
-rw-r--r--include/linux/netdevice.h8
-rw-r--r--include/linux/netfilter.h4
-rw-r--r--include/linux/netfilter/Kbuild2
-rw-r--r--include/linux/netfilter/xt_hashlimit.h1
-rw-r--r--include/linux/netpoll.h7
-rw-r--r--include/linux/nfs_fs.h1
-rw-r--r--include/linux/page-flags.h4
-rw-r--r--include/linux/pci.h10
-rw-r--r--include/linux/pci_ids.h7
-rw-r--r--include/linux/pm.h9
-rw-r--r--include/linux/raid/bitmap.h2
-rw-r--r--include/linux/raid/md_k.h1
-rw-r--r--include/linux/rcuclassic.h3
-rw-r--r--include/linux/rcupreempt.h22
-rw-r--r--include/linux/sched.h11
-rw-r--r--include/linux/security.h99
-rw-r--r--include/linux/serial_sci.h (renamed from include/asm-sh/sci.h)10
-rw-r--r--include/linux/skbuff.h2
-rw-r--r--include/linux/slab_def.h4
-rw-r--r--include/linux/slub_def.h4
-rw-r--r--include/linux/sm501-regs.h3
-rw-r--r--include/linux/sm501.h3
-rw-r--r--include/linux/ssb/ssb.h12
-rw-r--r--include/linux/ssb/ssb_driver_chipcommon.h18
-rw-r--r--include/linux/ssb/ssb_driver_extif.h18
-rw-r--r--include/linux/ssb/ssb_driver_pci.h5
-rw-r--r--include/linux/ssb/ssb_embedded.h18
-rw-r--r--include/linux/usb.h12
-rw-r--r--include/linux/videodev.h1
-rw-r--r--include/linux/videodev2.h1
-rw-r--r--include/linux/vmstat.h3
-rw-r--r--include/media/ir-common.h1
-rw-r--r--include/media/v4l2-common.h2
-rw-r--r--include/media/v4l2-dev.h2
-rw-r--r--include/media/videobuf-core.h2
-rw-r--r--include/media/videobuf-vmalloc.h2
-rw-r--r--include/net/ax25.h2
-rw-r--r--include/net/inet_sock.h3
-rw-r--r--include/net/ip6_tunnel.h2
-rw-r--r--include/net/ndisc.h1
-rw-r--r--include/net/sctp/user.h10
-rw-r--r--include/net/sock.h1
-rw-r--r--include/net/xfrm.h5
-rw-r--r--include/scsi/libsas.h1
-rw-r--r--include/scsi/scsi_transport_iscsi.h2
-rw-r--r--include/sound/opl3.h9
-rw-r--r--init/Kconfig33
-rw-r--r--init/main.c2
-rw-r--r--kernel/audit.c19
-rw-r--r--kernel/auditsc.c7
-rw-r--r--kernel/cgroup.c157
-rw-r--r--kernel/cpuset.c4
-rw-r--r--kernel/exit.c98
-rw-r--r--kernel/futex.c50
-rw-r--r--kernel/futex_compat.c9
-rw-r--r--kernel/irq/chip.c20
-rw-r--r--kernel/irq/spurious.c3
-rw-r--r--kernel/kprobes.c52
-rw-r--r--kernel/lockdep.c8
-rw-r--r--kernel/marker.c13
-rw-r--r--kernel/module.c16
-rw-r--r--kernel/power/disk.c4
-rw-r--r--kernel/power/process.c29
-rw-r--r--kernel/power/snapshot.c42
-rw-r--r--kernel/printk.c2
-rw-r--r--kernel/rcupreempt.c233
-rw-r--r--kernel/res_counter.c1
-rw-r--r--kernel/sched.c358
-rw-r--r--kernel/sched_fair.c142
-rw-r--r--kernel/sched_rt.c10
-rw-r--r--kernel/signal.c16
-rw-r--r--kernel/softirq.c1
-rw-r--r--kernel/softlockup.c13
-rw-r--r--kernel/sysctl.c18
-rw-r--r--kernel/time/tick-sched.c3
-rw-r--r--kernel/time/timer_list.c4
-rw-r--r--lib/Kconfig.debug4
-rw-r--r--lib/iommu-helper.c10
-rw-r--r--lib/kobject.c11
-rw-r--r--lib/vsprintf.c2
-rw-r--r--mm/Makefile2
-rw-r--r--mm/allocpercpu.c15
-rw-r--r--mm/hugetlb.c45
-rw-r--r--mm/internal.h13
-rw-r--r--mm/memcontrol.c370
-rw-r--r--mm/memory.c13
-rw-r--r--mm/migrate.c19
-rw-r--r--mm/oom_kill.c2
-rw-r--r--mm/page_alloc.c25
-rw-r--r--mm/rmap.c4
-rw-r--r--mm/shmem.c9
-rw-r--r--mm/slab.c9
-rw-r--r--mm/slub.c304
-rw-r--r--mm/swap.c2
-rw-r--r--mm/truncate.c3
-rw-r--r--mm/vmscan.c9
-rw-r--r--net/8021q/vlanproc.c11
-rw-r--r--net/9p/trans_virtio.c5
-rw-r--r--net/appletalk/atalk_proc.c15
-rw-r--r--net/atm/br2684.c4
-rw-r--r--net/atm/clip.c4
-rw-r--r--net/atm/lec.c4
-rw-r--r--net/atm/mpoa_proc.c3
-rw-r--r--net/atm/proc.c8
-rw-r--r--net/ax25/af_ax25.c12
-rw-r--r--net/ax25/ax25_dev.c2
-rw-r--r--net/ax25/ax25_ds_timer.c12
-rw-r--r--net/ax25/ax25_out.c13
-rw-r--r--net/ax25/ax25_route.c28
-rw-r--r--net/ax25/ax25_timer.c60
-rw-r--r--net/bluetooth/hci_conn.c1
-rw-r--r--net/bluetooth/hci_core.c5
-rw-r--r--net/bluetooth/hci_sysfs.c24
-rw-r--r--net/bluetooth/l2cap.c3
-rw-r--r--net/bridge/netfilter/ebt_dnat.c4
-rw-r--r--net/bridge/netfilter/ebt_redirect.c4
-rw-r--r--net/bridge/netfilter/ebt_snat.c4
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/neighbour.c13
-rw-r--r--net/core/netpoll.c12
-rw-r--r--net/core/pktgen.c10
-rw-r--r--net/core/rtnetlink.c27
-rw-r--r--net/core/skbuff.c3
-rw-r--r--net/ipv4/Kconfig2
-rw-r--r--net/ipv4/ah4.c2
-rw-r--r--net/ipv4/devinet.c1
-rw-r--r--net/ipv4/esp4.c5
-rw-r--r--net/ipv4/fib_hash.c10
-rw-r--r--net/ipv4/fib_trie.c99
-rw-r--r--net/ipv4/inet_hashtables.c3
-rw-r--r--net/ipv4/ip_gre.c26
-rw-r--r--net/ipv4/ip_sockglue.c5
-rw-r--r--net/ipv4/ipcomp.c5
-rw-r--r--net/ipv4/ipconfig.c6
-rw-r--r--net/ipv4/ipip.c26
-rw-r--r--net/ipv4/netfilter/arpt_mangle.c2
-rw-r--r--net/ipv4/netfilter/ip_queue.c12
-rw-r--r--net/ipv4/route.c5
-rw-r--r--net/ipv4/tcp_bic.c5
-rw-r--r--net/ipv4/tcp_input.c14
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv6/Kconfig2
-rw-r--r--net/ipv6/addrconf.c3
-rw-r--r--net/ipv6/af_inet6.c8
-rw-r--r--net/ipv6/ah6.c2
-rw-r--r--net/ipv6/esp6.c5
-rw-r--r--net/ipv6/ip6_fib.c2
-rw-r--r--net/ipv6/ip6_output.c6
-rw-r--r--net/ipv6/ip6_tunnel.c31
-rw-r--r--net/ipv6/ipcomp6.c2
-rw-r--r--net/ipv6/netfilter/ip6_queue.c10
-rw-r--r--net/ipv6/proc.c4
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/ipv6/sit.c25
-rw-r--r--net/ipv6/sysctl_net_ipv6.c3
-rw-r--r--net/ipv6/xfrm6_output.c2
-rw-r--r--net/ipx/ipx_proc.c11
-rw-r--r--net/irda/ircomm/ircomm_core.c8
-rw-r--r--net/irda/irlan/irlan_common.c4
-rw-r--r--net/irda/irproc.c8
-rw-r--r--net/iucv/iucv.c2
-rw-r--r--net/key/af_key.c6
-rw-r--r--net/llc/llc_proc.c8
-rw-r--r--net/mac80211/ieee80211.c5
-rw-r--r--net/mac80211/ieee80211_sta.c7
-rw-r--r--net/mac80211/rc80211_pid_algo.c92
-rw-r--r--net/netfilter/nf_conntrack_core.c15
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c2
-rw-r--r--net/netfilter/nfnetlink_queue.c10
-rw-r--r--net/netfilter/xt_SECMARK.c2
-rw-r--r--net/netfilter/xt_conntrack.c4
-rw-r--r--net/netfilter/xt_hashlimit.c3
-rw-r--r--net/netfilter/xt_iprange.c2
-rw-r--r--net/netfilter/xt_u32.c11
-rw-r--r--net/netlabel/netlabel_cipso_v4.c45
-rw-r--r--net/netlabel/netlabel_domainhash.c8
-rw-r--r--net/netlabel/netlabel_mgmt.c81
-rw-r--r--net/netlabel/netlabel_unlabeled.c122
-rw-r--r--net/netlabel/netlabel_user.c5
-rw-r--r--net/netlink/genetlink.c6
-rw-r--r--net/rfkill/rfkill.c2
-rw-r--r--net/rxrpc/ar-accept.c3
-rw-r--r--net/rxrpc/ar-ack.c3
-rw-r--r--net/sctp/auth.c4
-rw-r--r--net/sctp/ipv6.c12
-rw-r--r--net/sctp/objcnt.c5
-rw-r--r--net/sctp/proc.c13
-rw-r--r--net/sctp/protocol.c12
-rw-r--r--net/sctp/socket.c20
-rw-r--r--net/sctp/ulpevent.c2
-rw-r--r--net/socket.c3
-rw-r--r--net/sunrpc/cache.c14
-rw-r--r--net/sunrpc/stats.c3
-rw-r--r--net/sunrpc/svcsock.c6
-rw-r--r--net/sunrpc/xprtrdma/transport.c6
-rw-r--r--net/tipc/cluster.c2
-rw-r--r--net/tipc/link.c2
-rw-r--r--net/tipc/ref.c2
-rw-r--r--net/tipc/zone.c2
-rw-r--r--net/wanrouter/wanproc.c10
-rw-r--r--net/x25/x25_proc.c10
-rw-r--r--net/xfrm/Kconfig2
-rw-r--r--net/xfrm/xfrm_input.c4
-rw-r--r--net/xfrm/xfrm_output.c2
-rw-r--r--net/xfrm/xfrm_policy.c20
-rw-r--r--net/xfrm/xfrm_user.c1
-rw-r--r--samples/Kconfig11
-rw-r--r--samples/Makefile2
-rw-r--r--samples/kprobes/Makefile5
-rw-r--r--samples/kprobes/jprobe_example.c68
-rw-r--r--samples/kprobes/kprobe_example.c91
-rw-r--r--samples/kprobes/kretprobe_example.c106
-rwxr-xr-xscripts/checkpatch.pl323
-rw-r--r--scripts/kconfig/symbol.c34
-rwxr-xr-xscripts/kernel-doc6
-rw-r--r--scripts/mod/modpost.c2
-rw-r--r--security/commoncap.c2
-rw-r--r--security/dummy.c23
-rw-r--r--security/security.c23
-rw-r--r--security/selinux/hooks.c175
-rw-r--r--security/selinux/include/security.h5
-rw-r--r--security/smack/smack_lsm.c132
-rw-r--r--security/smack/smackfs.c61
-rw-r--r--sound/drivers/opl3/opl3_synth.c8
-rw-r--r--sound/isa/sb/sb8_main.c2
-rw-r--r--sound/pci/bt87x.c9
-rw-r--r--sound/pci/hda/hda_codec.c14
-rw-r--r--sound/pci/hda/hda_intel.c23
-rw-r--r--sound/pci/hda/hda_proc.c3
-rw-r--r--sound/pci/hda/patch_analog.c8
-rw-r--r--sound/pci/hda/patch_conexant.c12
-rw-r--r--sound/pci/hda/patch_realtek.c30
-rw-r--r--sound/pci/ice1712/phase.c2
-rw-r--r--sound/pci/ice1712/revo.c2
-rw-r--r--sound/pci/intel8x0.c12
-rw-r--r--sound/pci/oxygen/hifier.c1
-rw-r--r--sound/pci/oxygen/oxygen.c35
-rw-r--r--sound/pci/oxygen/oxygen_lib.c10
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c2
-rw-r--r--sound/pci/oxygen/virtuoso.c1
-rw-r--r--sound/pci/rme9652/hdsp.c7
-rw-r--r--sound/soc/codecs/tlv320aic3x.c4
-rw-r--r--sound/soc/codecs/wm9712.c3
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c2
-rw-r--r--sound/soc/pxa/corgi.c6
-rw-r--r--sound/soc/pxa/poodle.c3
-rw-r--r--sound/soc/pxa/spitz.c3
-rw-r--r--sound/soc/pxa/tosa.c3
-rw-r--r--sound/usb/caiaq/caiaq-device.c6
-rw-r--r--sound/usb/usbaudio.c38
-rw-r--r--sound/usb/usbmidi.c19
-rw-r--r--virt/kvm/ioapic.c8
-rw-r--r--virt/kvm/kvm_main.c5
1401 files changed, 37072 insertions, 18349 deletions
diff --git a/.gitignore b/.gitignore
index 8363e48cdcd..fdcce40226d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,3 +53,5 @@ cscope.*
*.orig
*.rej
+*~
+\#*#
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 30b327a116e..042073f656e 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -183,8 +183,6 @@ i386/
- directory with info about Linux on Intel 32 bit architecture.
ia64/
- directory with info about Linux on Intel 64 bit architecture.
-ide.txt
- - important info for users of ATA devices (IDE/EIDE disks and CD-ROMS).
infiniband/
- directory with documents concerning Linux InfiniBand support.
initrd.txt
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index f31601e8bd8..dc0f30c3e57 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -361,12 +361,14 @@ X!Edrivers/pnp/system.c
<chapter id="blkdev">
<title>Block Devices</title>
!Eblock/blk-core.c
+!Iblock/blk-core.c
!Eblock/blk-map.c
!Iblock/blk-sysfs.c
!Eblock/blk-settings.c
!Eblock/blk-exec.c
!Eblock/blk-barrier.c
!Eblock/blk-tag.c
+!Iblock/blk-tag.c
</chapter>
<chapter id="chrdev">
diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt
index f20c10c2858..4ef24501045 100644
--- a/Documentation/atomic_ops.txt
+++ b/Documentation/atomic_ops.txt
@@ -186,7 +186,8 @@ If the atomic value v is not equal to u, this function adds a to v, and
returns non zero. If v is equal to u then it returns zero. This is done as
an atomic operation.
-atomic_add_unless requires explicit memory barriers around the operation.
+atomic_add_unless requires explicit memory barriers around the operation
+unless it fails (returns 0).
atomic_inc_not_zero, equivalent to atomic_add_unless(v, 1, 0)
diff --git a/Documentation/cdrom/ide-cd b/Documentation/cdrom/ide-cd
index 29721bfcde1..91c0dcc6fa5 100644
--- a/Documentation/cdrom/ide-cd
+++ b/Documentation/cdrom/ide-cd
@@ -45,7 +45,7 @@ This driver provides the following features:
---------------
0. The ide-cd relies on the ide disk driver. See
- Documentation/ide.txt for up-to-date information on the ide
+ Documentation/ide/ide.txt for up-to-date information on the ide
driver.
1. Make sure that the ide and ide-cd drivers are compiled into the
@@ -64,7 +64,7 @@ This driver provides the following features:
Depending on what type of IDE interface you have, you may need to
specify additional configuration options. See
- Documentation/ide.txt.
+ Documentation/ide/ide.txt.
2. You should also ensure that the iso9660 filesystem is either
compiled into the kernel or available as a loadable module. You
@@ -84,7 +84,7 @@ This driver provides the following features:
on the primary IDE interface are called `hda' and `hdb',
respectively. The drives on the secondary interface are called
`hdc' and `hdd'. (Interfaces at other locations get other letters
- in the third position; see Documentation/ide.txt.)
+ in the third position; see Documentation/ide/ide.txt.)
If you want your CDROM drive to be found automatically by the
driver, you should make sure your IDE interface uses either the
@@ -93,7 +93,7 @@ This driver provides the following features:
be jumpered as `master'. (If for some reason you cannot configure
your system in this manner, you can probably still use the driver.
You may have to pass extra configuration information to the kernel
- when you boot, however. See Documentation/ide.txt for more
+ when you boot, however. See Documentation/ide/ide.txt for more
information.)
4. Boot the system. If the drive is recognized, you should see a
@@ -201,7 +201,7 @@ TEST
This section discusses some common problems encountered when trying to
use the driver, and some possible solutions. Note that if you are
experiencing problems, you should probably also review
-Documentation/ide.txt for current information about the underlying
+Documentation/ide/ide.txt for current information about the underlying
IDE support code. Some of these items apply only to earlier versions
of the driver, but are mentioned here for completeness.
@@ -211,7 +211,7 @@ from the driver.
a. Drive is not detected during booting.
- Review the configuration instructions above and in
- Documentation/ide.txt, and check how your hardware is
+ Documentation/ide/ide.txt, and check how your hardware is
configured.
- If your drive is the only device on an IDE interface, it should
@@ -219,7 +219,7 @@ a. Drive is not detected during booting.
- If your IDE interface is not at the standard addresses of 0x170
or 0x1f0, you'll need to explicitly inform the driver using a
- lilo option. See Documentation/ide.txt. (This feature was
+ lilo option. See Documentation/ide/ide.txt. (This feature was
added around kernel version 1.3.30.)
- If the autoprobing is not finding your drive, you can tell the
@@ -245,7 +245,7 @@ a. Drive is not detected during booting.
Support for some interfaces needing extra initialization is
provided in later 1.3.x kernels. You may need to turn on
additional kernel configuration options to get them to work;
- see Documentation/ide.txt.
+ see Documentation/ide/ide.txt.
Even if support is not available for your interface, you may be
able to get it to work with the following procedure. First boot
@@ -299,7 +299,7 @@ c. System hangups.
be worked around by specifying the `serialize' option when
booting. Recent kernels should be able to detect the need for
this automatically in most cases, but the detection is not
- foolproof. See Documentation/ide.txt for more information
+ foolproof. See Documentation/ide/ide.txt for more information
about the `serialize' option and the CMD640B.
- Note that many MS-DOS CDROM drivers will work with such buggy
diff --git a/Documentation/cgroups.txt b/Documentation/cgroups.txt
index 42d7c4cb39c..31d12e21ff8 100644
--- a/Documentation/cgroups.txt
+++ b/Documentation/cgroups.txt
@@ -28,7 +28,7 @@ CONTENTS:
4. Questions
1. Control Groups
-==========
+=================
1.1 What are cgroups ?
----------------------
@@ -143,10 +143,10 @@ proliferation of such cgroups.
Also lets say that the administrator would like to give enhanced network
access temporarily to a student's browser (since it is night and the user
-wants to do online gaming :) OR give one of the students simulation
+wants to do online gaming :)) OR give one of the students simulation
apps enhanced CPU power,
-With ability to write pids directly to resource classes, its just a
+With ability to write pids directly to resource classes, it's just a
matter of :
# echo pid > /mnt/network/<new_class>/tasks
@@ -227,10 +227,13 @@ Each cgroup is represented by a directory in the cgroup file system
containing the following files describing that cgroup:
- tasks: list of tasks (by pid) attached to that cgroup
- - notify_on_release flag: run /sbin/cgroup_release_agent on exit?
+ - releasable flag: cgroup currently removeable?
+ - notify_on_release flag: run the release agent on exit?
+ - release_agent: the path to use for release notifications (this file
+ exists in the top cgroup only)
Other subsystems such as cpusets may add additional files in each
-cgroup dir
+cgroup dir.
New cgroups are created using the mkdir system call or shell
command. The properties of a cgroup, such as its flags, are
@@ -257,7 +260,7 @@ 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;
each cg_cgroup_link is linked into a list of cg_cgroup_links for
-a single cgroup on its cont_link_list field, and a list of
+a single cgroup on its cgrp_link_list field, and a list of
cg_cgroup_links for a single css_set on its cg_link_list.
Thus the set of tasks in a cgroup can be listed by iterating over
@@ -271,9 +274,6 @@ for cgroups, with a minimum of additional kernel code.
1.4 What does notify_on_release do ?
------------------------------------
-*** notify_on_release is disabled in the current patch set. It will be
-*** reactivated in a future patch in a less-intrusive manner
-
If the notify_on_release flag is enabled (1) in a cgroup, then
whenever the last task in the cgroup leaves (exits or attaches to
some other cgroup) and the last child cgroup of that cgroup
@@ -360,8 +360,8 @@ Now you want to do something with this cgroup.
In this directory you can find several files:
# ls
-notify_on_release release_agent tasks
-(plus whatever files are added by the attached subsystems)
+notify_on_release releasable tasks
+(plus whatever files added by the attached subsystems)
Now attach your shell to this cgroup:
# /bin/echo $$ > tasks
@@ -404,19 +404,13 @@ with a subsystem id which will be assigned by the cgroup system.
Other fields in the cgroup_subsys object include:
- subsys_id: a unique array index for the subsystem, indicating which
- entry in cgroup->subsys[] this subsystem should be
- managing. Initialized by cgroup_register_subsys(); prior to this
- it should be initialized to -1
+ entry in cgroup->subsys[] this subsystem should be managing.
-- hierarchy: an index indicating which hierarchy, if any, this
- subsystem is currently attached to. If this is -1, then the
- subsystem is not attached to any hierarchy, and all tasks should be
- considered to be members of the subsystem's top_cgroup. It should
- be initialized to -1.
+- name: should be initialized to a unique subsystem name. Should be
+ no longer than MAX_CGROUP_TYPE_NAMELEN.
-- name: should be initialized to a unique subsystem name prior to
- calling cgroup_register_subsystem. Should be no longer than
- MAX_CGROUP_TYPE_NAMELEN
+- early_init: indicate if the subsystem needs early initialization
+ at system boot.
Each cgroup object created by the system has an array of pointers,
indexed by subsystem id; this pointer is entirely managed by the
@@ -434,8 +428,6 @@ situation.
See kernel/cgroup.c for more details.
Subsystems can take/release the cgroup_mutex via the functions
-cgroup_lock()/cgroup_unlock(), and can
-take/release the callback_mutex via the functions
cgroup_lock()/cgroup_unlock().
Accessing a task's cgroup pointer may be done in the following ways:
@@ -444,7 +436,7 @@ Accessing a task's cgroup pointer may be done in the following ways:
- inside an rcu_read_lock() section via rcu_dereference()
3.3 Subsystem API
---------------------------
+-----------------
Each subsystem should:
@@ -455,7 +447,8 @@ Each subsystem may export the following methods. The only mandatory
methods are create/destroy. Any others that are null are presumed to
be successful no-ops.
-struct cgroup_subsys_state *create(struct cgroup *cont)
+struct cgroup_subsys_state *create(struct cgroup_subsys *ss,
+ struct cgroup *cgrp)
(cgroup_mutex held by caller)
Called to create a subsystem state object for a cgroup. The
@@ -470,7 +463,7 @@ identified by the passed cgroup object having a NULL parent (since
it's the root of the hierarchy) and may be an appropriate place for
initialization code.
-void destroy(struct cgroup *cont)
+void destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
(cgroup_mutex held by caller)
The cgroup system is about to destroy the passed cgroup; the subsystem
@@ -481,7 +474,14 @@ cgroup->parent is still valid. (Note - can also be called for a
newly-created cgroup if an error occurs after this subsystem's
create() method has been called for the new cgroup).
-int can_attach(struct cgroup_subsys *ss, struct cgroup *cont,
+void pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
+(cgroup_mutex held by caller)
+
+Called before checking the reference count on each subsystem. This may
+be useful for subsystems which have some extra references even if
+there are not tasks in the cgroup.
+
+int can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
struct task_struct *task)
(cgroup_mutex held by caller)
@@ -492,8 +492,8 @@ unspecified task can be moved into the cgroup. Note that this isn't
called on a fork. If this method returns 0 (success) then this should
remain valid while the caller holds cgroup_mutex.
-void attach(struct cgroup_subsys *ss, struct cgroup *cont,
- struct cgroup *old_cont, struct task_struct *task)
+void attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
+ struct cgroup *old_cgrp, struct task_struct *task)
Called after the task has been attached to the cgroup, to allow any
post-attachment activity that requires memory allocations or blocking.
@@ -505,9 +505,9 @@ registration for all existing tasks.
void exit(struct cgroup_subsys *ss, struct task_struct *task)
-Called during task exit
+Called during task exit.
-int populate(struct cgroup_subsys *ss, struct cgroup *cont)
+int populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
Called after creation of a cgroup to allow a subsystem to populate
the cgroup directory with file entries. The subsystem should make
@@ -516,7 +516,7 @@ include/linux/cgroup.h for details). Note that although this
method can return an error code, the error code is currently not
always handled well.
-void post_clone(struct cgroup_subsys *ss, struct cgroup *cont)
+void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp)
Called at the end of cgroup_clone() to do any paramater
initialization which might be required before a task could attach. For
diff --git a/Documentation/controllers/memory.txt b/Documentation/controllers/memory.txt
index b5bbea92a61..866b9cd9a95 100644
--- a/Documentation/controllers/memory.txt
+++ b/Documentation/controllers/memory.txt
@@ -1,4 +1,8 @@
-Memory Controller
+Memory Resource Controller
+
+NOTE: The Memory Resource Controller has been generically been referred
+to as the memory controller in this document. Do not confuse memory controller
+used here with the memory controller that is used in hardware.
Salient features
@@ -152,7 +156,7 @@ The memory controller uses the following hierarchy
a. Enable CONFIG_CGROUPS
b. Enable CONFIG_RESOURCE_COUNTERS
-c. Enable CONFIG_CGROUP_MEM_CONT
+c. Enable CONFIG_CGROUP_MEM_RES_CTLR
1. Prepare the cgroups
# mkdir -p /cgroups
@@ -164,20 +168,20 @@ c. Enable CONFIG_CGROUP_MEM_CONT
Since now we're in the 0 cgroup,
We can alter the memory limit:
-# echo -n 4M > /cgroups/0/memory.limit_in_bytes
+# echo 4M > /cgroups/0/memory.limit_in_bytes
NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo,
mega or gigabytes.
# cat /cgroups/0/memory.limit_in_bytes
-4194304 Bytes
+4194304
NOTE: The interface has now changed to display the usage in bytes
instead of pages
We can check the usage:
# cat /cgroups/0/memory.usage_in_bytes
-1216512 Bytes
+1216512
A successful write to this file does not guarantee a successful set of
this limit to the value written into the file. This can be due to a
@@ -185,9 +189,9 @@ number of factors, such as rounding up to page boundaries or the total
availability of memory on the system. The user is required to re-read
this file after a write to guarantee the value committed by the kernel.
-# echo -n 1 > memory.limit_in_bytes
+# echo 1 > memory.limit_in_bytes
# cat memory.limit_in_bytes
-4096 Bytes
+4096
The memory.failcnt field gives the number of times that the cgroup limit was
exceeded.
@@ -197,7 +201,7 @@ caches, RSS and Active pages/Inactive pages are shown.
The memory.force_empty gives an interface to drop *all* charges by force.
-# echo -n 1 > memory.force_empty
+# echo 1 > memory.force_empty
will drop all charges in cgroup. Currently, this is maintained for test.
@@ -233,13 +237,6 @@ cgroup might have some charge associated with it, even though all
tasks have migrated away from it. Such charges are automatically dropped at
rmdir() if there are no tasks.
-4.4 Choosing what to account -- Page Cache (unmapped) vs RSS (mapped)?
-
-The type of memory accounted by the cgroup can be limited to just
-mapped pages by writing "1" to memory.control_type field
-
-echo -n 1 > memory.control_type
-
5. TODO
1. Add support for accounting huge pages (as a separate controller)
@@ -262,18 +259,19 @@ References
3. Emelianov, Pavel. Resource controllers based on process cgroups
http://lkml.org/lkml/2007/3/6/198
4. Emelianov, Pavel. RSS controller based on process cgroups (v2)
- http://lkml.org/lkml/2007/4/9/74
+ http://lkml.org/lkml/2007/4/9/78
5. Emelianov, Pavel. RSS controller based on process cgroups (v3)
http://lkml.org/lkml/2007/5/30/244
6. Menage, Paul. Control Groups v10, http://lwn.net/Articles/236032/
7. Vaidyanathan, Srinivasan, Control Groups: Pagecache accounting and control
subsystem (v3), http://lwn.net/Articles/235534/
-8. Singh, Balbir. RSS controller V2 test results (lmbench),
+8. Singh, Balbir. RSS controller v2 test results (lmbench),
http://lkml.org/lkml/2007/5/17/232
-9. Singh, Balbir. RSS controller V2 AIM9 results
+9. Singh, Balbir. RSS controller v2 AIM9 results
http://lkml.org/lkml/2007/5/18/1
-10. Singh, Balbir. Memory controller v6 results,
+10. Singh, Balbir. Memory controller v6 test results,
http://lkml.org/lkml/2007/8/19/36
-11. Singh, Balbir. Memory controller v6, http://lkml.org/lkml/2007/8/17/69
+11. Singh, Balbir. Memory controller introduction (v6),
+ http://lkml.org/lkml/2007/8/17/69
12. Corbet, Jonathan, Controlling memory use in cgroups,
http://lwn.net/Articles/243795/
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index 43db6fe1281..ad2bb3b3acc 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -209,7 +209,7 @@ and name space for cpusets, with a minimum of additional kernel code.
The cpus and mems files in the root (top_cpuset) cpuset are
read-only. The cpus file automatically tracks the value of
cpu_online_map using a CPU hotplug notifier, and the mems file
-automatically tracks the value of node_states[N_MEMORY]--i.e.,
+automatically tracks the value of node_states[N_HIGH_MEMORY]--i.e.,
nodes with memory--using the cpuset_track_online_nodes() hook.
diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt
index de4804e8b39..c360d4e91b4 100644
--- a/Documentation/debugging-via-ohci1394.txt
+++ b/Documentation/debugging-via-ohci1394.txt
@@ -36,14 +36,15 @@ available (notebooks) or too slow for extensive debug information (like ACPI).
Drivers
-------
-The OHCI-1394 drivers in drivers/firewire and drivers/ieee1394 initialize
-the OHCI-1394 controllers to a working state and can be used to enable
-physical DMA. By default you only have to load the driver, and physical
-DMA access will be granted to all remote nodes, but it can be turned off
-when using the ohci1394 driver.
-
-Because these drivers depend on the PCI enumeration to be completed, an
-initialization routine which can runs pretty early (long before console_init(),
+The ohci1394 driver in drivers/ieee1394 initializes the OHCI-1394 controllers
+to a working state and enables physical DMA by default for all remote nodes.
+This can be turned off by ohci1394's module parameter phys_dma=0.
+
+The alternative firewire-ohci driver in drivers/firewire uses filtered physical
+DMA, hence is not yet suitable for remote debugging.
+
+Because ohci1394 depends on the PCI enumeration to be completed, an
+initialization routine which runs pretty early (long before console_init()
which makes the printk buffer appear on the console can be called) was written.
To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu:
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 4d3aa519ead..c1d1fd0c299 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -172,6 +172,16 @@ Who: Len Brown <len.brown@intel.com>
---------------------------
+What: ide-tape driver
+When: July 2008
+Files: drivers/ide/ide-tape.c
+Why: This driver might not have any users anymore and maintaining it for no
+ reason is an effort no one wants to make.
+Who: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>, Borislav Petkov
+ <petkovbb@googlemail.com>
+
+---------------------------
+
What: libata spindown skipping and warning
When: Dec 2008
Why: Some halt(8) implementations synchronize caches for and spin
@@ -306,3 +316,15 @@ Why: Largely unmaintained and almost entirely unused. File system
is largely pointless as without a lot of work only the most
trivial of Solaris binaries can work with the emulation code.
Who: David S. Miller <davem@davemloft.net>
+
+---------------------------
+
+What: init_mm export
+When: 2.6.26
+Why: Not used in-tree. The current out-of-tree users used it to
+ work around problems in the CPA code which should be resolved
+ by now. One usecase was described to provide verification code
+ of the CPA operation. That's a good idea in general, but such
+ code / infrastructure should be in the kernel and not in some
+ out-of-tree driver.
+Who: Thomas Gleixner <tglx@linutronix.de>
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index 8da724e2a0f..54630095aa3 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -2,6 +2,9 @@ GPIO Interfaces
This provides an overview of GPIO access conventions on Linux.
+These calls use the gpio_* naming prefix. No other calls should use that
+prefix, or the related __gpio_* prefix.
+
What is a GPIO?
===============
@@ -69,11 +72,13 @@ in this document, but drivers acting as clients to the GPIO interface must
not care how it's implemented.)
That said, if the convention is supported on their platform, drivers should
-use it when possible. Platforms should declare GENERIC_GPIO support in
-Kconfig (boolean true), which multi-platform drivers can depend on when
-using the include file:
+use it when possible. Platforms must declare GENERIC_GPIO support in their
+Kconfig (boolean true), and provide an <asm/gpio.h> file. Drivers that can't
+work without standard GPIO calls should have Kconfig entries which depend
+on GENERIC_GPIO. The GPIO calls are available, either as "real code" or as
+optimized-away stubs, when drivers use the include file:
- #include <asm/gpio.h>
+ #include <linux/gpio.h>
If you stick to this convention then it'll be easier for other developers to
see what your code is doing, and help maintain it.
@@ -316,6 +321,9 @@ pulldowns integrated on some platforms. Not all platforms support them,
or support them in the same way; and any given board might use external
pullups (or pulldowns) so that the on-chip ones should not be used.
(When a circuit needs 5 kOhm, on-chip 100 kOhm resistors won't do.)
+Likewise drive strength (2 mA vs 20 mA) and voltage (1.8V vs 3.3V) is a
+platform-specific issue, as are models like (not) having a one-to-one
+correspondence between configurable pins and GPIOs.
There are other system-specific mechanisms that are not specified here,
like the aforementioned options for input de-glitching and wire-OR output.
diff --git a/Documentation/hwmon/adt7473 b/Documentation/hwmon/adt7473
new file mode 100644
index 00000000000..22d8b19046a
--- /dev/null
+++ b/Documentation/hwmon/adt7473
@@ -0,0 +1,79 @@
+Kernel driver adt7473
+======================
+
+Supported chips:
+ * Analog Devices ADT7473
+ Prefix: 'adt7473'
+ Addresses scanned: I2C 0x2C, 0x2D, 0x2E
+ Datasheet: Publicly available at the Analog Devices website
+
+Author: Darrick J. Wong
+
+Description
+-----------
+
+This driver implements support for the Analog Devices ADT7473 chip family.
+
+The LM85 uses the 2-wire interface compatible with the SMBUS 2.0
+specification. Using an analog to digital converter it measures three (3)
+temperatures and two (2) voltages. It has three (3) 16-bit counters for
+measuring fan speed. There are three (3) PWM outputs that can be used
+to control fan speed.
+
+A sophisticated control system for the PWM outputs is designed into the
+LM85 that allows fan speed to be adjusted automatically based on any of the
+three temperature sensors. Each PWM output is individually adjustable and
+programmable. Once configured, the ADT7473 will adjust the PWM outputs in
+response to the measured temperatures without further host intervention.
+This feature can also be disabled for manual control of the PWM's.
+
+Each of the measured inputs (voltage, temperature, fan speed) has
+corresponding high/low limit values. The ADT7473 will signal an ALARM if
+any measured value exceeds either limit.
+
+The ADT7473 samples all inputs continuously. The driver will not read
+the registers more often than once every other second. Further,
+configuration data is only read once per minute.
+
+Special Features
+----------------
+
+The ADT7473 have a 10-bit ADC and can therefore measure temperatures
+with 0.25 degC resolution. Temperature readings can be configured either
+for twos complement format or "Offset 64" format, wherein 63 is subtracted
+from the raw value to get the temperature value.
+
+The Analog Devices datasheet is very detailed and describes a procedure for
+determining an optimal configuration for the automatic PWM control.
+
+Hardware Configurations
+-----------------------
+
+The ADT7473 chips have an optional SMBALERT output that can be used to
+signal the chipset in case a limit is exceeded or the temperature sensors
+fail. Individual sensor interrupts can be masked so they won't trigger
+SMBALERT. The SMBALERT output if configured replaces the PWM2 function.
+
+Configuration Notes
+-------------------
+
+Besides standard interfaces driver adds the following:
+
+* PWM Control
+
+* pwm#_auto_point1_pwm and pwm#_auto_point1_temp and
+* pwm#_auto_point2_pwm and pwm#_auto_point2_temp -
+
+point1: Set the pwm speed at a lower temperature bound.
+point2: Set the pwm speed at a higher temperature bound.
+
+The ADT7473 will scale the pwm between the lower and higher pwm speed when
+the temperature is between the two temperature boundaries. PWM values range
+from 0 (off) to 255 (full speed).
+
+Notes
+-----
+
+The NVIDIA binary driver presents an ADT7473 chip via an on-card i2c bus.
+Unfortunately, they fail to set the i2c adapter class, so this driver may
+fail to find the chip until the nvidia driver is patched.
diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp
index 170bf862437..dbbe6c7025b 100644
--- a/Documentation/hwmon/coretemp
+++ b/Documentation/hwmon/coretemp
@@ -4,9 +4,10 @@ Kernel driver coretemp
Supported chips:
* All Intel Core family
Prefix: 'coretemp'
- CPUID: family 0x6, models 0xe, 0xf, 0x16
+ CPUID: family 0x6, models 0xe, 0xf, 0x16, 0x17
Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual
Volume 3A: System Programming Guide
+ http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
Author: Rudolf Marek
@@ -25,7 +26,8 @@ may be raised, if the temperature grows enough (more than TjMax) to trigger
the Out-Of-Spec bit. Following table summarizes the exported sysfs files:
temp1_input - Core temperature (in millidegrees Celsius).
-temp1_crit - Maximum junction temperature (in millidegrees Celsius).
+temp1_max - All cooling devices should be turned on (on Core2).
+temp1_crit - Maximum junction temperature (in millidegrees Celsius).
temp1_crit_alarm - Set when Out-of-spec bit is set, never clears.
Correct CPU operation is no longer guaranteed.
temp1_label - Contains string "Core X", where X is processor
diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801
index 3bd95836015..c31e0291e16 100644
--- a/Documentation/i2c/busses/i2c-i801
+++ b/Documentation/i2c/busses/i2c-i801
@@ -12,8 +12,9 @@ Supported adapters:
* Intel 82801G (ICH7)
* Intel 631xESB/632xESB (ESB2)
* Intel 82801H (ICH8)
- * Intel ICH9
+ * Intel 82801I (ICH9)
* Intel Tolapai
+ * Intel ICH10
Datasheets: Publicly available at the Intel website
Authors:
diff --git a/Documentation/i386/IO-APIC.txt b/Documentation/i386/IO-APIC.txt
index 435e69e6e9a..f95166645d2 100644
--- a/Documentation/i386/IO-APIC.txt
+++ b/Documentation/i386/IO-APIC.txt
@@ -1,12 +1,14 @@
Most (all) Intel-MP compliant SMP boards have the so-called 'IO-APIC',
-which is an enhanced interrupt controller, it enables us to route
-hardware interrupts to multiple CPUs, or to CPU groups.
+which is an enhanced interrupt controller. It enables us to route
+hardware interrupts to multiple CPUs, or to CPU groups. Without an
+IO-APIC, interrupts from hardware will be delivered only to the
+CPU which boots the operating system (usually CPU#0).
Linux supports all variants of compliant SMP boards, including ones with
-multiple IO-APICs. (multiple IO-APICs are used in high-end servers to
-distribute IRQ load further).
+multiple IO-APICs. Multiple IO-APICs are used in high-end servers to
+distribute IRQ load further.
-There are (a few) known breakages in certain older boards, which bugs are
+There are (a few) known breakages in certain older boards, such bugs are
usually worked around by the kernel. If your MP-compliant SMP board does
not boot Linux, then consult the linux-smp mailing list archives first.
@@ -28,18 +30,18 @@ If your box boots fine with enabled IO-APIC IRQs, then your
hell:~>
<----------------------------
-some interrupts are still listed as 'XT PIC', but this is not a problem,
+Some interrupts are still listed as 'XT PIC', but this is not a problem;
none of those IRQ sources is performance-critical.
-in the unlikely case that your board does not create a working mp-table,
+In the unlikely case that your board does not create a working mp-table,
you can use the pirq= boot parameter to 'hand-construct' IRQ entries. This
-is nontrivial though and cannot be automated. One sample /etc/lilo.conf
+is non-trivial though and cannot be automated. One sample /etc/lilo.conf
entry:
append="pirq=15,11,10"
-the actual numbers depend on your system, on your PCI cards and on their
+The actual numbers depend on your system, on your PCI cards and on their
PCI slot position. Usually PCI slots are 'daisy chained' before they are
connected to the PCI chipset IRQ routing facility (the incoming PIRQ1-4
lines):
@@ -54,7 +56,7 @@ lines):
PIRQ1 ----| |- `----| |- `----| |- `----| |--------| |
`-' `-' `-' `-' `-'
-every PCI card emits a PCI IRQ, which can be INTA,INTB,INTC,INTD:
+Every PCI card emits a PCI IRQ, which can be INTA, INTB, INTC or INTD:
,-.
INTD--| |
@@ -95,21 +97,21 @@ card (IRQ11) in Slot3, and have Slot1 empty:
[value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting)
slots.]
-generally, it's always possible to find out the correct pirq= settings, just
+Generally, it's always possible to find out the correct pirq= settings, just
permute all IRQ numbers properly ... it will take some time though. An
'incorrect' pirq line will cause the booting process to hang, or a device
-won't function properly (if it's inserted as eg. a module).
+won't function properly (e.g. if it's inserted as a module).
-If you have 2 PCI buses, then you can use up to 8 pirq values. Although such
+If you have 2 PCI buses, then you can use up to 8 pirq values, although such
boards tend to have a good configuration.
Be prepared that it might happen that you need some strange pirq line:
append="pirq=0,0,0,0,0,0,9,11"
-use smart try-and-err techniques to find out the correct pirq line ...
+Use smart trial-and-error techniques to find out the correct pirq line ...
-good luck and mail to linux-smp@vger.kernel.org or
+Good luck and mail to linux-smp@vger.kernel.org or
linux-kernel@vger.kernel.org if you have any problems that are not covered
by this document.
diff --git a/Documentation/ide/00-INDEX b/Documentation/ide/00-INDEX
new file mode 100644
index 00000000000..d6b778842b7
--- /dev/null
+++ b/Documentation/ide/00-INDEX
@@ -0,0 +1,12 @@
+00-INDEX
+ - this file
+ChangeLog.ide-cd.1994-2004
+ - ide-cd changelog
+ChangeLog.ide-floppy.1996-2002
+ - ide-floppy changelog
+ChangeLog.ide-tape.1995-2002
+ - ide-tape changelog
+ide-tape.txt
+ - info on the IDE ATAPI streaming tape driver
+ide.txt
+ - important info for users of ATA devices (IDE/EIDE disks and CD-ROMS).
diff --git a/Documentation/ide.txt b/Documentation/ide/ide.txt
index 94e2e3b9e77..e3b3425328b 100644
--- a/Documentation/ide.txt
+++ b/Documentation/ide/ide.txt
@@ -3,11 +3,11 @@
==============================================================================
-
+
The hdparm utility can be used to control various IDE features on a
running system. It is packaged separately. Please Look for it on popular
linux FTP sites.
-
+
*** IMPORTANT NOTICES: BUGGY IDE CHIPSETS CAN CORRUPT DATA!!
@@ -51,7 +51,7 @@ Common pitfalls:
================================================================================
-This is the multiple IDE interface driver, as evolved from hd.c.
+This is the multiple IDE interface driver, as evolved from hd.c.
It supports up to 9 IDE interfaces per default, on one or more IRQs (usually
14 & 15). There can be up to two drives per interface, as per the ATA-6 spec.
@@ -215,17 +215,17 @@ Summary of ide driver parameters for kernel command line
--------------------------------------------------------
"hdx=" is recognized for all "x" from "a" to "h", such as "hdc".
-
+
"idex=" is recognized for all "x" from "0" to "3", such as "ide1".
"hdx=noprobe" : drive may be present, but do not probe for it
-
+
"hdx=none" : drive is NOT present, ignore cmos and do not probe
-
+
"hdx=nowerr" : ignore the WRERR_STAT bit on this drive
-
+
"hdx=cdrom" : drive is present, and is a cdrom drive
-
+
"hdx=cyl,head,sect" : disk drive is present, with specified geometry
"hdx=remap" : remap access of sector 0 to sector 1 (for EZDrive)
@@ -258,12 +258,10 @@ Summary of ide driver parameters for kernel command line
As for VLB, it is safest to not specify it.
Bigger values are safer than smaller ones.
- "idex=noprobe" : do not attempt to access/use this interface
-
"idex=base" : probe for an interface at the addr specified,
where "base" is usually 0x1f0 or 0x170
and "ctl" is assumed to be "base"+0x206
-
+
"idex=base,ctl" : specify both base and ctl
"idex=base,ctl,irq" : specify base, ctl, and irq number
@@ -274,7 +272,7 @@ Summary of ide driver parameters for kernel command line
to take effect.
"idex=four" : four drives on idex and ide(x^1) share same ports
-
+
"idex=reset" : reset interface after probe
"idex=ata66" : informs the interface that it has an 80c cable
@@ -309,53 +307,6 @@ are detected automatically).
================================================================================
-IDE ATAPI streaming tape driver
--------------------------------
-
-This driver is a part of the Linux ide driver and works in co-operation
-with linux/drivers/block/ide.c.
-
-The driver, in co-operation with ide.c, basically traverses the
-request-list for the block device interface. The character device
-interface, on the other hand, creates new requests, adds them
-to the request-list of the block device, and waits for their completion.
-
-Pipelined operation mode is now supported on both reads and writes.
-
-The block device major and minor numbers are determined from the
-tape's relative position in the ide interfaces, as explained in ide.c.
-
-The character device interface consists of the following devices:
-
- ht0 major 37, minor 0 first IDE tape, rewind on close.
- ht1 major 37, minor 1 second IDE tape, rewind on close.
- ...
- nht0 major 37, minor 128 first IDE tape, no rewind on close.
- nht1 major 37, minor 129 second IDE tape, no rewind on close.
- ...
-
-Run /dev/MAKEDEV to create the above entries.
-
-The general magnetic tape commands compatible interface, as defined by
-include/linux/mtio.h, is accessible through the character device.
-
-General ide driver configuration options, such as the interrupt-unmask
-flag, can be configured by issuing an ioctl to the block device interface,
-as any other ide device.
-
-Our own ide-tape ioctl's can be issued to either the block device or
-the character device interface.
-
-Maximal throughput with minimal bus load will usually be achieved in the
-following scenario:
-
- 1. ide-tape is operating in the pipelined operation mode.
- 2. No buffering is performed by the user backup program.
-
-
-
-================================================================================
-
Some Terminology
----------------
IDE = Integrated Drive Electronics, meaning that each drive has a built-in
diff --git a/Documentation/ja_JP/stable_kernel_rules.txt b/Documentation/ja_JP/stable_kernel_rules.txt
index 17d87519e46..b3ffe870de3 100644
--- a/Documentation/ja_JP/stable_kernel_rules.txt
+++ b/Documentation/ja_JP/stable_kernel_rules.txt
@@ -11,69 +11,69 @@ comment or update of this file, please try to update Original(English)
file at first.
==================================
-これは、
+これは、
linux-2.6.24/Documentation/stable_kernel_rules.txt
-の和訳です。
+の和訳です。
-翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
-翻訳日: 2007/12/30
-翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com>
-校正者: 武井伸光さん、<takei at webmasters dot gr dot jp>
- かねこさん (Seiji Kaneko) <skaneko at a2 dot mbn dot or dot jp>
- 小林 雅典さん (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp>
- 野口さん (Kenji Noguchi) <tokyo246 at gmail dot com>
- 神宮信太郎さん <jin at libjingu dot jp>
+翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
+翻訳日: 2007/12/30
+翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com>
+校正者: 武井伸光さん、<takei at webmasters dot gr dot jp>
+ かねこさん (Seiji Kaneko) <skaneko at a2 dot mbn dot or dot jp>
+ 小林 雅典さん (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp>
+ 野口さん (Kenji Noguchi) <tokyo246 at gmail dot com>
+ 神宮信太郎さん <jin at libjingu dot jp>
==================================
-ずっと知りたかった Linux 2.6 -stable リリースの全て
+ずっと知りたかった Linux 2.6 -stable リリースの全て
-"-stable" ツリーにどのような種類のパッチが受け入れられるか、どのような
-ものが受け入れられないか、についての規則-
+"-stable" ツリーにどのような種類のパッチが受け入れられるか、どのような
+ものが受け入れられないか、についての規則-
- - 明らかに正しく、テストされているものでなければならない。
- - 文脈(変更行の前後)を含めて 100 行より大きくてはいけない。
- - ただ一個のことだけを修正しているべき。
- - 皆を悩ませている本物のバグを修正しなければならない。("これはバグで
- あるかもしれないが..." のようなものではない)
- - ビルドエラー(CONFIG_BROKENになっているものを除く), oops, ハング、デー
- タ破壊、現実のセキュリティ問題、その他 "ああ、これはダメだね"という
- ようなものを修正しなければならない。短く言えば、重大な問題。
- - どのように競合状態が発生するかの説明も一緒に書かれていない限り、
- "理論的には競合状態になる"ようなものは不可。
- - いかなる些細な修正も含めることはできない。(スペルの修正、空白のクリー
- ンアップなど)
- - 対応するサブシステムメンテナが受け入れたものでなければならない。
- - Documentation/SubmittingPatches の規則に従ったものでなければならない。
+ - 明らかに正しく、テストされているものでなければならない。
+ - 文脈(変更行の前後)を含めて 100 行より大きくてはいけない。
+ - ただ一個のことだけを修正しているべき。
+ - 皆を悩ませている本物のバグを修正しなければならない。("これはバグで
+ あるかもしれないが..." のようなものではない)
+ - ビルドエラー(CONFIG_BROKENになっているものを除く), oops, ハング、デー
+ タ破壊、現実のセキュリティ問題、その他 "ああ、これはダメだね"という
+ ようなものを修正しなければならない。短く言えば、重大な問題。
+ - どのように競合状態が発生するかの説明も一緒に書かれていない限り、
+ "理論的には競合状態になる"ようなものは不可。
+ - いかなる些細な修正も含めることはできない。(スペルの修正、空白のクリー
+ ンアップなど)
+ - 対応するサブシステムメンテナが受け入れたものでなければならない。
+ - Documentation/SubmittingPatches の規則に従ったものでなければならない。
--stable ツリーにパッチを送付する手続き-
+-stable ツリーにパッチを送付する手続き-
- - 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ
- を送る。
- - 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
- には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
- 日かかる場合がある。
- - もし受け取られたら、パッチは他の開発者たちのレビューのために
- -stable キューに追加される。
- - セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ
- きではなく、代わりに security@kernel.org のアドレスに送られる。
+ - 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ
+ を送る。
+ - 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
+ には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
+ 日かかる場合がある。
+ - もし受け取られたら、パッチは他の開発者たちのレビューのために
+ -stable キューに追加される。
+ - セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ
+ きではなく、代わりに security@kernel.org のアドレスに送られる。
-レビューサイクル-
+レビューサイクル-
- - -stable メンテナがレビューサイクルを決めるとき、パッチはレビュー委
- 員会とパッチが影響する領域のメンテナ(提供者がその領域のメンテナで無
- い限り)に送られ、linux-kernel メーリングリストにCCされる。
- - レビュー委員会は 48時間の間に ACK か NAK を出す。
- - もしパッチが委員会のメンバから却下れるか、メンテナ達やメンバが気付
- かなかった問題が持ちあがり、linux-kernel メンバがパッチに異議を唱え
- た場合には、パッチはキューから削除される。
- - レビューサイクルの最後に、ACK を受けたパッチは最新の -stable リリー
- スに追加され、その後に新しい -stable リリースが行われる。
- - セキュリティパッチは、通常のレビューサイクルを通らず、セキュリティ
- カーネルチームから直接 -stable ツリーに受け付けられる。
- この手続きの詳細については kernel security チームに問い合わせること。
+ - -stable メンテナがレビューサイクルを決めるとき、パッチはレビュー委
+ 員会とパッチが影響する領域のメンテナ(提供者がその領域のメンテナで無
+ い限り)に送られ、linux-kernel メーリングリストにCCされる。
+ - レビュー委員会は 48時間の間に ACK か NAK を出す。
+ - もしパッチが委員会のメンバから却下されるか、メンテナ達やメンバが気付
+ かなかった問題が持ちあがり、linux-kernel メンバがパッチに異議を唱え
+ た場合には、パッチはキューから削除される。
+ - レビューサイクルの最後に、ACK を受けたパッチは最新の -stable リリー
+ スに追加され、その後に新しい -stable リリースが行われる。
+ - セキュリティパッチは、通常のレビューサイクルを通らず、セキュリティ
+ カーネルチームから直接 -stable ツリーに受け付けられる。
+ この手続きの詳細については kernel security チームに問い合わせること。
-レビュー委員会-
+レビュー委員会-
- - この委員会は、このタスクについて活動する多くのボランティアと、少数の
- 非ボランティアのカーネル開発者達で構成されている。
+ - この委員会は、このタスクについて活動する多くのボランティアと、少数の
+ 非ボランティアのカーネル開発者達で構成されている。
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a4fc7fc2143..533e67febf8 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -712,7 +712,7 @@ and is between 256 and 4096 characters. It is defined in the file
Format: <cyl>,<head>,<sect>
hd?= [HW] (E)IDE subsystem
- hd?lun= See Documentation/ide.txt.
+ hd?lun= See Documentation/ide/ide.txt.
highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact
size of <nn>. This works even on boxes that have no
@@ -766,14 +766,14 @@ and is between 256 and 4096 characters. It is defined in the file
ide= [HW] (E)IDE subsystem
Format: ide=nodma or ide=doubler or ide=reverse
- See Documentation/ide.txt.
+ See Documentation/ide/ide.txt.
ide?= [HW] (E)IDE subsystem
Format: ide?=noprobe or chipset specific parameters.
- See Documentation/ide.txt.
+ See Documentation/ide/ide.txt.
idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed
- See Documentation/ide.txt.
+ See Documentation/ide/ide.txt.
idle= [X86]
Format: idle=poll or idle=mwait
@@ -950,6 +950,41 @@ and is between 256 and 4096 characters. It is defined in the file
when set.
Format: <int>
+ libata.force= [LIBATA] Force configurations. The format is comma
+ separated list of "[ID:]VAL" where ID is
+ PORT[:DEVICE]. PORT and DEVICE are decimal numbers
+ matching port, link or device. Basically, it matches
+ the ATA ID string printed on console by libata. If
+ the whole ID part is omitted, the last PORT and DEVICE
+ values are used. If ID hasn't been specified yet, the
+ configuration applies to all ports, links and devices.
+
+ If only DEVICE is omitted, the parameter applies to
+ the port and all links and devices behind it. DEVICE
+ number of 0 either selects the first device or the
+ first fan-out link behind PMP device. It does not
+ select the host link. DEVICE number of 15 selects the
+ host link and device attached to it.
+
+ The VAL specifies the configuration to force. As long
+ as there's no ambiguity shortcut notation is allowed.
+ For example, both 1.5 and 1.5G would work for 1.5Gbps.
+ The following configurations can be forced.
+
+ * Cable type: 40c, 80c, short40c, unk, ign or sata.
+ Any ID with matching PORT is used.
+
+ * SATA link speed limit: 1.5Gbps or 3.0Gbps.
+
+ * Transfer mode: pio[0-7], mwdma[0-4] and udma[0-7].
+ udma[/][16,25,33,44,66,100,133] notation is also
+ allowed.
+
+ * [no]ncq: Turn on or off NCQ.
+
+ If there are multiple matching configurations changing
+ the same attribute, the last one is used.
+
load_ramdisk= [RAM] List of ramdisks to load from floppy
See Documentation/ramdisk.txt.
@@ -1056,8 +1091,6 @@ and is between 256 and 4096 characters. It is defined in the file
[SCSI] Maximum number of LUNs received.
Should be between 1 and 16384.
- mca-pentium [BUGS=X86-32]
-
mcatest= [IA-64]
mce [X86-32] Machine Check Exception
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 83f515c2905..be89f393274 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -192,7 +192,8 @@ code mapping.
The Kprobes API includes a "register" function and an "unregister"
function for each type of probe. Here are terse, mini-man-page
specifications for these functions and the associated probe handlers
-that you'll write. See the latter half of this document for examples.
+that you'll write. See the files in the samples/kprobes/ sub-directory
+for examples.
4.1 register_kprobe
@@ -420,249 +421,15 @@ e. Watchpoint probes (which fire on data references).
8. Kprobes Example
-Here's a sample kernel module showing the use of kprobes to dump a
-stack trace and selected i386 registers when do_fork() is called.
------ cut here -----
-/*kprobe_example.c*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/kprobes.h>
-#include <linux/sched.h>
-
-/*For each probe you need to allocate a kprobe structure*/
-static struct kprobe kp;
-
-/*kprobe pre_handler: called just before the probed instruction is executed*/
-int handler_pre(struct kprobe *p, struct pt_regs *regs)
-{
- printk("pre_handler: p->addr=0x%p, eip=%lx, eflags=0x%lx\n",
- p->addr, regs->eip, regs->eflags);
- dump_stack();
- return 0;
-}
-
-/*kprobe post_handler: called after the probed instruction is executed*/
-void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
-{
- printk("post_handler: p->addr=0x%p, eflags=0x%lx\n",
- p->addr, regs->eflags);
-}
-
-/* fault_handler: this is called if an exception is generated for any
- * instruction within the pre- or post-handler, or when Kprobes
- * single-steps the probed instruction.
- */
-int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
-{
- printk("fault_handler: p->addr=0x%p, trap #%dn",
- p->addr, trapnr);
- /* Return 0 because we don't handle the fault. */
- return 0;
-}
-
-static int __init kprobe_init(void)
-{
- int ret;
- kp.pre_handler = handler_pre;
- kp.post_handler = handler_post;
- kp.fault_handler = handler_fault;
- kp.symbol_name = "do_fork";
-
- ret = register_kprobe(&kp);
- if (ret < 0) {
- printk("register_kprobe failed, returned %d\n", ret);
- return ret;
- }
- printk("kprobe registered\n");
- return 0;
-}
-
-static void __exit kprobe_exit(void)
-{
- unregister_kprobe(&kp);
- printk("kprobe unregistered\n");
-}
-
-module_init(kprobe_init)
-module_exit(kprobe_exit)
-MODULE_LICENSE("GPL");
------ cut here -----
-
-You can build the kernel module, kprobe-example.ko, using the following
-Makefile:
------ cut here -----
-obj-m := kprobe-example.o
-KDIR := /lib/modules/$(shell uname -r)/build
-PWD := $(shell pwd)
-default:
- $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
-clean:
- rm -f *.mod.c *.ko *.o
------ cut here -----
-
-$ make
-$ su -
-...
-# insmod kprobe-example.ko
-
-You will see the trace data in /var/log/messages and on the console
-whenever do_fork() is invoked to create a new process.
+See samples/kprobes/kprobe_example.c
9. Jprobes Example
-Here's a sample kernel module showing the use of jprobes to dump
-the arguments of do_fork().
------ cut here -----
-/*jprobe-example.c */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/uio.h>
-#include <linux/kprobes.h>
-
-/*
- * Jumper probe for do_fork.
- * Mirror principle enables access to arguments of the probed routine
- * from the probe handler.
- */
-
-/* Proxy routine having the same arguments as actual do_fork() routine */
-long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
- struct pt_regs *regs, unsigned long stack_size,
- int __user * parent_tidptr, int __user * child_tidptr)
-{
- printk("jprobe: clone_flags=0x%lx, stack_size=0x%lx, regs=0x%p\n",
- clone_flags, stack_size, regs);
- /* Always end with a call to jprobe_return(). */
- jprobe_return();
- /*NOTREACHED*/
- return 0;
-}
-
-static struct jprobe my_jprobe = {
- .entry = jdo_fork
-};
-
-static int __init jprobe_init(void)
-{
- int ret;
- my_jprobe.kp.symbol_name = "do_fork";
-
- if ((ret = register_jprobe(&my_jprobe)) <0) {
- printk("register_jprobe failed, returned %d\n", ret);
- return -1;
- }
- printk("Planted jprobe at %p, handler addr %p\n",
- my_jprobe.kp.addr, my_jprobe.entry);
- return 0;
-}
-
-static void __exit jprobe_exit(void)
-{
- unregister_jprobe(&my_jprobe);
- printk("jprobe unregistered\n");
-}
-
-module_init(jprobe_init)
-module_exit(jprobe_exit)
-MODULE_LICENSE("GPL");
------ cut here -----
-
-Build and insert the kernel module as shown in the above kprobe
-example. You will see the trace data in /var/log/messages and on
-the console whenever do_fork() is invoked to create a new process.
-(Some messages may be suppressed if syslogd is configured to
-eliminate duplicate messages.)
+See samples/kprobes/jprobe_example.c
10. Kretprobes Example
-Here's a sample kernel module showing the use of return probes to
-report failed calls to sys_open().
------ cut here -----
-/*kretprobe-example.c*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/kprobes.h>
-#include <linux/ktime.h>
-
-/* per-instance private data */
-struct my_data {
- ktime_t entry_stamp;
-};
-
-static const char *probed_func = "sys_open";
-
-/* Timestamp function entry. */
-static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- struct my_data *data;
-
- if(!current->mm)
- return 1; /* skip kernel threads */
-
- data = (struct my_data *)ri->data;
- data->entry_stamp = ktime_get();
- return 0;
-}
-
-/* If the probed function failed, log the return value and duration.
- * Duration may turn out to be zero consistently, depending upon the
- * granularity of time accounting on the platform. */
-static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- int retval = regs_return_value(regs);
- struct my_data *data = (struct my_data *)ri->data;
- s64 delta;
- ktime_t now;
-
- if (retval < 0) {
- now = ktime_get();
- delta = ktime_to_ns(ktime_sub(now, data->entry_stamp));
- printk("%s: return val = %d (duration = %lld ns)\n",
- probed_func, retval, delta);
- }
- return 0;
-}
-
-static struct kretprobe my_kretprobe = {
- .handler = return_handler,
- .entry_handler = entry_handler,
- .data_size = sizeof(struct my_data),
- .maxactive = 20, /* probe up to 20 instances concurrently */
-};
-
-static int __init kretprobe_init(void)
-{
- int ret;
- my_kretprobe.kp.symbol_name = (char *)probed_func;
-
- if ((ret = register_kretprobe(&my_kretprobe)) < 0) {
- printk("register_kretprobe failed, returned %d\n", ret);
- return -1;
- }
- printk("Kretprobe active on %s\n", my_kretprobe.kp.symbol_name);
- return 0;
-}
-
-static void __exit kretprobe_exit(void)
-{
- unregister_kretprobe(&my_kretprobe);
- printk("kretprobe unregistered\n");
- /* nmissed > 0 suggests that maxactive was set too low. */
- printk("Missed probing %d instances of %s\n",
- my_kretprobe.nmissed, probed_func);
-}
-
-module_init(kretprobe_init)
-module_exit(kretprobe_exit)
-MODULE_LICENSE("GPL");
------ cut here -----
-
-Build and insert the kernel module as shown in the above kprobe
-example. You will see the trace data in /var/log/messages and on the
-console whenever sys_open() returns a negative value. (Some messages
-may be suppressed if syslogd is configured to eliminate duplicate
-messages.)
+See samples/kprobes/kretprobe_example.c
For additional information on Kprobes, refer to the following URLs:
http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 6c2477754a2..76cb428435d 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -160,7 +160,7 @@ Hot keys
procfs: /proc/acpi/ibm/hotkey
sysfs device attribute: hotkey_*
-In a ThinkPad, the ACPI HKEY handler is responsible for comunicating
+In a ThinkPad, the ACPI HKEY handler is responsible for communicating
some important events and also keyboard hot key presses to the operating
system. Enabling the hotkey functionality of thinkpad-acpi signals the
firmware that such a driver is present, and modifies how the ThinkPad
@@ -193,7 +193,7 @@ Not all bits in the mask can be modified. Not all bits that can be
modified do anything. Not all hot keys can be individually controlled
by the mask. Some models do not support the mask at all, and in those
models, hot keys cannot be controlled individually. The behaviour of
-the mask is, therefore, higly dependent on the ThinkPad model.
+the mask is, therefore, highly dependent on the ThinkPad model.
Note that unmasking some keys prevents their default behavior. For
example, if Fn+F5 is unmasked, that key will no longer enable/disable
@@ -288,7 +288,7 @@ sysfs notes:
in ACPI event mode, volume up/down/mute are reported as
separate events, but this behaviour may be corrected in
future releases of this driver, in which case the
- ThinkPad volume mixer user interface semanthics will be
+ ThinkPad volume mixer user interface semantics will be
enforced.
hotkey_poll_freq:
@@ -306,13 +306,20 @@ sysfs notes:
The recommended polling frequency is 10Hz.
hotkey_radio_sw:
- if the ThinkPad has a hardware radio switch, this
+ If the ThinkPad has a hardware radio switch, this
attribute will read 0 if the switch is in the "radios
- disabled" postition, and 1 if the switch is in the
+ disabled" position, and 1 if the switch is in the
"radios enabled" position.
This attribute has poll()/select() support.
+ hotkey_tablet_mode:
+ If the ThinkPad has tablet capabilities, this attribute
+ will read 0 if the ThinkPad is in normal mode, and
+ 1 if the ThinkPad is in tablet mode.
+
+ This attribute has poll()/select() support.
+
hotkey_report_mode:
Returns the state of the procfs ACPI event report mode
filter for hot keys. If it is set to 1 (the default),
@@ -339,7 +346,7 @@ sysfs notes:
wakeup_hotunplug_complete:
Set to 1 if the system was waken up because of an
undock or bay ejection request, and that request
- was sucessfully completed. At this point, it might
+ was successfully completed. At this point, it might
be useful to send the system back to sleep, at the
user's choice. Refer to HKEY events 0x4003 and
0x3003, below.
@@ -392,7 +399,7 @@ event code Key Notes
Lenovo: battery
0x1004 0x03 FN+F4 Sleep button (ACPI sleep button
- semanthics, i.e. sleep-to-RAM).
+ semantics, i.e. sleep-to-RAM).
It is always generate some kind
of event, either the hot key
event or a ACPI sleep button
@@ -403,12 +410,12 @@ event code Key Notes
time passes.
0x1005 0x04 FN+F5 Radio. Enables/disables
- the internal BlueTooth hardware
+ the internal Bluetooth hardware
and W-WAN card if left in control
of the firmware. Does not affect
the WLAN card.
Should be used to turn on/off all
- radios (bluetooth+W-WAN+WLAN),
+ radios (Bluetooth+W-WAN+WLAN),
really.
0x1006 0x05 FN+F6 -
@@ -417,7 +424,7 @@ event code Key Notes
Do you feel lucky today?
0x1008 0x07 FN+F8 IBM: toggle screen expand
- Lenovo: configure ultranav
+ Lenovo: configure UltraNav
0x1009 0x08 FN+F9 -
.. .. ..
@@ -447,7 +454,7 @@ event code Key Notes
0x1011 0x10 FN+END Brightness down. See brightness
up for details.
-0x1012 0x11 FN+PGUP Thinklight toggle. This key is
+0x1012 0x11 FN+PGUP ThinkLight toggle. This key is
always handled by the firmware,
even when unmasked.
@@ -469,7 +476,7 @@ event code Key Notes
key is always handled by the
firmware, even when unmasked.
-0x1018 0x17 THINKPAD Thinkpad/Access IBM/Lenovo key
+0x1018 0x17 THINKPAD ThinkPad/Access IBM/Lenovo key
0x1019 0x18 unknown
.. .. ..
@@ -488,9 +495,17 @@ If a key is mapped to KEY_UNKNOWN, it generates an input event that
includes an scan code. If a key is mapped to anything else, it will
generate input device EV_KEY events.
+In addition to the EV_KEY events, thinkpad-acpi may also issue EV_SW
+events for switches:
+
+SW_RADIO T60 and later hardare rfkill rocker switch
+SW_TABLET_MODE Tablet ThinkPads HKEY events 0x5009 and 0x500A
+
Non hot-key ACPI HKEY event map:
0x5001 Lid closed
0x5002 Lid opened
+0x5009 Tablet swivel: switched to tablet mode
+0x500A Tablet swivel: switched to normal mode
0x7000 Radio Switch may have changed state
The above events are not propagated by the driver, except for legacy
@@ -505,9 +520,7 @@ The above events are never propagated by the driver.
0x3003 Bay ejection (see 0x2x05) complete, can sleep again
0x4003 Undocked (see 0x2x04), can sleep again
-0x5009 Tablet swivel: switched to tablet mode
-0x500A Tablet swivel: switched to normal mode
-0x500B Tablet pen insterted into its storage bay
+0x500B Tablet pen inserted into its storage bay
0x500C Tablet pen removed from its storage bay
0x5010 Brightness level changed (newer Lenovo BIOSes)
@@ -539,7 +552,7 @@ sysfs (it is read-only).
If the hotkey_report_mode module parameter is set to 1 or 2, it cannot
be changed later through sysfs (any writes will return -EPERM to signal
that hotkey_report_mode was locked. On 2.6.23 and later, where
-hotkey_report_mode cannot be changed at all, writes will return -EACES).
+hotkey_report_mode cannot be changed at all, writes will return -EACCES).
hotkey_report_mode set to 1 makes the driver export through the procfs
ACPI event interface all hot key presses (which are *also* sent to the
@@ -584,7 +597,7 @@ Sysfs notes:
0: disables Bluetooth / Bluetooth is disabled
1: enables Bluetooth / Bluetooth is enabled.
- Note: this interface will be probably be superseeded by the
+ Note: this interface will be probably be superseded by the
generic rfkill class, so it is NOT to be considered stable yet.
Video output control -- /proc/acpi/ibm/video
@@ -791,12 +804,12 @@ on the X40 (tpb is the ThinkPad Buttons utility):
1 - Related to "Volume up" key press
2 - Related to "Mute on" key press
3 - Related to "Access IBM" key press
- 4 - Related to "LCD brightness up" key pess
+ 4 - Related to "LCD brightness up" key press
5 - Related to "LCD brightness down" key press
11 - Related to "toggle screen expansion" key press/function
12 - Related to "ThinkLight on"
13 - Related to "ThinkLight off"
- 14 - Related to "ThinkLight" key press (toggle thinklight)
+ 14 - Related to "ThinkLight" key press (toggle ThinkLight)
The cmos command interface is prone to firmware split-brain problems, as
in newer ThinkPads it is just a compatibility layer. Do not use it, it is
@@ -1024,7 +1037,7 @@ There are two interfaces to the firmware for direct brightness control,
EC and CMOS. To select which one should be used, use the
brightness_mode module parameter: brightness_mode=1 selects EC mode,
brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC
-and CMOS. The driver tries to autodetect which interface to use.
+and CMOS. The driver tries to auto-detect which interface to use.
When display backlight brightness controls are available through the
standard ACPI interface, it is best to use it instead of this direct
@@ -1266,8 +1279,8 @@ experimental=1 parameter when loading the module.
This feature shows the presence and current state of a W-WAN (Sierra
Wireless EV-DO) device.
-It was tested on a Lenovo Thinkpad X60. It should probably work on other
-Thinkpad models which come with this module installed.
+It was tested on a Lenovo ThinkPad X60. It should probably work on other
+ThinkPad models which come with this module installed.
Procfs notes:
@@ -1286,7 +1299,7 @@ Sysfs notes:
0: disables WWAN card / WWAN card is disabled
1: enables WWAN card / WWAN card is enabled.
- Note: this interface will be probably be superseeded by the
+ Note: this interface will be probably be superseded by the
generic rfkill class, so it is NOT to be considered stable yet.
Multiple Commands, Module Parameters
@@ -1309,7 +1322,7 @@ Enabling debugging output
The module takes a debug parameter which can be used to selectively
enable various classes of debugging output, for example:
- modprobe ibm_acpi debug=0xffff
+ modprobe thinkpad_acpi debug=0xffff
will enable all debugging output classes. It takes a bitmask, so
to enable more than one output class, just add their values.
@@ -1356,7 +1369,7 @@ Sysfs interface changelog:
NVRAM is compiled out by the user because it is
unneeded/undesired in the first place).
0x020101: Marker for thinkpad-acpi with hot key NVRAM polling
- and proper hotkey_mask semanthics (version 8 of the
+ and proper hotkey_mask semantics (version 8 of the
NVRAM polling patch). Some development snapshots of
0.18 had an earlier version that did strange things
to hotkey_mask.
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 4e17beba237..1f506f7830e 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -1493,7 +1493,7 @@ explicit lock operations, described later). These include:
atomic_dec_and_test();
atomic_sub_and_test();
atomic_add_negative();
- atomic_add_unless();
+ atomic_add_unless(); /* when succeeds (returns 1) */
test_and_set_bit();
test_and_clear_bit();
test_and_change_bit();
diff --git a/Documentation/networking/tcp.txt b/Documentation/networking/tcp.txt
index 0121edc3ba0..7d11bb5dc30 100644
--- a/Documentation/networking/tcp.txt
+++ b/Documentation/networking/tcp.txt
@@ -1,7 +1,7 @@
TCP protocol
============
-Last updated: 21 June 2005
+Last updated: 9 February 2008
Contents
========
@@ -52,9 +52,9 @@ research and RFC's before developing new modules.
The method that is used to determine which congestion control mechanism is
determined by the setting of the sysctl net.ipv4.tcp_congestion_control.
The default congestion control will be the last one registered (LIFO);
-so if you built everything as modules. the default will be reno. If you
-build with the default's from Kconfig, then BIC will be builtin (not a module)
-and it will end up the default.
+so if you built everything as modules, the default will be reno. If you
+build with the defaults from Kconfig, then CUBIC will be builtin (not a
+module) and it will end up the default.
If you really want a particular default value then you will need
to set it with the sysctl. If you use a sysctl, the module will be autoloaded
diff --git a/Documentation/pci.txt b/Documentation/pci.txt
index 72b20c63959..bb7bd27d468 100644
--- a/Documentation/pci.txt
+++ b/Documentation/pci.txt
@@ -123,7 +123,8 @@ initialization with a pointer to a structure describing the driver
The ID table is an array of struct pci_device_id entries ending with an
-all-zero entry. Each entry consists of:
+all-zero entry; use of the macro DECLARE_PCI_DEVICE_TABLE is the preferred
+method of declaring the table. Each entry consists of:
vendor,device Vendor and device ID to match (or PCI_ANY_ID)
@@ -191,7 +192,8 @@ Tips on when/where to use the above attributes:
o Do not mark the struct pci_driver.
- o The ID table array should be marked __devinitdata.
+ o The ID table array should be marked __devinitconst; this is done
+ automatically if the table is declared with DECLARE_PCI_DEVICE_TABLE().
o The probe() and remove() functions should be marked __devinit
and __devexit respectively. All initialization functions
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index c53d2636191..461e4f1dbec 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -310,9 +310,12 @@ used with suspend-to-disk:
PM_EVENT_SUSPEND -- quiesce the driver and put hardware into a low-power
state. When used with system sleep states like "suspend-to-RAM" or
"standby", the upcoming resume() call will often be able to rely on
- state kept in hardware, or issue system wakeup events. When used
- instead with suspend-to-disk, few devices support this capability;
- most are completely powered off.
+ state kept in hardware, or issue system wakeup events.
+
+ PM_EVENT_HIBERNATE -- Put hardware into a low-power state and enable wakeup
+ events as appropriate. It is only used with hibernation
+ (suspend-to-disk) and few devices are able to wake up the system from
+ this state; most are completely powered off.
PM_EVENT_FREEZE -- quiesce the driver, but don't necessarily change into
any low power mode. A system snapshot is about to be taken, often
@@ -329,8 +332,8 @@ used with suspend-to-disk:
wakeup events nor DMA are allowed.
To enter "standby" (ACPI S1) or "Suspend to RAM" (STR, ACPI S3) states, or
-the similarly named APM states, only PM_EVENT_SUSPEND is used; for "Suspend
-to Disk" (STD, hibernate, ACPI S4), all of those event codes are used.
+the similarly named APM states, only PM_EVENT_SUSPEND is used; the other event
+codes are used for hibernation ("Suspend to Disk", STD, ACPI S4).
There's also PM_EVENT_ON, a value which never appears as a suspend event
but is sometimes used to record the "not suspended" device state.
diff --git a/Documentation/scsi/ChangeLog.arcmsr b/Documentation/scsi/ChangeLog.arcmsr
index de2bcacfa87..038a3e6ecaa 100644
--- a/Documentation/scsi/ChangeLog.arcmsr
+++ b/Documentation/scsi/ChangeLog.arcmsr
@@ -109,4 +109,10 @@
** 8.replace pci_alloc_consistent()/pci_free_consistent() with kmalloc()/kfree() in arcmsr_iop_message_xfer()
** 9. fix the release of dma memory for type B in arcmsr_free_ccb_pool()
** 10.fix the arcmsr_polling_hbb_ccbdone()
+** 1.20.00.15 02/27/2008 Erich Chen & Nick Cheng
+** 1.arcmsr_iop_message_xfer() is called from atomic context under the
+** queuecommand scsi_host_template handler. James Bottomley pointed out
+** that the current GFP_KERNEL|GFP_DMA flags are wrong: firstly we are in
+** atomic context, secondly this memory is not used for DMA.
+** Also removed some unneeded casts. Thanks to Daniel Drake <dsd@gentoo.org>
**************************************************************************
diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt
index c815c5206e8..4cfc78835bc 100644
--- a/Documentation/stable_kernel_rules.txt
+++ b/Documentation/stable_kernel_rules.txt
@@ -16,8 +16,9 @@ Rules on what kind of patches are accepted, and which ones are not, into the
race can be exploited is also provided.
- It cannot contain any "trivial" fixes in it (spelling changes,
whitespace cleanups, etc).
- - It must be accepted by the relevant subsystem maintainer.
- It must follow the Documentation/SubmittingPatches rules.
+ - It or an equivalent fix must already exist in Linus' tree. Quote the
+ respective commit ID in Linus' tree in your patch submission to -stable.
Procedure for submitting patches to the -stable tree:
@@ -28,7 +29,9 @@ Procedure for submitting patches to the -stable tree:
queue, or a NAK if the patch is rejected. This response might take a few
days, according to the developer's schedules.
- If accepted, the patch will be added to the -stable queue, for review by
- other developers.
+ other developers and by the relevant subsystem maintainer.
+ - If the stable@kernel.org address is added to a patch, when it goes into
+ Linus's tree it will automatically be emailed to the stable team.
- Security patches should not be sent to this alias, but instead to the
documented security@kernel.org address.
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index 6a8469f2bca..f40e09296f3 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -8,7 +8,7 @@
7 -> Leadtek Winfast USB II (em2800)
8 -> Kworld USB2800 (em2800)
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
- 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
+ 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500,2040:6502]
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 5d3b6b4d251..0424901ebc7 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -92,9 +92,9 @@
91 -> AVerMedia A169 B [1461:7360]
92 -> AVerMedia A169 B1 [1461:6360]
93 -> Medion 7134 Bridge #2 [16be:0005]
- 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,4e42:3502]
+ 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,5168:3307,4e42:3502]
95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138]
- 96 -> Medion Md8800 Quadro [16be:0007,16be:0008]
+ 96 -> Medion Md8800 Quadro [16be:0007,16be:0008,16be:000d]
97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300]
98 -> Proteus Pro 2309 [0919:2003]
99 -> AVerMedia TV Hybrid A16AR [1461:2c00]
@@ -129,3 +129,5 @@
128 -> Beholder BeholdTV Columbus TVFM [0000:5201]
129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193]
+131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022]
+132 -> Genius TVGO AM11MCE
diff --git a/Documentation/video4linux/zr364xx.txt b/Documentation/video4linux/zr364xx.txt
index 4d9a0c33f2f..5c81e3ae645 100644
--- a/Documentation/video4linux/zr364xx.txt
+++ b/Documentation/video4linux/zr364xx.txt
@@ -25,7 +25,7 @@ modprobe zr364xx debug=X mode=Y
- debug : set to 1 to enable verbose debug messages
- mode : 0 = 320x240, 1 = 160x120, 2 = 640x480
You can then use the camera with V4L2 compatible applications, for example Ekiga.
-To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1 count=1
+To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1M count=1
links :
http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
@@ -63,3 +63,5 @@ Vendor Product Distributor Model
0x06d6 0x0034 Trust Powerc@m 750
0x0a17 0x0062 Pentax Optio 50L
0x06d6 0x003b Trust Powerc@m 970Z
+0x0a17 0x004e Pentax Optio 50
+0x041e 0x405d Creative DiVi CAM 516
diff --git a/Documentation/vm/slabinfo.c b/Documentation/vm/slabinfo.c
index 7123fee708c..22d7e3e4d60 100644
--- a/Documentation/vm/slabinfo.c
+++ b/Documentation/vm/slabinfo.c
@@ -1123,7 +1123,7 @@ void read_slab_dir(void)
char *t;
int count;
- if (chdir("/sys/kernel/slab"))
+ if (chdir("/sys/kernel/slab") && chdir("/sys/slab"))
fatal("SYSFS support for SLUB not active\n");
dir = opendir(".");
diff --git a/Documentation/vm/slub.txt b/Documentation/vm/slub.txt
index dcf8bcf846d..7c13f22a0c9 100644
--- a/Documentation/vm/slub.txt
+++ b/Documentation/vm/slub.txt
@@ -50,14 +50,14 @@ F.e. in order to boot just with sanity checks and red zoning one would specify:
Trying to find an issue in the dentry cache? Try
- slub_debug=,dentry_cache
+ slub_debug=,dentry
to only enable debugging on the dentry cache.
Red zoning and tracking may realign the slab. We can just apply sanity checks
to the dentry cache with
- slub_debug=F,dentry_cache
+ slub_debug=F,dentry
In case you forgot to enable debugging on the kernel command line: It is
possible to enable debugging manually when the kernel is up. Look at the
diff --git a/MAINTAINERS b/MAINTAINERS
index 1d2edb491b3..558636e3a95 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -640,8 +640,8 @@ S: Maintained
ASYNCHRONOUS TRANSFERS/TRANSFORMS API
P: Dan Williams
M: dan.j.williams@intel.com
-P: Shannon Nelson
-M: shannon.nelson@intel.com
+P: Maciej Sosnowski
+M: maciej.sosnowski@intel.com
L: linux-kernel@vger.kernel.org
W: http://sourceforge.net/projects/xscaleiop
S: Supported
@@ -697,7 +697,7 @@ S: Supported
ATMEL LCDFB DRIVER
P: Nicolas Ferre
M: nicolas.ferre@atmel.com
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
ATMEL MACB ETHERNET DRIVER
@@ -767,14 +767,14 @@ S: Maintained
BLACKFIN ARCHITECTURE
P: Bryan Wu
-M: bryan.wu@analog.com
+M: cooloney@kernel.org
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org
S: Supported
BLACKFIN EMAC DRIVER
P: Bryan Wu
-M: bryan.wu@analog.com
+M: cooloney@kernel.org
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org
S: Supported
@@ -982,6 +982,12 @@ M: mchan@broadcom.com
L: netdev@vger.kernel.org
S: Supported
+BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
+P: Eliezer Tamir
+M: eliezert@broadcom.com
+L: netdev@vger.kernel.org
+S: Supported
+
BROADCOM TG3 GIGABIT ETHERNET DRIVER
P: Michael Chan
M: mchan@broadcom.com
@@ -1132,6 +1138,12 @@ L: accessrunner-general@lists.sourceforge.net
W: http://accessrunner.sourceforge.net/
S: Maintained
+CONTROL GROUPS (CGROUPS)
+P: Paul Menage
+M: menage@google.com
+L: containers@lists.linux-foundation.org
+S: Maintained
+
CORETEMP HARDWARE MONITORING DRIVER
P: Rudolf Marek
M: r.marek@assembler.cz
@@ -1202,7 +1214,7 @@ S: Maintained
CYBLAFB FRAMEBUFFER DRIVER
P: Knut Petersen
M: Knut_Petersen@t-online.de
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
CYCLADES 2X SYNC CARD DRIVER
@@ -1324,8 +1336,7 @@ P: David Teigland
M: teigland@redhat.com
L: cluster-devel@redhat.com
W: http://sources.redhat.com/cluster/
-T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git
-T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git
+T: git kernel.org:/pub/scm/linux/kernel/git/teigland/dlm.git
S: Supported
DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER
@@ -1335,8 +1346,8 @@ L: netdev@vger.kernel.org
S: Maintained
DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
-P: Shannon Nelson
-M: shannon.nelson@intel.com
+P: Maciej Sosnowski
+M: maciej.sosnowski@intel.com
P: Dan Williams
M: dan.j.williams@intel.com
L: linux-kernel@vger.kernel.org
@@ -1580,10 +1591,17 @@ S: Supported
FRAMEBUFFER LAYER
P: Antonino Daplas
M: adaplas@gmail.com
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
W: http://linux-fbdev.sourceforge.net/
S: Maintained
+FREESCALE DMA DRIVER
+P; Zhang Wei
+M: wei.zhang@freescale.com
+L: linuxppc-embedded@ozlabs.org
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
FREESCALE SOC FS_ENET DRIVER
P: Pantelis Antoniou
M: pantelis.antoniou@gmail.com
@@ -1713,9 +1731,7 @@ T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git release
S: Maintained
HARDWARE RANDOM NUMBER GENERATOR CORE
-P: Michael Buesch
-M: mb@bu3sch.de
-S: Maintained
+S: Orphaned
HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
P: Robert Love
@@ -1924,7 +1940,7 @@ S: Maintained
IDE/ATAPI CDROM DRIVER
P: Borislav Petkov
-M: bbpetkov@yahoo.de
+M: petkovbb@gmail.com
L: linux-ide@vger.kernel.org
S: Maintained
@@ -1965,7 +1981,7 @@ L: linux1394-devel@lists.sourceforge.net
S: Maintained
IMS TWINTURBO FRAMEBUFFER DRIVER
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Orphan
INFINIBAND SUBSYSTEM
@@ -1999,13 +2015,13 @@ S: Maintained
INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
P: Sylvain Meyer
M: sylvain.meyer@worldonline.fr
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
INTEL 810/815 FRAMEBUFFER DRIVER
P: Antonino Daplas
M: adaplas@gmail.com
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
INTEL IA32 MICROCODE UPDATE SUPPORT
@@ -2014,8 +2030,8 @@ M: tigran@aivazian.fsnet.co.uk
S: Maintained
INTEL I/OAT DMA DRIVER
-P: Shannon Nelson
-M: shannon.nelson@intel.com
+P: Maciej Sosnowski
+M: maciej.sosnowski@intel.com
L: linux-kernel@vger.kernel.org
S: Supported
@@ -2601,7 +2617,7 @@ S: Odd Fixes for 2.4; Maintained for 2.6.
MATROX FRAMEBUFFER DRIVER
P: Petr Vandrovec
M: vandrove@vc.cvut.cz
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
@@ -2623,6 +2639,17 @@ L: linux-kernel@vger.kernel.org
W: http://www.linux-mm.org
S: Maintained
+MEMORY RESOURCE CONTROLLER
+P: Balbir Singh
+M: balbir@linux.vnet.ibm.com
+P: Pavel Emelyanov
+M: xemul@openvz.org
+P: KAMEZAWA Hiroyuki
+M: kamezawa.hiroyu@jp.fujitsu.com
+L: linux-mm@kvack.org
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
MEI MN10300/AM33 PORT
P: David Howells
M: dhowells@redhat.com
@@ -2747,6 +2774,8 @@ S: Maintained
NETEFFECT IWARP RNIC DRIVER (IW_NES)
P: Faisal Latif
M: flatif@neteffect.com
+P: Nishi Gupta
+M: ngupta@neteffect.com
P: Glenn Streiff
M: gstreiff@neteffect.com
L: general@lists.openfabrics.org
@@ -2910,7 +2939,7 @@ S: Maintained
NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER
P: Antonino Daplas
M: adaplas@gmail.com
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
OPENCORES I2C BUS DRIVER
@@ -3239,13 +3268,13 @@ S: Maintained
RADEON FRAMEBUFFER DISPLAY DRIVER
P: Benjamin Herrenschmidt
M: benh@kernel.crashing.org
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
RAGE128 FRAMEBUFFER DISPLAY DRIVER
P: Paul Mackerras
M: paulus@samba.org
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
@@ -3350,7 +3379,7 @@ S: Maintained
S3 SAVAGE FRAMEBUFFER DRIVER
P: Antonino Daplas
M: adaplas@gmail.com
-L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
S390
@@ -3887,10 +3916,13 @@ M: trivial@kernel.org
L: linux-kernel@vger.kernel.org
S: Maintained
-TULIP NETWORK DRIVER
-L: tulip-users@lists.sourceforge.net
-W: http://sourceforge.net/projects/tulip/
-S: Orphan
+TULIP NETWORK DRIVERS
+P: Grant Grundler
+M: grundler@parisc-linux.org
+P: Kyle McMartin
+M: kyle@parisc-linux.org
+L: netdev@vger.kernel.org
+S: Maintained
TUN/TAP driver
P: Maxim Krasnyansky
@@ -4262,7 +4294,7 @@ S: Maintained
VT8231 HARDWARE MONITOR DRIVER
P: Roger Lucas
-M: roger@planbit.co.uk
+M: vt8231@hiddenengine.co.uk
L: lm-sensors@lm-sensors.org
S: Maintained
diff --git a/Makefile b/Makefile
index c162370c736..ae78a31a9de 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 25
-EXTRAVERSION = -rc1
-NAME = Arr Matey! A Hairy Bilge Rat!
+EXTRAVERSION = -rc4
+NAME = Funky Weasel is Jiggy wit it
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
@@ -507,6 +507,10 @@ else
KBUILD_CFLAGS += -O2
endif
+# Force gcc to behave correct even for buggy distributions
+# Arch Makefiles may override this setting
+KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
+
include $(srctree)/arch/$(SRCARCH)/Makefile
ifdef CONFIG_FRAME_POINTER
@@ -525,9 +529,6 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
endif
-# Force gcc to behave correct even for buggy distributions
-KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
-
# arch Makefile may override CC so keep this after arch Makefile is included
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
CHECKFLAGS += $(NOSTDINC_FLAGS)
@@ -810,7 +811,9 @@ endif
$(Q)rm -f .old_version
# build vmlinux.o first to catch section mismatch errors early
-$(kallsyms.o): vmlinux.o
+ifdef CONFIG_KALLSYMS
+.tmp_vmlinux1: vmlinux.o
+endif
vmlinux.o: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE
$(call if_changed_rule,vmlinux-modpost)
diff --git a/arch/Kconfig b/arch/Kconfig
index 3d72dc3fc8f..694c9af520b 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -27,5 +27,12 @@ config KPROBES
for kernel debugging, non-intrusive instrumentation and testing.
If in doubt, say "N".
+config KRETPROBES
+ def_bool y
+ depends on KPROBES && HAVE_KRETPROBES
+
config HAVE_KPROBES
def_bool n
+
+config HAVE_KRETPROBES
+ def_bool n
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 26d3789dfdd..e07a23fc5b7 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -31,7 +31,6 @@
#endif
#define DEBUG_NODIRECT 0
-#define DEBUG_FORCEDAC 0
#define ISA_DMA_MASK 0x00ffffff
@@ -126,39 +125,66 @@ iommu_arena_new(struct pci_controller *hose, dma_addr_t base,
return iommu_arena_new_node(0, hose, base, window_size, align);
}
+static inline int is_span_boundary(unsigned int index, unsigned int nr,
+ unsigned long shift,
+ unsigned long boundary_size)
+{
+ shift = (shift + index) & (boundary_size - 1);
+ return shift + nr > boundary_size;
+}
+
/* Must be called with the arena lock held */
static long
-iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask)
+iommu_arena_find_pages(struct device *dev, struct pci_iommu_arena *arena,
+ long n, long mask)
{
unsigned long *ptes;
long i, p, nent;
+ int pass = 0;
+ unsigned long base;
+ unsigned long boundary_size;
+
+ base = arena->dma_base >> PAGE_SHIFT;
+ if (dev) {
+ boundary_size = dma_get_seg_boundary(dev) + 1;
+ BUG_ON(!is_power_of_2(boundary_size));
+ boundary_size >>= PAGE_SHIFT;
+ } else {
+ boundary_size = 1UL << (32 - PAGE_SHIFT);
+ }
/* Search forward for the first mask-aligned sequence of N free ptes */
ptes = arena->ptes;
nent = arena->size >> PAGE_SHIFT;
- p = (arena->next_entry + mask) & ~mask;
+ p = ALIGN(arena->next_entry, mask + 1);
i = 0;
+
+again:
while (i < n && p+i < nent) {
+ if (!i && is_span_boundary(p, n, base, boundary_size)) {
+ p = ALIGN(p + 1, mask + 1);
+ goto again;
+ }
+
if (ptes[p+i])
- p = (p + i + 1 + mask) & ~mask, i = 0;
+ p = ALIGN(p + i + 1, mask + 1), i = 0;
else
i = i + 1;
}
if (i < n) {
- /* Reached the end. Flush the TLB and restart the
- search from the beginning. */
- alpha_mv.mv_pci_tbi(arena->hose, 0, -1);
-
- p = 0, i = 0;
- while (i < n && p+i < nent) {
- if (ptes[p+i])
- p = (p + i + 1 + mask) & ~mask, i = 0;
- else
- i = i + 1;
- }
-
- if (i < n)
+ if (pass < 1) {
+ /*
+ * Reached the end. Flush the TLB and restart
+ * the search from the beginning.
+ */
+ alpha_mv.mv_pci_tbi(arena->hose, 0, -1);
+
+ pass++;
+ p = 0;
+ i = 0;
+ goto again;
+ } else
return -1;
}
@@ -168,7 +194,8 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask)
}
static long
-iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align)
+iommu_arena_alloc(struct device *dev, struct pci_iommu_arena *arena, long n,
+ unsigned int align)
{
unsigned long flags;
unsigned long *ptes;
@@ -179,7 +206,7 @@ iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align)
/* Search for N empty ptes */
ptes = arena->ptes;
mask = max(align, arena->align_entry) - 1;
- p = iommu_arena_find_pages(arena, n, mask);
+ p = iommu_arena_find_pages(dev, arena, n, mask);
if (p < 0) {
spin_unlock_irqrestore(&arena->lock, flags);
return -1;
@@ -229,6 +256,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
unsigned long paddr;
dma_addr_t ret;
unsigned int align = 0;
+ struct device *dev = pdev ? &pdev->dev : NULL;
paddr = __pa(cpu_addr);
@@ -276,7 +304,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
/* Force allocation to 64KB boundary for ISA bridges. */
if (pdev && pdev == isa_bridge)
align = 8;
- dma_ofs = iommu_arena_alloc(arena, npages, align);
+ dma_ofs = iommu_arena_alloc(dev, arena, npages, align);
if (dma_ofs < 0) {
printk(KERN_WARNING "pci_map_single failed: "
"could not allocate dma page tables\n");
@@ -563,7 +591,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
paddr &= ~PAGE_MASK;
npages = calc_npages(paddr + size);
- dma_ofs = iommu_arena_alloc(arena, npages, 0);
+ dma_ofs = iommu_arena_alloc(dev, arena, npages, 0);
if (dma_ofs < 0) {
/* If we attempted a direct map above but failed, die. */
if (leader->dma_address == 0)
@@ -830,7 +858,7 @@ iommu_reserve(struct pci_iommu_arena *arena, long pg_count, long align_mask)
/* Search for N empty ptes. */
ptes = arena->ptes;
- p = iommu_arena_find_pages(arena, pg_count, align_mask);
+ p = iommu_arena_find_pages(NULL, arena, pg_count, align_mask);
if (p < 0) {
spin_unlock_irqrestore(&arena->lock, flags);
return -1;
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9619c43783f..955fc53c1c0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -12,6 +12,7 @@ config ARM
select SYS_SUPPORTS_APM_EMULATION
select HAVE_OPROFILE
select HAVE_KPROBES if (!XIP_KERNEL)
+ select HAVE_KRETPROBES if (HAVE_KPROBES)
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
@@ -939,7 +940,8 @@ config KEXEC
config ATAGS_PROC
bool "Export atags in procfs"
- default n
+ depends on KEXEC
+ default y
help
Should the atags used to boot the kernel be exported in an "atags"
file in procfs. Useful with kexec.
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 1c7f09aedf0..e473fa6d4a5 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -61,6 +61,7 @@ int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
data[0] = regoffset; /* register num */
data[1] = value; /* register data */
err = i2c_transfer(adap, msg, 1);
+ i2c_put_adapter(adap);
if (err >= 0)
return 0;
return err;
@@ -91,6 +92,7 @@ int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value)
msg->buf = data;
err = i2c_transfer(adap, msg, 1);
*value = data[0];
+ i2c_put_adapter(adap);
if (err >= 0)
return 0;
diff --git a/arch/arm/mach-orion/ts209-setup.c b/arch/arm/mach-orion/ts209-setup.c
index 306dbcd1e37..b8cfe6813e9 100644
--- a/arch/arm/mach-orion/ts209-setup.c
+++ b/arch/arm/mach-orion/ts209-setup.c
@@ -192,9 +192,13 @@ static struct mv643xx_eth_platform_data qnap_ts209_eth_data = {
/*****************************************************************************
* RTC S35390A on I2C bus
****************************************************************************/
+
+#define TS209_RTC_GPIO 3
+
static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = {
.driver_name = "rtc-s35390a",
.addr = 0x30,
+ .irq = 0,
};
/****************************************************************************
@@ -328,7 +332,18 @@ static void __init qnap_ts209_init(void)
platform_add_devices(qnap_ts209_devices,
ARRAY_SIZE(qnap_ts209_devices));
+
+ /* Get RTC IRQ and register the chip */
+ if (gpio_request(TS209_RTC_GPIO, "rtc") == 0) {
+ if (gpio_direction_input(TS209_RTC_GPIO) == 0)
+ qnap_ts209_i2c_rtc.irq = gpio_to_irq(TS209_RTC_GPIO);
+ else
+ gpio_free(TS209_RTC_GPIO);
+ }
+ if (qnap_ts209_i2c_rtc.irq == 0)
+ pr_warning("qnap_ts209_init: failed to get RTC IRQ\n");
i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1);
+
orion_eth_init(&qnap_ts209_eth_data);
orion_sata_init(&qnap_ts209_sata_data);
}
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index 83ef5ecaf43..df5ae2710ab 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -23,18 +23,27 @@ static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clocks_lock);
+static struct clk *clk_lookup(struct device *dev, const char *id)
+{
+ struct clk *p;
+
+ list_for_each_entry(p, &clocks, node)
+ if (strcmp(id, p->name) == 0 && p->dev == dev)
+ return p;
+
+ return NULL;
+}
+
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
mutex_lock(&clocks_mutex);
- list_for_each_entry(p, &clocks, node) {
- if (strcmp(id, p->name) == 0 &&
- (p->dev == NULL || p->dev == dev)) {
- clk = p;
- break;
- }
- }
+ p = clk_lookup(dev, id);
+ if (!p)
+ p = clk_lookup(NULL, id);
+ if (p)
+ clk = p;
mutex_unlock(&clocks_mutex);
return clk;
diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c
index cbc583beedc..4b21479332a 100644
--- a/arch/arm/mach-pxa/cpu-pxa.c
+++ b/arch/arm/mach-pxa/cpu-pxa.c
@@ -43,7 +43,7 @@
#ifdef DEBUG
static unsigned int freq_debug;
-MODULE_PARM(freq_debug, "i");
+module_param(freq_debug, uint, 0);
MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
#else
#define freq_debug 0
@@ -134,7 +134,7 @@ static int pxa_set_target(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *pxa_freqs_table;
pxa_freqs_t *pxa_freq_settings;
struct cpufreq_freqs freqs;
- int idx;
+ unsigned int idx;
unsigned long flags;
unsigned int unused, preset_mdrefr, postset_mdrefr;
void *ramstart = phys_to_virt(0xa0000000);
@@ -233,6 +233,11 @@ static int pxa_set_target(struct cpufreq_policy *policy,
return 0;
}
+static unsigned int pxa_cpufreq_get(unsigned int cpu)
+{
+ return get_clk_frequency_khz(0);
+}
+
static int pxa_cpufreq_init(struct cpufreq_policy *policy)
{
int i;
@@ -269,6 +274,7 @@ static struct cpufreq_driver pxa_cpufreq_driver = {
.verify = pxa_verify_policy,
.target = pxa_set_target,
.init = pxa_cpufreq_init,
+ .get = pxa_cpufreq_get,
.name = "PXA25x",
};
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 7cd9ef8deb0..35f25fdaeba 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -129,28 +129,20 @@ static void clk_pxa3xx_cken_enable(struct clk *clk)
{
unsigned long mask = 1ul << (clk->cken & 0x1f);
- local_irq_disable();
-
if (clk->cken < 32)
CKENA |= mask;
else
CKENB |= mask;
-
- local_irq_enable();
}
static void clk_pxa3xx_cken_disable(struct clk *clk)
{
unsigned long mask = 1ul << (clk->cken & 0x1f);
- local_irq_disable();
-
if (clk->cken < 32)
CKENA &= ~mask;
else
CKENB &= ~mask;
-
- local_irq_enable();
}
static const struct clkops clk_pxa3xx_cken_ops = {
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 7731d50dd86..afd2cbfca0d 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -58,7 +58,7 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
-#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES)
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
static void zylonite_backlight_power(int on)
{
gpio_set_value(gpio_backlight, on);
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 2728b0e7d2b..3f6dc40b835 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -120,6 +120,8 @@ full_search:
*/
int valid_phys_addr_range(unsigned long addr, size_t size)
{
+ if (addr < PHYS_OFFSET)
+ return 0;
if (addr + size > __pa(high_memory))
return 0;
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 500c9610ab3..e0f19ab9116 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -75,7 +75,7 @@ no_pgd:
void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd)
{
pmd_t *pmd;
- struct page *pte;
+ pgtable_t pte;
if (!pgd)
return;
@@ -90,10 +90,8 @@ void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd)
goto free;
}
- pte = pmd_page(*pmd);
+ pte = pmd_pgtable(*pmd);
pmd_clear(pmd);
- dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE);
- pte_lock_deinit(pte);
pte_free(mm, pte);
pmd_free(mm, pmd);
free:
diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c
index 5a77030e07a..e765a8652b3 100644
--- a/arch/avr32/boards/atstk1000/atstk1004.c
+++ b/arch/avr32/boards/atstk1000/atstk1004.c
@@ -129,7 +129,7 @@ static int __init atstk1004_init(void)
#ifdef CONFIG_BOARD_ATSTK100X_SPI1
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
#endif
-#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
at32_add_device_mci(0);
#endif
at32_add_device_lcdc(0, &atstk1000_lcdc_data,
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index eaaa69bbdc3..7f4af0b1e11 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -11,6 +11,7 @@
#include <linux/fs.h>
#include <linux/ptrace.h>
#include <linux/reboot.h>
+#include <linux/tick.h>
#include <linux/uaccess.h>
#include <linux/unistd.h>
@@ -30,8 +31,10 @@ void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
+ tick_nohz_stop_sched_tick();
while (!need_resched())
cpu_idle_sleep();
+ tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
schedule();
preempt_disable();
@@ -345,6 +348,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
p->thread.cpu_context.ksp = (unsigned long)childregs;
p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
+ clear_tsk_thread_flag(p, TIF_DEBUG);
if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG))
ocd_enable(p);
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index 6560cb18b4e..ce4e4296b95 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -189,6 +189,8 @@ no_context:
page = sysreg_read(PTBR);
printk(KERN_ALERT "ptbr = %08lx", page);
+ if (address >= TASK_SIZE)
+ page = (unsigned long)swapper_pg_dir;
if (page) {
page = ((unsigned long *)page)[address >> 22];
printk(" pgd = %08lx", page);
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index fe254f886a6..75eba2ca788 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -98,8 +98,11 @@ drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/
# them changed. We use .mach to indicate when they were updated
# last, otherwise make uses the target directory mtime.
+ show_mach_symlink = :
+ quiet_show_mach_symlink = echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach'
+silent_show_mach_symlink = :
include/asm-blackfin/.mach: $(wildcard include/config/arch/*.h) include/config/auto.conf
- @echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach'
+ @$($(quiet)show_mach_symlink)
ifneq ($(KBUILD_SRC),)
$(Q)mkdir -p include/asm-$(ARCH)
$(Q)ln -fsn $(srctree)/include/asm-$(ARCH)/mach-$(MACHINE) include/asm-$(ARCH)/mach
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
index d59ee1530bd..ae320dcfede 100644
--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -1,7 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22.14
-# Thu Nov 29 17:32:47 2007
+# Linux kernel version: 2.6.22.16
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -116,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
# Processor and Board Settings
#
# CONFIG_BF522 is not set
+# CONFIG_BF523 is not set
+# CONFIG_BF524 is not set
# CONFIG_BF525 is not set
+# CONFIG_BF526 is not set
CONFIG_BF527=y
# CONFIG_BF531 is not set
# CONFIG_BF532 is not set
@@ -306,6 +308,7 @@ CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_WB is not set
CONFIG_BFIN_WT=y
CONFIG_L1_MAX_PIECE=16
+# CONFIG_MPU is not set
#
# Asynchonous Memory Configuration
@@ -354,6 +357,7 @@ CONFIG_BINFMT_ZFLAT=y
# Power management options
#
# CONFIG_PM is not set
+# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# Networking
@@ -496,7 +500,6 @@ CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_INTELEXT is not set
# CONFIG_MTD_CFI_AMDSTD is not set
# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_MW320D=m
CONFIG_MTD_RAM=y
CONFIG_MTD_ROM=m
# CONFIG_MTD_ABSENT is not set
@@ -506,9 +509,6 @@ CONFIG_MTD_ROM=m
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_BF5xx=m
-CONFIG_BFIN_FLASH_SIZE=0x400000
-CONFIG_EBIU_FLASH_BASE=0x20000000
# CONFIG_MTD_UCLINUX is not set
# CONFIG_MTD_PLATRAM is not set
@@ -684,7 +684,6 @@ CONFIG_INPUT_MISC=y
# CONFIG_INPUT_POWERMATE is not set
# CONFIG_INPUT_YEALINK is not set
# CONFIG_INPUT_UINPUT is not set
-# CONFIG_BF53X_PFBUTTONS is not set
# CONFIG_TWI_KEYPAD is not set
#
@@ -702,12 +701,12 @@ CONFIG_INPUT_MISC=y
# CONFIG_BF5xx_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
# CONFIG_BF5xx_PPI 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_AD5304 is not set
-# CONFIG_BF5xx_TEA5764 is not set
-# CONFIG_BF5xx_FBDMA is not set
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
@@ -772,7 +771,6 @@ CONFIG_I2C_CHARDEV=m
#
# I2C Hardware Bus support
#
-# CONFIG_I2C_BLACKFIN_GPIO is not set
CONFIG_I2C_BLACKFIN_TWI=m
CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
# CONFIG_I2C_GPIO is not set
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index 811711f59a2..9621caa60b5 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -322,10 +322,9 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
-CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+CONFIG_PM_BFIN_SLEEP_DEEPER=y
+# CONFIG_PM_BFIN_SLEEP is not set
# CONFIG_PM_WAKEUP_BY_GPIO is not set
-# CONFIG_PM_WAKEUP_GPIO_API is not set
-CONFIG_PM_WAKEUP_SIC_IWR=0x80
#
# CPU Frequency scaling
@@ -697,7 +696,6 @@ CONFIG_SERIAL_BFIN_DMA=y
# CONFIG_SERIAL_BFIN_PIO is not set
CONFIG_SERIAL_BFIN_UART0=y
# CONFIG_BFIN_UART0_CTSRTS is not set
-# CONFIG_SERIAL_BFIN_UART1 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig
index 198f4123af4..b51e76ce7f4 100644
--- a/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -323,10 +323,9 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
-CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+CONFIG_PM_BFIN_SLEEP_DEEPER=y
+# CONFIG_PM_BFIN_SLEEP is not set
# CONFIG_PM_WAKEUP_BY_GPIO is not set
-# CONFIG_PM_WAKEUP_GPIO_API is not set
-CONFIG_PM_WAKEUP_SIC_IWR=0x80
#
# CPU Frequency scaling
@@ -714,7 +713,6 @@ CONFIG_SERIAL_BFIN_DMA=y
# CONFIG_SERIAL_BFIN_PIO is not set
CONFIG_SERIAL_BFIN_UART0=y
# CONFIG_BFIN_UART0_CTSRTS is not set
-# CONFIG_SERIAL_BFIN_UART1 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig
index b37ccc681e7..d45fa535dad 100644
--- a/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -330,10 +330,9 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
-CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+CONFIG_PM_BFIN_SLEEP_DEEPER=y
+# CONFIG_PM_BFIN_SLEEP is not set
# CONFIG_PM_WAKEUP_BY_GPIO is not set
-# CONFIG_PM_WAKEUP_GPIO_API is not set
-CONFIG_PM_WAKEUP_SIC_IWR=0x8
#
# CPU Frequency scaling
@@ -1013,6 +1012,7 @@ CONFIG_SND_BFIN_AD73311_SE=4
CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_SOC=m
CONFIG_SND_BF5XX_SOC=m
+CONFIG_SND_MMAP_SUPPORT=y
CONFIG_SND_BF5XX_SOC_AC97=m
# CONFIG_SND_BF5XX_SOC_WM8750 is not set
# CONFIG_SND_BF5XX_SOC_WM8731 is not set
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index fd702161ef5..c9707f7665a 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -396,6 +396,7 @@ CONFIG_BINFMT_ZFLAT=y
# Power management options
#
# CONFIG_PM is not set
+# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# CPU Frequency scaling
@@ -1075,6 +1076,7 @@ CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_SOC=y
CONFIG_SND_BF5XX_SOC=y
+CONFIG_SND_MMAP_SUPPORT=y
CONFIG_SND_BF5XX_SOC_AC97=y
CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y
# CONFIG_SND_BF5XX_SOC_WM8750 is not set
diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig
index 8546994939f..4d8a6333130 100644
--- a/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -367,6 +367,7 @@ CONFIG_BINFMT_ZFLAT=y
# Power management options
#
# CONFIG_PM is not set
+# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# Networking
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 5453bc3664f..8fd5d22cec3 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -105,13 +105,14 @@ int request_dma(unsigned int channel, char *device_id)
mutex_unlock(&(dma_ch[channel].dmalock));
#ifdef CONFIG_BF54x
- if (channel >= CH_UART2_RX && channel <= CH_UART3_TX &&
- strncmp(device_id, "BFIN_UART", 9) == 0)
- dma_ch[channel].regs->peripheral_map |=
- (channel - CH_UART2_RX + 0xC);
- else
- dma_ch[channel].regs->peripheral_map |=
- (channel - CH_UART2_RX + 0x6);
+ if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) {
+ if (strncmp(device_id, "BFIN_UART", 9) == 0)
+ dma_ch[channel].regs->peripheral_map |=
+ (channel - CH_UART2_RX + 0xC);
+ else
+ dma_ch[channel].regs->peripheral_map |=
+ (channel - CH_UART2_RX + 0x6);
+ }
#endif
dma_ch[channel].device_id = device_id;
diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S
index 90262691b11..5ed47228a39 100644
--- a/arch/blackfin/kernel/fixed_code.S
+++ b/arch/blackfin/kernel/fixed_code.S
@@ -101,9 +101,9 @@ ENDPROC (_atomic_ior32)
.align 16
/*
- * Atomic ior, 32 bit.
+ * Atomic and, 32 bit.
* Inputs: P0: memory address to use
- * R0: value to ior
+ * R0: value to and
* Outputs: R0: new contents of the memory address.
* R1: previous contents of the memory address.
*/
@@ -112,13 +112,13 @@ ENTRY(_atomic_and32)
R0 = R1 & R0;
[P0] = R0;
rts;
-ENDPROC (_atomic_ior32)
+ENDPROC (_atomic_and32)
.align 16
/*
- * Atomic ior, 32 bit.
+ * Atomic xor, 32 bit.
* Inputs: P0: memory address to use
- * R0: value to ior
+ * R0: value to xor
* Outputs: R0: new contents of the memory address.
* R1: previous contents of the memory address.
*/
@@ -127,7 +127,7 @@ ENTRY(_atomic_xor32)
R0 = R1 ^ R0;
[P0] = R0;
rts;
-ENDPROC (_atomic_ior32)
+ENDPROC (_atomic_xor32)
.align 16
/*
diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c
index 5cf4bdb1df3..1904d8b5332 100644
--- a/arch/blackfin/kernel/gptimers.c
+++ b/arch/blackfin/kernel/gptimers.c
@@ -1,9 +1,9 @@
/*
- * bfin_gptimers.c - derived from bf53x_timers.c
- * Driver for General Purpose Timer functions on the Blackfin processor
+ * gptimers.c - Blackfin General Purpose Timer core API
*
- * Copyright (C) 2005 John DeHority
- * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
+ * Copyright (c) 2005-2008 Analog Devices Inc.
+ * Copyright (C) 2005 John DeHority
+ * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
*
* Licensed under the GPLv2.
*/
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 8229b1090eb..2255c289a71 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -32,6 +32,7 @@
static DEFINE_PER_CPU(struct cpu, cpu_devices);
u16 _bfin_swrst;
+EXPORT_SYMBOL(_bfin_swrst);
unsigned long memory_start, memory_end, physical_mem_end;
unsigned long reserved_mem_dcache_on;
@@ -514,6 +515,7 @@ static __init void memory_setup(void)
printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20);
printk(KERN_INFO "Memory map:\n"
+ KERN_INFO " fixedcode = 0x%p-0x%p\n"
KERN_INFO " text = 0x%p-0x%p\n"
KERN_INFO " rodata = 0x%p-0x%p\n"
KERN_INFO " bss = 0x%p-0x%p\n"
@@ -527,7 +529,8 @@ static __init void memory_setup(void)
#if DMA_UNCACHED_REGION > 0
KERN_INFO " DMA Zone = 0x%p-0x%p\n"
#endif
- , _stext, _etext,
+ , (void *)FIXED_CODE_START, (void *)FIXED_CODE_END,
+ _stext, _etext,
__start_rodata, __end_rodata,
__bss_start, __bss_stop,
_sdata, _edata,
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index aed832540b3..cb01a9de268 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -147,44 +147,64 @@ SECTIONS
__l1_lma_start = .;
+#if L1_CODE_LENGTH
+# define LDS_L1_CODE *(.l1.text)
+#else
+# define LDS_L1_CODE
+#endif
.text_l1 L1_CODE_START : AT(LOADADDR(.init.ramfs) + SIZEOF(.init.ramfs))
{
. = ALIGN(4);
__stext_l1 = .;
- *(.l1.text)
-
+ LDS_L1_CODE
. = ALIGN(4);
__etext_l1 = .;
}
+#if L1_DATA_A_LENGTH
+# define LDS_L1_A_DATA *(.l1.data)
+# define LDS_L1_A_BSS *(.l1.bss)
+# define LDS_L1_A_CACHE *(.data_l1.cacheline_aligned)
+#else
+# define LDS_L1_A_DATA
+# define LDS_L1_A_BSS
+# define LDS_L1_A_CACHE
+#endif
.data_l1 L1_DATA_A_START : AT(LOADADDR(.text_l1) + SIZEOF(.text_l1))
{
. = ALIGN(4);
__sdata_l1 = .;
- *(.l1.data)
+ LDS_L1_A_DATA
__edata_l1 = .;
. = ALIGN(4);
__sbss_l1 = .;
- *(.l1.bss)
+ LDS_L1_A_BSS
. = ALIGN(32);
- *(.data_l1.cacheline_aligned)
+ LDS_L1_A_CACHE
. = ALIGN(4);
__ebss_l1 = .;
}
+#if L1_DATA_B_LENGTH
+# define LDS_L1_B_DATA *(.l1.data.B)
+# define LDS_L1_B_BSS *(.l1.bss.B)
+#else
+# define LDS_L1_B_DATA
+# define LDS_L1_B_BSS
+#endif
.data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1))
{
. = ALIGN(4);
__sdata_b_l1 = .;
- *(.l1.data.B)
+ LDS_L1_B_DATA
__edata_b_l1 = .;
. = ALIGN(4);
__sbss_b_l1 = .;
- *(.l1.bss.B)
+ LDS_L1_B_BSS
. = ALIGN(4);
__ebss_b_l1 = .;
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 337515fba61..cf4bc0d8335 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -180,8 +180,8 @@ static struct mtd_partition partition_info[] = {
},
{
.name = "File System",
- .offset = 4 * SIZE_1M,
- .size = (256 - 4) * SIZE_1M,
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
},
};
@@ -422,11 +422,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = 0x20000
+ .offset = MTDPART_OFS_APPEND,
}, {
.name = "file system",
- .size = 0x700000,
- .offset = 0x00100000,
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
}
};
@@ -484,13 +484,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
};
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
-static struct bfin5xx_spi_chip ad5304_chip_info = {
- .enable_dma = 0,
- .bits_per_word = 16,
-};
-#endif
-
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
.enable_dma = 0,
@@ -611,17 +604,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_MODE_3,
},
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
- {
- .modalias = "ad5304_spi",
- .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
- .chip_select = 2,
- .platform_data = NULL,
- .controller_data = &ad5304_chip_info,
- .mode = SPI_MODE_2,
- },
-#endif
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
{
.modalias = "ad7877",
@@ -818,6 +800,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
&bf5xx_nand_device,
@@ -895,6 +890,8 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
#endif
+
+ &bfin_gpios_device,
};
static int __init stamp_init(void)
@@ -921,13 +918,18 @@ void native_machine_restart(char *cmd)
bfin_gpio_reset_spi0_ssel1();
}
-/*
- * Currently the MAC address is saved in Flash by U-Boot
- */
-#define FLASH_MAC 0x203f0000
void bfin_get_ether_addr(char *addr)
{
- *(u32 *)(&(addr[0])) = bfin_read32(FLASH_MAC);
- *(u16 *)(&(addr[4])) = bfin_read16(FLASH_MAC + 4);
+ /* the MAC is stored in OTP memory page 0xDF */
+ u32 ret;
+ u64 otp_mac;
+ u32 (*otp_read)(u32 page, u32 flags, u64 *page_content) = (void *)0xEF00001A;
+
+ ret = otp_read(0xDF, 0x00, &otp_mac);
+ if (!(ret & 0x1)) {
+ char *otp_mac_p = (char *)&otp_mac;
+ for (ret = 0; ret < 6; ++ret)
+ addr[ret] = otp_mac_p[5 - ret];
+ }
}
EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index 2b09aa39f56..241b5a20a36 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -99,11 +99,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = 0x20000
+ .offset = MTDPART_OFS_APPEND,
}, {
.name = "file system",
- .size = 0x700000,
- .offset = 0x00100000,
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
}
};
@@ -298,6 +298,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
#include <linux/i2c-gpio.h>
@@ -350,6 +363,8 @@ static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
&i2c_gpio_device,
#endif
+
+ &bfin_gpios_device,
};
static int __init ezkit_init(void)
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index a645f6fd091..b2ac4816ae6 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -112,7 +112,7 @@ static struct platform_device net2272_bfin_device = {
static struct mtd_partition stamp_partitions[] = {
{
.name = "Bootloader",
- .size = 0x20000,
+ .size = 0x40000,
.offset = 0,
}, {
.name = "Kernel",
@@ -160,17 +160,17 @@ static struct platform_device stamp_flash_device = {
static struct mtd_partition bfin_spi_flash_partitions[] = {
{
.name = "bootloader",
- .size = 0x00020000,
+ .size = 0x00040000,
.offset = 0,
.mask_flags = MTD_CAP_ROM
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = 0x20000
+ .offset = MTDPART_OFS_APPEND,
}, {
.name = "file system",
- .size = 0x700000,
- .offset = 0x00100000,
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
}
};
@@ -212,13 +212,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
};
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
-static struct bfin5xx_spi_chip ad5304_chip_info = {
- .enable_dma = 0,
- .bits_per_word = 16,
-};
-#endif
-
#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
static struct bfin5xx_spi_chip spi_mmc_chip_info = {
.enable_dma = 1,
@@ -308,17 +301,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
- {
- .modalias = "ad5304_spi",
- .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
- .chip_select = 2,
- .platform_data = NULL,
- .controller_data = &ad5304_chip_info,
- .mode = SPI_MODE_2,
- },
-#endif
#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
{
.modalias = "spidev",
@@ -457,6 +439,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
#include <linux/i2c-gpio.h>
@@ -518,6 +513,8 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
&i2c_gpio_device,
#endif
+
+ &bfin_gpios_device,
&stamp_flash_device,
};
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
index 8a3397db1d2..c95395ba7bf 100644
--- a/arch/blackfin/mach-bf537/boards/generic_board.c
+++ b/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -371,13 +371,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
};
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
-static struct bfin5xx_spi_chip ad5304_chip_info = {
- .enable_dma = 0,
- .bits_per_word = 16,
-};
-#endif
-
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
.enable_dma = 0,
@@ -483,17 +476,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_MODE_3,
},
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
- {
- .modalias = "ad5304_spi",
- .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
- .chip_select = 2,
- .platform_data = NULL,
- .controller_data = &ad5304_chip_info,
- .mode = SPI_MODE_2,
- },
-#endif
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
{
.modalias = "ad7877",
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 9e2277e0d25..ea83148993d 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -128,6 +128,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
static struct resource bfin_pcmcia_cf_resources[] = {
{
@@ -343,7 +356,7 @@ static struct platform_device net2272_bfin_device = {
static struct mtd_partition stamp_partitions[] = {
{
.name = "Bootloader",
- .size = 0x20000,
+ .size = 0x40000,
.offset = 0,
}, {
.name = "Kernel",
@@ -351,7 +364,7 @@ static struct mtd_partition stamp_partitions[] = {
.offset = MTDPART_OFS_APPEND,
}, {
.name = "RootFS",
- .size = 0x400000 - 0x20000 - 0xE0000 - 0x10000,
+ .size = 0x400000 - 0x40000 - 0xE0000 - 0x10000,
.offset = MTDPART_OFS_APPEND,
}, {
.name = "MAC Address",
@@ -391,17 +404,17 @@ static struct platform_device stamp_flash_device = {
static struct mtd_partition bfin_spi_flash_partitions[] = {
{
.name = "bootloader",
- .size = 0x00020000,
+ .size = 0x00040000,
.offset = 0,
.mask_flags = MTD_CAP_ROM
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = 0x20000
+ .offset = MTDPART_OFS_APPEND,
}, {
.name = "file system",
- .size = 0x700000,
- .offset = 0x00100000,
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
}
};
@@ -459,13 +472,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
};
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
-static struct bfin5xx_spi_chip ad5304_chip_info = {
- .enable_dma = 0,
- .bits_per_word = 16,
-};
-#endif
-
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
.enable_dma = 0,
@@ -578,17 +584,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_MODE_3,
},
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
- {
- .modalias = "ad5304_spi",
- .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
- .chip_select = 2,
- .platform_data = NULL,
- .controller_data = &ad5304_chip_info,
- .mode = SPI_MODE_2,
- },
-#endif
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
{
.modalias = "ad7877",
@@ -821,6 +816,8 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
#endif
+
+ &bfin_gpios_device,
&stamp_flash_device,
};
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index 916e963e83b..40846aa034c 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -285,8 +285,8 @@ static struct mtd_partition partition_info[] = {
},
{
.name = "File System",
- .offset = 4 * SIZE_1M,
- .size = (256 - 4) * SIZE_1M,
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
},
};
@@ -323,7 +323,7 @@ static struct platform_device bf5xx_nand_device = {
};
#endif
-#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN)
+#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE)
static struct platform_device bf54x_sdh_device = {
.name = "bfin-sdh",
.id = 0,
@@ -333,7 +333,7 @@ static struct platform_device bf54x_sdh_device = {
static struct mtd_partition ezkit_partitions[] = {
{
.name = "Bootloader",
- .size = 0x20000,
+ .size = 0x40000,
.offset = 0,
}, {
.name = "Kernel",
@@ -381,8 +381,8 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
.mask_flags = MTD_CAP_ROM
}, {
.name = "linux kernel",
- .size = 0x1c0000,
- .offset = 0x40000
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
}
};
@@ -594,6 +594,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
&rtc_device,
@@ -623,7 +636,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
&bf5xx_nand_device,
#endif
-#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN)
+#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE)
&bf54x_sdh_device,
#endif
@@ -646,6 +659,8 @@ static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
#endif
+
+ &bfin_gpios_device,
&ezkit_flash_device,
};
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
index 374803a8d2e..f5479298bb7 100644
--- a/arch/blackfin/mach-bf548/dma.c
+++ b/arch/blackfin/mach-bf548/dma.c
@@ -27,6 +27,8 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <linux/module.h>
+
#include <asm/blackfin.h>
#include <asm/dma.h>
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S
index 74fe258421a..46222a75321 100644
--- a/arch/blackfin/mach-bf548/head.S
+++ b/arch/blackfin/mach-bf548/head.S
@@ -28,6 +28,7 @@
*/
#include <linux/linkage.h>
+#include <linux/init.h>
#include <asm/blackfin.h>
#include <asm/trace.h>
#if CONFIG_BFIN_KERNEL_CLOCK
@@ -44,10 +45,9 @@
#define INITIAL_STACK 0xFFB01000
-.text
+__INIT
ENTRY(__start)
-ENTRY(__stext)
/* R0: argument of command line string, passed from uboot, save it */
R7 = R0;
/* Enable Cycle Counter and Nesting Of Interrupts */
@@ -213,6 +213,7 @@ ENTRY(__stext)
.LWAIT_HERE:
jump .LWAIT_HERE;
+ENDPROC(__start)
ENTRY(_real_start)
[ -- sp ] = reti;
@@ -285,6 +286,9 @@ ENTRY(_real_start)
call _start_kernel;
.L_exit:
jump.s .L_exit;
+ENDPROC(_real_start)
+
+__FINIT
.section .l1.text
#if CONFIG_BFIN_KERNEL_CLOCK
@@ -450,6 +454,7 @@ ENTRY(_start_dma_code)
SSYNC;
RTS;
+ENDPROC(_start_dma_code)
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
.data
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 43c1b098281..d357f648d96 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -223,7 +223,7 @@ static struct platform_device bfin_uart_device = {
static struct mtd_partition ezkit_partitions[] = {
{
.name = "Bootloader",
- .size = 0x20000,
+ .size = 0x40000,
.offset = 0,
}, {
.name = "Kernel",
@@ -389,6 +389,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
#include <linux/i2c-gpio.h>
@@ -446,6 +459,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
&isp1362_hcd_device,
#endif
+ &bfin_gpios_device,
&ezkit_flash_device,
};
diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S
index b80ddd8b232..9d45aa3265b 100644
--- a/arch/blackfin/mach-common/dpmc.S
+++ b/arch/blackfin/mach-common/dpmc.S
@@ -31,140 +31,6 @@
#include <asm/blackfin.h>
#include <asm/mach/irq.h>
-.text
-
-ENTRY(_unmask_wdog_wakeup_evt)
- [--SP] = ( R7:0, P5:0 );
-#if defined(CONFIG_BF561)
- P0.H = hi(SICA_IWR1);
- P0.L = lo(SICA_IWR1);
-#elif defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
- P0.h = HI(SIC_IWR0);
- P0.l = LO(SIC_IWR0);
-#else
- P0.h = HI(SIC_IWR);
- P0.l = LO(SIC_IWR);
-#endif
- R7 = [P0];
-#if defined(CONFIG_BF561)
- BITSET(R7, 27);
-#else
- BITSET(R7,(IRQ_WATCH - IVG7));
-#endif
- [P0] = R7;
- SSYNC;
-
- ( R7:0, P5:0 ) = [SP++];
- RTS;
-
-.LWRITE_TO_STAT:
- /* When watch dog timer is enabled, a write to STAT will load the
- * contents of CNT to STAT
- */
- R7 = 0x0000(z);
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_STAT);
- P0.l = LO(WDOGA_STAT);
-#else
- P0.h = HI(WDOG_STAT);
- P0.l = LO(WDOG_STAT);
-#endif
- [P0] = R7;
- SSYNC;
- JUMP .LSKIP_WRITE_TO_STAT;
-
-ENTRY(_program_wdog_timer)
- [--SP] = ( R7:0, P5:0 );
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_CNT);
- P0.l = LO(WDOGA_CNT);
-#else
- P0.h = HI(WDOG_CNT);
- P0.l = LO(WDOG_CNT);
-#endif
- [P0] = R0;
- SSYNC;
-
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_CTL);
- P0.l = LO(WDOGA_CTL);
-#else
- P0.h = HI(WDOG_CTL);
- P0.l = LO(WDOG_CTL);
-#endif
- R7 = W[P0](Z);
- CC = BITTST(R7,1);
- if !CC JUMP .LWRITE_TO_STAT;
- CC = BITTST(R7,2);
- if !CC JUMP .LWRITE_TO_STAT;
-
-.LSKIP_WRITE_TO_STAT:
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_CTL);
- P0.l = LO(WDOGA_CTL);
-#else
- P0.h = HI(WDOG_CTL);
- P0.l = LO(WDOG_CTL);
-#endif
- R7 = W[P0](Z);
- BITCLR(R7,1); /* Enable GP event */
- BITSET(R7,2);
- W[P0] = R7.L;
- SSYNC;
- NOP;
-
- R7 = W[P0](Z);
- BITCLR(R7,4); /* Enable the wdog counter */
- W[P0] = R7.L;
- SSYNC;
-
- ( R7:0, P5:0 ) = [SP++];
- RTS;
-
-ENTRY(_clear_wdog_wakeup_evt)
- [--SP] = ( R7:0, P5:0 );
-
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_CTL);
- P0.l = LO(WDOGA_CTL);
-#else
- P0.h = HI(WDOG_CTL);
- P0.l = LO(WDOG_CTL);
-#endif
- R7 = 0x0AD6(Z);
- W[P0] = R7.L;
- SSYNC;
-
- R7 = W[P0](Z);
- BITSET(R7,15);
- W[P0] = R7.L;
- SSYNC;
-
- R7 = W[P0](Z);
- BITSET(R7,1);
- BITSET(R7,2);
- W[P0] = R7.L;
- SSYNC;
-
- ( R7:0, P5:0 ) = [SP++];
- RTS;
-
-ENTRY(_disable_wdog_timer)
- [--SP] = ( R7:0, P5:0 );
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_CTL);
- P0.l = LO(WDOGA_CTL);
-#else
- P0.h = HI(WDOG_CTL);
- P0.l = LO(WDOG_CTL);
-#endif
- R7 = 0xAD6(Z);
- W[P0] = R7.L;
- SSYNC;
- ( R7:0, P5:0 ) = [SP++];
- RTS;
-
-#if !defined(CONFIG_BF561)
.section .l1.text
@@ -459,10 +325,12 @@ ENTRY(_set_sic_iwr)
RTS;
ENTRY(_set_rtc_istat)
+#ifndef CONFIG_BF561
P0.H = hi(RTC_ISTAT);
P0.L = lo(RTC_ISTAT);
w[P0] = R0.L;
SSYNC;
+#endif
RTS;
ENTRY(_test_pll_locked)
@@ -473,4 +341,3 @@ ENTRY(_test_pll_locked)
CC = BITTST(R0,5);
IF !CC JUMP 1b;
RTS;
-#endif
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 2cbb7a0bc38..cee54cebbc6 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -1369,7 +1369,7 @@ ENTRY(_sys_call_table)
.long _sys_epoll_pwait
.long _sys_utimensat
.long _sys_signalfd
- .long _sys_ni_syscall
+ .long _sys_timerfd_create
.long _sys_eventfd /* 350 */
.long _sys_pread64
.long _sys_pwrite64
@@ -1378,6 +1378,9 @@ ENTRY(_sys_call_table)
.long _sys_get_robust_list /* 355 */
.long _sys_fallocate
.long _sys_semtimedop
+ .long _sys_timerfd_settime
+ .long _sys_timerfd_gettime
+
.rept NR_syscalls-(.-_sys_call_table)/4
.long _sys_ni_syscall
.endr
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 880595afe98..225ef14af75 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -74,7 +74,7 @@ unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */
#endif
struct ivgx {
- /* irq number for request_irq, available in mach-bf533/irq.h */
+ /* irq number for request_irq, available in mach-bf5xx/irq.h */
unsigned int irqno;
/* corresponding bit in the SIC_ISR register */
unsigned int isrflag;
@@ -86,7 +86,6 @@ struct ivg_slice {
struct ivgx *istop;
} ivg7_13[IVG13 - IVG7 + 1];
-static void search_IAR(void);
/*
* Search SIC_IAR and fill tables with the irqvalues
@@ -120,10 +119,10 @@ static void __init search_IAR(void)
}
/*
- * This is for BF533 internal IRQs
+ * This is for core internal IRQs
*/
-static void ack_noop(unsigned int irq)
+static void bfin_ack_noop(unsigned int irq)
{
/* Dummy function. */
}
@@ -156,11 +155,11 @@ static void bfin_internal_mask_irq(unsigned int irq)
{
#ifdef CONFIG_BF53x
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
- ~(1 << (irq - (IRQ_CORETMR + 1))));
+ ~(1 << SIC_SYSIRQ(irq)));
#else
unsigned mask_bank, mask_bit;
- mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
- mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
+ mask_bank = SIC_SYSIRQ(irq) / 32;
+ mask_bit = SIC_SYSIRQ(irq) % 32;
bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
~(1 << mask_bit));
#endif
@@ -171,11 +170,11 @@ static void bfin_internal_unmask_irq(unsigned int irq)
{
#ifdef CONFIG_BF53x
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
- (1 << (irq - (IRQ_CORETMR + 1))));
+ (1 << SIC_SYSIRQ(irq)));
#else
unsigned mask_bank, mask_bit;
- mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
- mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
+ mask_bank = SIC_SYSIRQ(irq) / 32;
+ mask_bit = SIC_SYSIRQ(irq) % 32;
bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) |
(1 << mask_bit));
#endif
@@ -187,8 +186,8 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
{
unsigned bank, bit;
unsigned long flags;
- bank = (irq - (IRQ_CORETMR + 1)) / 32;
- bit = (irq - (IRQ_CORETMR + 1)) % 32;
+ bank = SIC_SYSIRQ(irq) / 32;
+ bit = SIC_SYSIRQ(irq) % 32;
local_irq_save(flags);
@@ -204,15 +203,18 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
#endif
static struct irq_chip bfin_core_irqchip = {
- .ack = ack_noop,
+ .ack = bfin_ack_noop,
.mask = bfin_core_mask_irq,
.unmask = bfin_core_unmask_irq,
};
static struct irq_chip bfin_internal_irqchip = {
- .ack = ack_noop,
+ .ack = bfin_ack_noop,
.mask = bfin_internal_mask_irq,
.unmask = bfin_internal_unmask_irq,
+ .mask_ack = bfin_internal_mask_irq,
+ .disable = bfin_internal_mask_irq,
+ .enable = bfin_internal_unmask_irq,
#ifdef CONFIG_PM
.set_wake = bfin_internal_set_wake,
#endif
@@ -221,38 +223,23 @@ static struct irq_chip bfin_internal_irqchip = {
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
static int error_int_mask;
-static void bfin_generic_error_ack_irq(unsigned int irq)
-{
-
-}
-
static void bfin_generic_error_mask_irq(unsigned int irq)
{
error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
- if (!error_int_mask) {
- local_irq_disable();
- bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
- ~(1 << (IRQ_GENERIC_ERROR -
- (IRQ_CORETMR + 1))));
- SSYNC();
- local_irq_enable();
- }
+ if (!error_int_mask)
+ bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
}
static void bfin_generic_error_unmask_irq(unsigned int irq)
{
- local_irq_disable();
- bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 <<
- (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1)));
- SSYNC();
- local_irq_enable();
-
+ bfin_internal_unmask_irq(IRQ_GENERIC_ERROR);
error_int_mask |= 1L << (irq - IRQ_PPI_ERROR);
}
static struct irq_chip bfin_generic_error_irqchip = {
- .ack = bfin_generic_error_ack_irq,
+ .ack = bfin_ack_noop,
+ .mask_ack = bfin_generic_error_mask_irq,
.mask = bfin_generic_error_mask_irq,
.unmask = bfin_generic_error_unmask_irq,
};
@@ -608,7 +595,7 @@ static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = {
(struct pin_int_t *)PINT3_MASK_SET,
};
-unsigned short get_irq_base(u8 bank, u8 bmap)
+inline unsigned short get_irq_base(u8 bank, u8 bmap)
{
u16 irq_base;
@@ -969,17 +956,12 @@ int __init init_arch_irq(void)
#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
bfin_write_SIC_IMASK1(SIC_UNMASK_ALL);
- bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
- bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
# ifdef CONFIG_BF54x
bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
- bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
# endif
#else
bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
#endif
- SSYNC();
local_irq_disable();
@@ -1001,90 +983,53 @@ int __init init_arch_irq(void)
set_irq_chip(irq, &bfin_core_irqchip);
else
set_irq_chip(irq, &bfin_internal_irqchip);
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
- if (irq != IRQ_GENERIC_ERROR) {
-#endif
- switch (irq) {
+ switch (irq) {
#if defined(CONFIG_BF53x)
- case IRQ_PROG_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ case IRQ_PROG_INTA:
# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
- case IRQ_MAC_RX:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ case IRQ_MAC_RX:
# endif
#elif defined(CONFIG_BF54x)
- case IRQ_PINT0:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PINT1:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PINT2:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PINT3:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ case IRQ_PINT0:
+ case IRQ_PINT1:
+ case IRQ_PINT2:
+ case IRQ_PINT3:
#elif defined(CONFIG_BF52x)
- case IRQ_PORTF_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PORTG_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PORTH_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ case IRQ_PORTF_INTA:
+ case IRQ_PORTG_INTA:
+ case IRQ_PORTH_INTA:
#elif defined(CONFIG_BF561)
- case IRQ_PROG0_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PROG1_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PROG2_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ case IRQ_PROG0_INTA:
+ case IRQ_PROG1_INTA:
+ case IRQ_PROG2_INTA:
#endif
- default:
- set_irq_handler(irq, handle_simple_irq);
- break;
- }
-
+ set_irq_chained_handler(irq,
+ bfin_demux_gpio_irq);
+ break;
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
- } else {
+ case IRQ_GENERIC_ERROR:
set_irq_handler(irq, bfin_demux_error_irq);
- }
+
+ break;
#endif
+ default:
+ set_irq_handler(irq, handle_simple_irq);
+ break;
+ }
}
+
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
- for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) {
- set_irq_chip(irq, &bfin_generic_error_irqchip);
- set_irq_handler(irq, handle_level_irq);
- }
+ for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
+ set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip,
+ handle_level_irq);
#endif
- for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) {
+ /* if configured as edge, then will be changed to do_edge_IRQ */
+ for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++)
+ set_irq_chip_and_handler(irq, &bfin_gpio_irqchip,
+ handle_level_irq);
- set_irq_chip(irq, &bfin_gpio_irqchip);
- /* if configured as edge, then will be changed to do_edge_IRQ */
- set_irq_handler(irq, handle_level_irq);
- }
bfin_write_IMASK(0);
CSYNC();
@@ -1106,6 +1051,16 @@ int __init init_arch_irq(void)
IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
+ bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
+ bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
+# ifdef CONFIG_BF54x
+ bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+# endif
+#else
+ bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+#endif
+
return 0;
}
@@ -1122,7 +1077,6 @@ void do_irq(int vec, struct pt_regs *fp)
#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
unsigned long sic_status[3];
- SSYNC();
sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
#ifdef CONFIG_BF54x
@@ -1138,7 +1092,7 @@ void do_irq(int vec, struct pt_regs *fp)
}
#else
unsigned long sic_status;
- SSYNC();
+
sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
for (;; ivg++) {
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
index 1f516c55bde..ec3141fefd2 100644
--- a/arch/blackfin/mm/init.c
+++ b/arch/blackfin/mm/init.c
@@ -181,7 +181,7 @@ void __init mem_init(void)
}
}
-static __init void free_init_pages(const char *what, unsigned long begin, unsigned long end)
+static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end)
{
unsigned long addr;
/* next to check that the page we free is not a partial page */
@@ -203,7 +203,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
}
#endif
-void __init free_initmem(void)
+void __init_refok free_initmem(void)
{
#if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU
free_init_pages("unused kernel memory",
diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c
index 9310a7b476e..525483f0ddf 100644
--- a/arch/cris/arch-v10/kernel/time.c
+++ b/arch/cris/arch-v10/kernel/time.c
@@ -13,7 +13,7 @@
#include <linux/swap.h>
#include <linux/sched.h>
#include <linux/init.h>
-#include <linux/vmstat.h>
+#include <linux/mm.h>
#include <asm/arch/svinto.h>
#include <asm/types.h>
#include <asm/signal.h>
diff --git a/arch/cris/arch-v10/lib/string.c b/arch/cris/arch-v10/lib/string.c
index 7161a2bef4f..c7bd6ebdc93 100644
--- a/arch/cris/arch-v10/lib/string.c
+++ b/arch/cris/arch-v10/lib/string.c
@@ -1,55 +1,59 @@
-/*#************************************************************************#*/
-/*#-------------------------------------------------------------------------*/
-/*# */
-/*# FUNCTION NAME: memcpy() */
-/*# */
-/*# PARAMETERS: void* dst; Destination address. */
-/*# void* src; Source address. */
-/*# int len; Number of bytes to copy. */
-/*# */
-/*# RETURNS: dst. */
-/*# */
-/*# DESCRIPTION: Copies len bytes of memory from src to dst. No guarantees */
-/*# about copying of overlapping memory areas. This routine is */
-/*# very sensitive to compiler changes in register allocation. */
-/*# Should really be rewritten to avoid this problem. */
-/*# */
-/*#-------------------------------------------------------------------------*/
-/*# */
-/*# HISTORY */
-/*# */
-/*# DATE NAME CHANGES */
-/*# ---- ---- ------- */
-/*# 941007 Kenny R Creation */
-/*# 941011 Kenny R Lots of optimizations and inlining. */
-/*# 941129 Ulf A Adapted for use in libc. */
-/*# 950216 HP N==0 forgotten if non-aligned src/dst. */
-/*# Added some optimizations. */
-/*# 001025 HP Make src and dst char *. Align dst to */
-/*# dword, not just word-if-both-src-and-dst- */
-/*# are-misaligned. */
-/*# */
-/*#-------------------------------------------------------------------------*/
-
-#include <linux/types.h>
-
-void *memcpy(void *pdst,
- const void *psrc,
- size_t pn)
+/* A memcpy for CRIS.
+ Copyright (C) 1994-2005 Axis Communications.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Neither the name of Axis Communications nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS
+ COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* FIXME: This file should really only be used for reference, as the
+ result is somewhat depending on gcc generating what we expect rather
+ than what we describe. An assembly file should be used instead. */
+
+#include <stddef.h>
+
+/* Break even between movem and move16 is really at 38.7 * 2, but
+ modulo 44, so up to the next multiple of 44, we use ordinary code. */
+#define MEMCPY_BY_BLOCK_THRESHOLD (44 * 2)
+
+/* No name ambiguities in this file. */
+__asm__ (".syntax no_register_prefix");
+
+void *
+memcpy(void *pdst, const void *psrc, size_t pn)
{
- /* Ok. Now we want the parameters put in special registers.
+ /* Now we want the parameters put in special registers.
Make sure the compiler is able to make something useful of this.
- As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+ As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
- If gcc was alright, it really would need no temporaries, and no
- stack space to save stuff on. */
+ If gcc was allright, it really would need no temporaries, and no
+ stack space to save stuff on. */
register void *return_dst __asm__ ("r10") = pdst;
- register char *dst __asm__ ("r13") = pdst;
- register const char *src __asm__ ("r11") = psrc;
+ register unsigned char *dst __asm__ ("r13") = pdst;
+ register unsigned const char *src __asm__ ("r11") = psrc;
register int n __asm__ ("r12") = pn;
-
-
+
/* When src is aligned but not dst, this makes a few extra needless
cycles. I believe it would take as many to check that the
re-alignment was unnecessary. */
@@ -59,167 +63,174 @@ void *memcpy(void *pdst,
&& n >= 3)
{
if ((unsigned long) dst & 1)
- {
- n--;
- *(char*)dst = *(char*)src;
- src++;
- dst++;
- }
+ {
+ n--;
+ *dst = *src;
+ src++;
+ dst++;
+ }
if ((unsigned long) dst & 2)
- {
- n -= 2;
- *(short*)dst = *(short*)src;
- src += 2;
- dst += 2;
- }
+ {
+ n -= 2;
+ *(short *) dst = *(short *) src;
+ src += 2;
+ dst += 2;
+ }
}
- /* Decide which copying method to use. */
- if (n >= 44*2) /* Break even between movem and
- move16 is at 38.7*2, but modulo 44. */
- {
- /* For large copies we use 'movem' */
-
- /* It is not optimal to tell the compiler about clobbering any
- registers; that will move the saving/restoring of those registers
- to the function prologue/epilogue, and make non-movem sizes
- suboptimal.
-
- This method is not foolproof; it assumes that the "asm reg"
- declarations at the beginning of the function really are used
- here (beware: they may be moved to temporary registers).
- This way, we do not have to save/move the registers around into
- temporaries; we can safely use them straight away.
-
- If you want to check that the allocation was right; then
- check the equalities in the first comment. It should say
- "r13=r13, r11=r11, r12=r12" */
- __asm__ volatile ("\n\
- ;; Check that the following is true (same register names on \n\
- ;; both sides of equal sign, as in r8=r8): \n\
- ;; %0=r13, %1=r11, %2=r12 \n\
- ;; \n\
- ;; Save the registers we'll use in the movem process \n\
- ;; on the stack. \n\
- subq 11*4,$sp \n\
- movem $r10,[$sp] \n\
+ /* Decide which copying method to use. */
+ if (n >= MEMCPY_BY_BLOCK_THRESHOLD)
+ {
+ /* It is not optimal to tell the compiler about clobbering any
+ registers; that will move the saving/restoring of those registers
+ to the function prologue/epilogue, and make non-movem sizes
+ suboptimal. */
+ __asm__ volatile
+ ("\
+ ;; GCC does promise correct register allocations, but let's \n\
+ ;; make sure it keeps its promises. \n\
+ .ifnc %0-%1-%2,$r13-$r11-$r12 \n\
+ .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\" \n\
+ .endif \n\
+ \n\
+ ;; Save the registers we'll use in the movem process \n\
+ ;; on the stack. \n\
+ subq 11*4,sp \n\
+ movem r10,[sp] \n\
\n\
- ;; Now we've got this: \n\
- ;; r11 - src \n\
- ;; r13 - dst \n\
- ;; r12 - n \n\
+ ;; Now we've got this: \n\
+ ;; r11 - src \n\
+ ;; r13 - dst \n\
+ ;; r12 - n \n\
\n\
- ;; Update n for the first loop \n\
- subq 44,$r12 \n\
+ ;; Update n for the first loop. \n\
+ subq 44,r12 \n\
0: \n\
- movem [$r11+],$r10 \n\
- subq 44,$r12 \n\
- bge 0b \n\
- movem $r10,[$r13+] \n\
+"
+#ifdef __arch_common_v10_v32
+ /* Cater to branch offset difference between v32 and v10. We
+ assume the branch below has an 8-bit offset. */
+" setf\n"
+#endif
+" movem [r11+],r10 \n\
+ subq 44,r12 \n\
+ bge 0b \n\
+ movem r10,[r13+] \n\
\n\
- addq 44,$r12 ;; compensate for last loop underflowing n \n\
+ ;; Compensate for last loop underflowing n. \n\
+ addq 44,r12 \n\
\n\
- ;; Restore registers from stack \n\
- movem [$sp+],$r10"
+ ;; Restore registers from stack. \n\
+ movem [sp+],r10"
- /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
- /* Inputs */ : "0" (dst), "1" (src), "2" (n));
-
- }
+ /* Outputs. */
+ : "=r" (dst), "=r" (src), "=r" (n)
- /* Either we directly starts copying, using dword copying
- in a loop, or we copy as much as possible with 'movem'
- and then the last block (<44 bytes) is copied here.
- This will work since 'movem' will have updated src,dst,n. */
+ /* Inputs. */
+ : "0" (dst), "1" (src), "2" (n));
+ }
- while ( n >= 16 )
- {
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- n -= 16;
- }
+ while (n >= 16)
+ {
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+
+ n -= 16;
+ }
- /* A switch() is definitely the fastest although it takes a LOT of code.
- * Particularly if you inline code this.
- */
switch (n)
- {
+ {
case 0:
break;
+
case 1:
- *(char*)dst = *(char*)src;
+ *dst = *src;
break;
+
case 2:
- *(short*)dst = *(short*)src;
+ *(short *) dst = *(short *) src;
break;
+
case 3:
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 4:
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src;
break;
+
case 5:
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 6:
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 7:
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 8:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src;
break;
+
case 9:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 10:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 11:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 12:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src;
break;
+
case 13:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 14:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 15:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
- }
+ }
- return return_dst; /* destination pointer. */
-} /* memcpy() */
+ return return_dst;
+}
diff --git a/arch/cris/arch-v10/lib/usercopy.c b/arch/cris/arch-v10/lib/usercopy.c
index b8e6c0430e5..b0a608da7bd 100644
--- a/arch/cris/arch-v10/lib/usercopy.c
+++ b/arch/cris/arch-v10/lib/usercopy.c
@@ -193,7 +193,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
inaccessible. */
unsigned long
-__copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn)
+__copy_user_zeroing(void *pdst, const void __user *psrc, unsigned long pn)
{
/* We want the parameters put in special registers.
Make sure the compiler is able to make something useful of this.
diff --git a/arch/cris/arch-v32/lib/string.c b/arch/cris/arch-v32/lib/string.c
index 6740b2cebae..c7bd6ebdc93 100644
--- a/arch/cris/arch-v32/lib/string.c
+++ b/arch/cris/arch-v32/lib/string.c
@@ -1,55 +1,59 @@
-/*#************************************************************************#*/
-/*#-------------------------------------------------------------------------*/
-/*# */
-/*# FUNCTION NAME: memcpy() */
-/*# */
-/*# PARAMETERS: void* dst; Destination address. */
-/*# void* src; Source address. */
-/*# int len; Number of bytes to copy. */
-/*# */
-/*# RETURNS: dst. */
-/*# */
-/*# DESCRIPTION: Copies len bytes of memory from src to dst. No guarantees */
-/*# about copying of overlapping memory areas. This routine is */
-/*# very sensitive to compiler changes in register allocation. */
-/*# Should really be rewritten to avoid this problem. */
-/*# */
-/*#-------------------------------------------------------------------------*/
-/*# */
-/*# HISTORY */
-/*# */
-/*# DATE NAME CHANGES */
-/*# ---- ---- ------- */
-/*# 941007 Kenny R Creation */
-/*# 941011 Kenny R Lots of optimizations and inlining. */
-/*# 941129 Ulf A Adapted for use in libc. */
-/*# 950216 HP N==0 forgotten if non-aligned src/dst. */
-/*# Added some optimizations. */
-/*# 001025 HP Make src and dst char *. Align dst to */
-/*# dword, not just word-if-both-src-and-dst- */
-/*# are-misaligned. */
-/*# */
-/*#-------------------------------------------------------------------------*/
-
-#include <linux/types.h>
-
-void *memcpy(void *pdst,
- const void *psrc,
- size_t pn)
+/* A memcpy for CRIS.
+ Copyright (C) 1994-2005 Axis Communications.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Neither the name of Axis Communications nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS
+ COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* FIXME: This file should really only be used for reference, as the
+ result is somewhat depending on gcc generating what we expect rather
+ than what we describe. An assembly file should be used instead. */
+
+#include <stddef.h>
+
+/* Break even between movem and move16 is really at 38.7 * 2, but
+ modulo 44, so up to the next multiple of 44, we use ordinary code. */
+#define MEMCPY_BY_BLOCK_THRESHOLD (44 * 2)
+
+/* No name ambiguities in this file. */
+__asm__ (".syntax no_register_prefix");
+
+void *
+memcpy(void *pdst, const void *psrc, size_t pn)
{
- /* Ok. Now we want the parameters put in special registers.
+ /* Now we want the parameters put in special registers.
Make sure the compiler is able to make something useful of this.
- As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+ As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
- If gcc was alright, it really would need no temporaries, and no
- stack space to save stuff on. */
+ If gcc was allright, it really would need no temporaries, and no
+ stack space to save stuff on. */
register void *return_dst __asm__ ("r10") = pdst;
- register char *dst __asm__ ("r13") = pdst;
- register const char *src __asm__ ("r11") = psrc;
+ register unsigned char *dst __asm__ ("r13") = pdst;
+ register unsigned const char *src __asm__ ("r11") = psrc;
register int n __asm__ ("r12") = pn;
-
/* When src is aligned but not dst, this makes a few extra needless
cycles. I believe it would take as many to check that the
re-alignment was unnecessary. */
@@ -59,161 +63,174 @@ void *memcpy(void *pdst,
&& n >= 3)
{
if ((unsigned long) dst & 1)
- {
- n--;
- *(char*)dst = *(char*)src;
- src++;
- dst++;
- }
+ {
+ n--;
+ *dst = *src;
+ src++;
+ dst++;
+ }
if ((unsigned long) dst & 2)
- {
- n -= 2;
- *(short*)dst = *(short*)src;
- src += 2;
- dst += 2;
- }
+ {
+ n -= 2;
+ *(short *) dst = *(short *) src;
+ src += 2;
+ dst += 2;
+ }
}
- /* Decide which copying method to use. Movem is dirt cheap, so the
- overheap is low enough to always use the minimum block size as the
- threshold. */
- if (n >= 44)
- {
- /* For large copies we use 'movem' */
-
- /* It is not optimal to tell the compiler about clobbering any
- registers; that will move the saving/restoring of those registers
- to the function prologue/epilogue, and make non-movem sizes
- suboptimal. */
- __asm__ volatile (" \n\
- ;; Check that the register asm declaration got right. \n\
- ;; The GCC manual explicitly says TRT will happen. \n\
- .ifnc %0-%1-%2,$r13-$r11-$r12 \n\
- .err \n\
- .endif \n\
- \n\
- ;; Save the registers we'll use in the movem process \n\
+ /* Decide which copying method to use. */
+ if (n >= MEMCPY_BY_BLOCK_THRESHOLD)
+ {
+ /* It is not optimal to tell the compiler about clobbering any
+ registers; that will move the saving/restoring of those registers
+ to the function prologue/epilogue, and make non-movem sizes
+ suboptimal. */
+ __asm__ volatile
+ ("\
+ ;; GCC does promise correct register allocations, but let's \n\
+ ;; make sure it keeps its promises. \n\
+ .ifnc %0-%1-%2,$r13-$r11-$r12 \n\
+ .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\" \n\
+ .endif \n\
\n\
- ;; on the stack. \n\
- subq 11*4,$sp \n\
- movem $r10,[$sp] \n\
+ ;; Save the registers we'll use in the movem process \n\
+ ;; on the stack. \n\
+ subq 11*4,sp \n\
+ movem r10,[sp] \n\
\n\
- ;; Now we've got this: \n\
- ;; r11 - src \n\
- ;; r13 - dst \n\
- ;; r12 - n \n\
+ ;; Now we've got this: \n\
+ ;; r11 - src \n\
+ ;; r13 - dst \n\
+ ;; r12 - n \n\
\n\
- ;; Update n for the first loop \n\
- subq 44,$r12 \n\
+ ;; Update n for the first loop. \n\
+ subq 44,r12 \n\
0: \n\
- movem [$r11+],$r10 \n\
- subq 44,$r12 \n\
- bge 0b \n\
- movem $r10,[$r13+] \n\
+"
+#ifdef __arch_common_v10_v32
+ /* Cater to branch offset difference between v32 and v10. We
+ assume the branch below has an 8-bit offset. */
+" setf\n"
+#endif
+" movem [r11+],r10 \n\
+ subq 44,r12 \n\
+ bge 0b \n\
+ movem r10,[r13+] \n\
\n\
- addq 44,$r12 ;; compensate for last loop underflowing n \n\
+ ;; Compensate for last loop underflowing n. \n\
+ addq 44,r12 \n\
\n\
- ;; Restore registers from stack \n\
- movem [$sp+],$r10"
+ ;; Restore registers from stack. \n\
+ movem [sp+],r10"
- /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
- /* Inputs */ : "0" (dst), "1" (src), "2" (n));
+ /* Outputs. */
+ : "=r" (dst), "=r" (src), "=r" (n)
- }
+ /* Inputs. */
+ : "0" (dst), "1" (src), "2" (n));
+ }
- /* Either we directly starts copying, using dword copying
- in a loop, or we copy as much as possible with 'movem'
- and then the last block (<44 bytes) is copied here.
- This will work since 'movem' will have updated src,dst,n. */
+ while (n >= 16)
+ {
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
- while ( n >= 16 )
- {
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- n -= 16;
- }
+ n -= 16;
+ }
- /* A switch() is definitely the fastest although it takes a LOT of code.
- * Particularly if you inline code this.
- */
switch (n)
- {
+ {
case 0:
break;
+
case 1:
- *(char*)dst = *(char*)src;
+ *dst = *src;
break;
+
case 2:
- *(short*)dst = *(short*)src;
+ *(short *) dst = *(short *) src;
break;
+
case 3:
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 4:
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src;
break;
+
case 5:
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 6:
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 7:
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 8:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src;
break;
+
case 9:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 10:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 11:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 12:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src;
break;
+
case 13:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 14:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 15:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
- }
+ }
- return return_dst; /* destination pointer. */
-} /* memcpy() */
+ return return_dst;
+}
diff --git a/arch/cris/arch-v32/lib/usercopy.c b/arch/cris/arch-v32/lib/usercopy.c
index 04d0cf35a27..0b5b70d5f58 100644
--- a/arch/cris/arch-v32/lib/usercopy.c
+++ b/arch/cris/arch-v32/lib/usercopy.c
@@ -161,7 +161,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
inaccessible. */
unsigned long
-__copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn)
+__copy_user_zeroing(void *pdst, const void __user *psrc, unsigned long pn)
{
/* We want the parameters put in special registers.
Make sure the compiler is able to make something useful of this.
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index ca6a345b87e..f36d7f4a7c2 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -1494,9 +1494,11 @@ sys_call_table:
.long sys_epoll_pwait
.long sys_utimensat /* 320 */
.long sys_signalfd
- .long sys_ni_syscall
+ .long sys_timerfd_create
.long sys_eventfd
.long sys_fallocate
+ .long sys_timerfd_settime /* 325 */
+ .long sys_timerfd_gettime
syscall_table_size = (. - sys_call_table)
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index 17725a55aed..b95c4eace62 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -76,9 +76,6 @@ SECTIONS
*(.data.init_task)
}
- . = ALIGN(4096);
- .data.page_aligned : { *(.data.idt) }
-
. = ALIGN(L1_CACHE_BYTES);
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
diff --git a/arch/h8300/defconfig b/arch/h8300/defconfig
index 8f1ec329715..8901cdb5e75 100644
--- a/arch/h8300/defconfig
+++ b/arch/h8300/defconfig
@@ -1,51 +1,98 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc1
-# Sun Jan 16 17:24:38 2005
+# Linux kernel version: 2.6.25-rc1
+# Fri Feb 15 17:13:14 2008
#
CONFIG_H8300=y
# CONFIG_MMU is not set
# CONFIG_SWAP is not set
+CONFIG_ZONE_DMA=y
# CONFIG_FPU is not set
-CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_TIME_LOW_RES=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_NO_IOPORT=y
+CONFIG_NO_DMA=y
CONFIG_ISA=y
# CONFIG_PCI is not set
+CONFIG_HZ=100
+CONFIG_C_SYMBOL_PREFIX=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
+CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_FAIR_GROUP_SCHED is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+# CONFIG_UID16 is not set
+# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_BASE_FULL is not set
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLAB is not set
+# CONFIG_SLUB is not set
+CONFIG_SLOB=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+# CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_KPROBES is not set
CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=1
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
-# Loadable module support
+# IO Schedulers
#
-# CONFIG_MODULES is not set
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
#
# Processor type and features
@@ -62,14 +109,26 @@ CONFIG_H8300H_GENERIC=y
# Detail Selection
#
# CONFIG_H83002 is not set
-# CONFIG_H83007 is not set
+CONFIG_H83007=y
# CONFIG_H83048 is not set
-CONFIG_H83068=y
+# CONFIG_H83068 is not set
CONFIG_CPU_CLOCK=20000
-# CONFIG_RAMKERNEL is not set
-CONFIG_ROMKERNEL=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
CONFIG_CPU_H8300H=y
# 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_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
#
# Executable file formats
@@ -77,34 +136,42 @@ CONFIG_CPU_H8300H=y
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_ZFLAT=y
# CONFIG_BINFMT_SHARED_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
+CONFIG_BINFMT_MISC=y
#
-# Generic Driver Options
+# Networking
#
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_NET is not set
#
-# Memory Technology Devices (MTD)
+# Generic Driver Options
#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_SYS_HYPERVISOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CONCAT=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
+# CONFIG_MTD_BLKDEVS is not set
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
@@ -129,7 +196,9 @@ CONFIG_MTD_ROM=y
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -137,7 +206,6 @@ CONFIG_MTD_UCLINUX=y
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
@@ -146,63 +214,27 @@ CONFIG_MTD_UCLINUX=y
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
+# UBI - Unsorted block images
#
+# CONFIG_MTD_UBI is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
# Input device support
#
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -223,45 +255,31 @@ CONFIG_SOUND_GAMEPORT=y
# Non-8250 serial port support
#
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
-
-#
-# I2C support
-#
# CONFIG_I2C is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
#
# File systems
#
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_JBD 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_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
-# CONFIG_QUOTA is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -280,11 +298,11 @@ CONFIG_ROMFS_FS=y
# Pseudo filesystems
#
CONFIG_PROC_FS=y
-# CONFIG_SYSFS is not set
-# CONFIG_DEVFS_FS is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -296,12 +314,13 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
@@ -310,22 +329,23 @@ CONFIG_RAMFS=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
# CONFIG_NLS is not set
#
# Kernel hacking
#
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
-CONFIG_FULLDEBUG=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_FULLDEBUG is not set
# CONFIG_HIGHPROFILE is not set
-CONFIG_NO_KERNEL_MSG=y
+# CONFIG_NO_KERNEL_MSG is not set
# CONFIG_SYSCALL_PRINT is not set
# CONFIG_GDB_DEBUG is not set
# CONFIG_SH_STANDARD_BIOS is not set
@@ -337,20 +357,17 @@ CONFIG_NO_KERNEL_MSG=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
-CONFIG_CRC32=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
+CONFIG_HAS_IOMEM=y
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c
index 5a1b4cfea05..ef4f0047067 100644
--- a/arch/h8300/kernel/irq.c
+++ b/arch/h8300/kernel/irq.c
@@ -26,7 +26,7 @@
extern unsigned long *interrupt_redirect_table;
extern const int h8300_saved_vectors[];
-extern const unsigned long h8300_trap_table[];
+extern const h8300_vector h8300_trap_table[];
int h8300_enable_irq_pin(unsigned int irq);
void h8300_disable_irq_pin(unsigned int irq);
@@ -116,7 +116,7 @@ static void __init setup_vector(void)
{
int i;
unsigned long *ramvec,*ramvec_p;
- const unsigned long *trap_entry;
+ const h8300_vector *trap_entry;
const int *saved_vector;
ramvec = get_vector_address();
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index 62ea12d339b..cf3472f7389 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -352,7 +352,7 @@ static void setup_frame (int sig, struct k_sigaction *ka,
ret = (unsigned char *)(ka->sa.sa_restorer);
else {
/* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
- err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
+ err |= __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
(unsigned long *)(frame->retcode + 0));
err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
}
@@ -428,7 +428,7 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
ret = (unsigned char *)(ka->sa.sa_restorer);
else {
/* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
- err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
+ err |= __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
(unsigned long *)(frame->retcode + 0));
err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
}
diff --git a/arch/h8300/platform/h8300h/Makefile b/arch/h8300/platform/h8300h/Makefile
index c5096369ea5..420f73b0d96 100644
--- a/arch/h8300/platform/h8300h/Makefile
+++ b/arch/h8300/platform/h8300h/Makefile
@@ -4,4 +4,4 @@
# Reuse any files we can from the H8/300H
#
-obj-y := irq_pin.o ptrace_h8300h.o
+obj-y := irq.o ptrace_h8300h.o
diff --git a/arch/h8300/platform/h8300h/irq.c b/arch/h8300/platform/h8300h/irq.c
new file mode 100644
index 00000000000..e977345105d
--- /dev/null
+++ b/arch/h8300/platform/h8300h/irq.c
@@ -0,0 +1,82 @@
+/*
+ * Interrupt handling H8/300H depend.
+ * Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+
+#include <asm/ptrace.h>
+#include <asm/traps.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/regs306x.h>
+
+const int __initdata h8300_saved_vectors[] = {
+#if defined(CONFIG_GDB_DEBUG)
+ TRAP3_VEC, /* TRAPA #3 is GDB breakpoint */
+#endif
+ -1,
+};
+
+const h8300_vector __initdata h8300_trap_table[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ system_call,
+ 0,
+ 0,
+ trace_break,
+};
+
+int h8300_enable_irq_pin(unsigned int irq)
+{
+ int bitmask;
+ if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
+ return 0;
+
+ /* initialize IRQ pin */
+ bitmask = 1 << (irq - EXT_IRQ0);
+ switch(irq) {
+ case EXT_IRQ0:
+ case EXT_IRQ1:
+ case EXT_IRQ2:
+ case EXT_IRQ3:
+ if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0)
+ return -EBUSY;
+ H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT);
+ break;
+ case EXT_IRQ4:
+ case EXT_IRQ5:
+ if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0)
+ return -EBUSY;
+ H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT);
+ break;
+ }
+
+ return 0;
+}
+
+void h8300_disable_irq_pin(unsigned int irq)
+{
+ int bitmask;
+ if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
+ return;
+
+ /* disable interrupt & release IRQ pin */
+ bitmask = 1 << (irq - EXT_IRQ0);
+ switch(irq) {
+ case EXT_IRQ0:
+ case EXT_IRQ1:
+ case EXT_IRQ2:
+ case EXT_IRQ3:
+ *(volatile unsigned char *)IER &= ~bitmask;
+ H8300_GPIO_FREE(H8300_GPIO_P8, bitmask);
+ break ;
+ case EXT_IRQ4:
+ case EXT_IRQ5:
+ *(volatile unsigned char *)IER &= ~bitmask;
+ H8300_GPIO_FREE(H8300_GPIO_P9, bitmask);
+ break;
+ }
+}
diff --git a/arch/h8300/platform/h8s/ints.c b/arch/h8300/platform/h8s/ints.c
deleted file mode 100644
index ac10b978385..00000000000
--- a/arch/h8300/platform/h8s/ints.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * linux/arch/h8300/platform/h8s/ints.c
- *
- * Yoshinori Sato <ysato@users.sourceforge.jp>
- *
- * Based on linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- *
- * Copyright 1996 Roman Zippel
- * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <linux/seq_file.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/bootmem.h>
-#include <linux/random.h>
-#include <linux/hardirq.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/traps.h>
-#include <asm/io.h>
-#include <asm/setup.h>
-#include <asm/gpio.h>
-#include <asm/regs267x.h>
-#include <asm/errno.h>
-
-/*
- * This structure has only 4 elements for speed reasons
- */
-typedef struct irq_handler {
- irqreturn_t (*handler)(int, void *, struct pt_regs *);
- int flags;
- int count;
- void *dev_id;
- const char *devname;
-} irq_handler_t;
-
-static irq_handler_t *irq_list[NR_IRQS];
-
-/* IRQ pin assignment */
-struct irq_pins {
- unsigned char port_no;
- unsigned char bit_no;
-};
-/* ISTR = 0 */
-static const struct irq_pins irq_assign_table0[16]={
- {H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1},
- {H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3},
- {H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5},
- {H8300_GPIO_P5,H8300_GPIO_B6},{H8300_GPIO_P5,H8300_GPIO_B7},
- {H8300_GPIO_P6,H8300_GPIO_B0},{H8300_GPIO_P6,H8300_GPIO_B1},
- {H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3},
- {H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5},
- {H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2},
-};
-/* ISTR = 1 */
-static const struct irq_pins irq_assign_table1[16]={
- {H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1},
- {H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3},
- {H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5},
- {H8300_GPIO_PH,H8300_GPIO_B2},{H8300_GPIO_PH,H8300_GPIO_B3},
- {H8300_GPIO_P2,H8300_GPIO_B0},{H8300_GPIO_P2,H8300_GPIO_B1},
- {H8300_GPIO_P2,H8300_GPIO_B2},{H8300_GPIO_P2,H8300_GPIO_B3},
- {H8300_GPIO_P2,H8300_GPIO_B4},{H8300_GPIO_P2,H8300_GPIO_B5},
- {H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7},
-};
-
-static short use_kmalloc = 0;
-
-extern unsigned long *interrupt_redirect_table;
-
-#define CPU_VECTOR ((unsigned long *)0x000000)
-#define ADDR_MASK (0xffffff)
-
-static inline unsigned long *get_vector_address(void)
-{
- volatile unsigned long *rom_vector = CPU_VECTOR;
- unsigned long base,tmp;
- int vec_no;
-
- base = rom_vector[EXT_IRQ0] & ADDR_MASK;
-
- /* check romvector format */
- for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ15; vec_no++) {
- if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK))
- return NULL;
- }
-
- /* ramvector base address */
- base -= EXT_IRQ0*4;
-
- /* writerble check */
- tmp = ~(*(unsigned long *)base);
- (*(unsigned long *)base) = tmp;
- if ((*(unsigned long *)base) != tmp)
- return NULL;
- return (unsigned long *)base;
-}
-
-void __init init_IRQ(void)
-{
-#if defined(CONFIG_RAMKERNEL)
- int i;
- unsigned long *ramvec,*ramvec_p;
- unsigned long break_vec;
-
- ramvec = get_vector_address();
- if (ramvec == NULL)
- panic("interrupt vector serup failed.");
- else
- printk("virtual vector at 0x%08lx\n",(unsigned long)ramvec);
-
-#if defined(CONFIG_GDB_DEBUG)
- /* save original break vector */
- break_vec = ramvec[TRAP3_VEC];
-#else
- break_vec = VECTOR(trace_break);
-#endif
-
- /* create redirect table */
- for (ramvec_p = ramvec, i = 0; i < NR_IRQS; i++)
- *ramvec_p++ = REDIRECT(interrupt_entry);
-
- /* set special vector */
- ramvec[TRAP0_VEC] = VECTOR(system_call);
- ramvec[TRAP3_VEC] = break_vec;
- interrupt_redirect_table = ramvec;
-#ifdef DUMP_VECTOR
- ramvec_p = ramvec;
- for (i = 0; i < NR_IRQS; i++) {
- if ((i % 8) == 0)
- printk("\n%p: ",ramvec_p);
- printk("%p ",*ramvec_p);
- ramvec_p++;
- }
- printk("\n");
-#endif
-#endif
-}
-
-int request_irq(unsigned int irq,
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
- unsigned long flags, const char *devname, void *dev_id)
-{
- unsigned short ptn = 1 << (irq - EXT_IRQ0);
- irq_handler_t *irq_handle;
- if (irq < 0 || irq >= NR_IRQS) {
- printk("Incorrect IRQ %d from %s\n", irq, devname);
- return -EINVAL;
- }
- if (irq_list[irq])
- return -EBUSY; /* already used */
- if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
- /* initialize IRQ pin */
- unsigned int port_no,bit_no;
- if (*(volatile unsigned short *)ITSR & ptn) {
- port_no = irq_assign_table1[irq - EXT_IRQ0].port_no;
- bit_no = irq_assign_table1[irq - EXT_IRQ0].bit_no;
- } else {
- port_no = irq_assign_table0[irq - EXT_IRQ0].port_no;
- bit_no = irq_assign_table0[irq - EXT_IRQ0].bit_no;
- }
- if (H8300_GPIO_RESERVE(port_no, bit_no) == 0)
- return -EBUSY; /* pin already use */
- H8300_GPIO_DDR(port_no, bit_no, H8300_GPIO_INPUT);
- *(volatile unsigned short *)ISR &= ~ptn; /* ISR clear */
- }
-
- if (use_kmalloc)
- irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
- else {
- /* use bootmem allocator */
- irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
- irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000);
- }
-
- if (irq_handle == NULL)
- return -ENOMEM;
-
- irq_handle->handler = handler;
- irq_handle->flags = flags;
- irq_handle->count = 0;
- irq_handle->dev_id = dev_id;
- irq_handle->devname = devname;
- irq_list[irq] = irq_handle;
- if (irq_handle->flags & IRQF_SAMPLE_RANDOM)
- rand_initialize_irq(irq);
-
- /* enable interrupt */
- /* compatible i386 */
- if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15)
- *(volatile unsigned short *)IER |= ptn;
- return 0;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-void free_irq(unsigned int irq, void *dev_id)
-{
- if (irq >= NR_IRQS)
- return;
- if (irq_list[irq]->dev_id != dev_id)
- printk("%s: Removing probably wrong IRQ %d from %s\n",
- __FUNCTION__, irq, irq_list[irq]->devname);
- if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
- /* disable interrupt & release IRQ pin */
- unsigned short port_no,bit_no;
- *(volatile unsigned short *)ISR &= ~(1 << (irq - EXT_IRQ0));
- *(volatile unsigned short *)IER |= 1 << (irq - EXT_IRQ0);
- if (*(volatile unsigned short *)ITSR & (1 << (irq - EXT_IRQ0))) {
- port_no = irq_assign_table1[irq - EXT_IRQ0].port_no;
- bit_no = irq_assign_table1[irq - EXT_IRQ0].bit_no;
- } else {
- port_no = irq_assign_table0[irq - EXT_IRQ0].port_no;
- bit_no = irq_assign_table0[irq - EXT_IRQ0].bit_no;
- }
- H8300_GPIO_FREE(port_no, bit_no);
- }
- if (((unsigned long)irq_list[irq] & 0x80000000) == 0) {
- kfree(irq_list[irq]);
- irq_list[irq] = NULL;
- }
-}
-
-EXPORT_SYMBOL(free_irq);
-
-unsigned long probe_irq_on (void)
-{
- return 0;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-int probe_irq_off (unsigned long irqs)
-{
- return 0;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-void enable_irq(unsigned int irq)
-{
- if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15)
- *(volatile unsigned short *)IER |= 1 << (irq - EXT_IRQ0);
-}
-
-void disable_irq(unsigned int irq)
-{
- if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15)
- *(volatile unsigned short *)IER &= ~(1 << (irq - EXT_IRQ0));
-}
-
-asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
-{
- irq_enter();
- /* ISR clear */
- /* compatible i386 */
- if (vec >= EXT_IRQ0 && vec <= EXT_IRQ15)
- *(volatile unsigned short *)ISR &= ~(1 << (vec - EXT_IRQ0));
- if (vec < NR_IRQS) {
- if (irq_list[vec]) {
- irq_list[vec]->handler(vec, irq_list[vec]->dev_id, fp);
- irq_list[vec]->count++;
- if (irq_list[vec]->flags & IRQF_SAMPLE_RANDOM)
- add_interrupt_randomness(vec);
- }
- } else {
- BUG();
- }
- irq_exit();
-}
-
-int show_interrupts(struct seq_file *p, void *v)
-{
- int i = *(loff_t *) v;
-
- if ((i < NR_IRQS) && (irq_list[i] !=NULL)) {
- seq_printf(p, "%3d: %10u ",i,irq_list[i]->count);
- seq_printf(p, "%s\n", irq_list[i]->devname);
- }
-
- return 0;
-}
-
-void init_irq_proc(void)
-{
-}
-
-static int __init enable_kmalloc(void)
-{
- use_kmalloc = 1;
- return 0;
-}
-core_initcall(enable_kmalloc);
diff --git a/arch/h8300/platform/h8s/ints_h8s.c b/arch/h8300/platform/h8s/irq.c
index faa8a459d95..8182f041f82 100644
--- a/arch/h8300/platform/h8s/ints_h8s.c
+++ b/arch/h8300/platform/h8s/irq.c
@@ -27,11 +27,11 @@ const int __initdata h8300_saved_vectors[]={
};
/* trap entry table */
-const unsigned long __initdata h8300_trap_table[NR_TRAPS]={
+const H8300_VECTOR __initdata h8300_trap_table[] = {
0,0,0,0,0,
- (unsigned long)trace_break, /* TRACE */
+ trace_break, /* TRACE */
0,0,
- (unsigned long)system_call, /* TRAPA #0 */
+ system_call, /* TRAPA #0 */
0,0,0,0,0,0,0
};
@@ -50,7 +50,7 @@ static const struct irq_pins irq_assign_table0[16]={
{H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3},
{H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5},
{H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2},
-};
+};
/* ISTR = 1 */
static const struct irq_pins irq_assign_table1[16]={
{H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1},
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index dff9edfc746..8fa3faf5ef1 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -18,6 +18,7 @@ config IA64
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_KPROBES
+ select HAVE_KRETPROBES
default y
help
The Itanium Processor Family is Intel's 64-bit successor to
@@ -155,6 +156,8 @@ config IA64_HP_ZX1_SWIOTLB
config IA64_SGI_SN2
bool "SGI-SN2"
+ select NUMA
+ select ACPI_NUMA
help
Selecting this option will optimize the kernel for use on sn2 based
systems, but the resulting kernel binary will not run on other
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index b916ccfdef8..f1645c4f703 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -11,6 +11,8 @@
# Copyright (C) 1998-2004 by David Mosberger-Tang <davidm@hpl.hp.com>
#
+KBUILD_DEFCONFIG := generic_defconfig
+
NM := $(CROSS_COMPILE)nm -B
READELF := $(CROSS_COMPILE)readelf
diff --git a/arch/ia64/defconfig b/arch/ia64/configs/generic_defconfig
index 0210545e7f6..0210545e7f6 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/configs/generic_defconfig
diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
index 94e57109fad..8f6bcfe1dad 100644
--- a/arch/ia64/hp/common/hwsw_iommu.c
+++ b/arch/ia64/hp/common/hwsw_iommu.c
@@ -71,7 +71,7 @@ hwsw_init (void)
#ifdef CONFIG_IA64_GENERIC
/* Better to have normal DMA than panic */
printk(KERN_WARNING "%s: Failed to initialize software I/O TLB,"
- " reverting to hpzx1 platform vector\n", __FUNCTION__);
+ " reverting to hpzx1 platform vector\n", __func__);
machvec_init("hpzx1");
#else
panic("Unable to initialize software I/O TLB services");
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index a94445422cc..523eae6d3e4 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -529,7 +529,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
base_mask = RESMAP_MASK(bits_wanted);
mask = base_mask << bitshiftcnt;
- DBG_RES("%s() o %ld %p", __FUNCTION__, o, res_ptr);
+ DBG_RES("%s() o %ld %p", __func__, o, res_ptr);
for(; res_ptr < res_end ; res_ptr++)
{
DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr);
@@ -679,7 +679,7 @@ sba_alloc_range(struct ioc *ioc, size_t size)
#endif
DBG_RES("%s(%x) %d -> %lx hint %x/%x\n",
- __FUNCTION__, size, pages_needed, pide,
+ __func__, size, pages_needed, pide,
(uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
ioc->res_bitshift );
@@ -722,8 +722,8 @@ sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1));
bits_not_wanted = 0;
- DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n", __FUNCTION__, (uint) iova, size,
- bits_not_wanted, m, pide, res_ptr, *res_ptr);
+ DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n", __func__, (uint) iova, size,
+ bits_not_wanted, m, pide, res_ptr, *res_ptr);
ASSERT(m != 0);
ASSERT(bits_not_wanted);
@@ -940,8 +940,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, int dir)
iovp = (dma_addr_t) pide << iovp_shift;
- DBG_RUN("%s() 0x%p -> 0x%lx\n",
- __FUNCTION__, addr, (long) iovp | offset);
+ DBG_RUN("%s() 0x%p -> 0x%lx\n", __func__, addr, (long) iovp | offset);
pdir_start = &(ioc->pdir_base[pide]);
@@ -1029,8 +1028,7 @@ void sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, int dir)
#endif
offset = iova & ~iovp_mask;
- DBG_RUN("%s() iovp 0x%lx/%x\n",
- __FUNCTION__, (long) iova, size);
+ DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long) iova, size);
iova ^= offset; /* clear offset bits */
size += offset;
@@ -1404,7 +1402,7 @@ int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int di
struct scatterlist *sg;
#endif
- DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
+ DBG_RUN_SG("%s() START %d entries\n", __func__, nents);
ioc = GET_IOC(dev);
ASSERT(ioc);
@@ -1468,7 +1466,7 @@ int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int di
#endif
ASSERT(coalesced == filled);
- DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);
+ DBG_RUN_SG("%s() DONE %d mappings\n", __func__, filled);
return filled;
}
@@ -1491,7 +1489,7 @@ void sba_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, in
#endif
DBG_RUN_SG("%s() START %d entries, %p,%x\n",
- __FUNCTION__, nents, sba_sg_address(sglist), sglist->length);
+ __func__, nents, sba_sg_address(sglist), sglist->length);
#ifdef ASSERT_PDIR_SANITY
ioc = GET_IOC(dev);
@@ -1509,7 +1507,7 @@ void sba_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, in
nents--;
}
- DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents);
+ DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents);
#ifdef ASSERT_PDIR_SANITY
spin_lock_irqsave(&ioc->res_lock, flags);
@@ -1546,7 +1544,7 @@ ioc_iova_init(struct ioc *ioc)
ioc->iov_size = ~ioc->imask + 1;
DBG_INIT("%s() hpa %p IOV base 0x%lx mask 0x%lx (%dMB)\n",
- __FUNCTION__, ioc->ioc_hpa, ioc->ibase, ioc->imask,
+ __func__, ioc->ioc_hpa, ioc->ibase, ioc->imask,
ioc->iov_size >> 20);
switch (iovp_size) {
@@ -1569,7 +1567,7 @@ ioc_iova_init(struct ioc *ioc)
memset(ioc->pdir_base, 0, ioc->pdir_size);
- DBG_INIT("%s() IOV page size %ldK pdir %p size %x\n", __FUNCTION__,
+ DBG_INIT("%s() IOV page size %ldK pdir %p size %x\n", __func__,
iovp_size >> 10, ioc->pdir_base, ioc->pdir_size);
ASSERT(ALIGN((unsigned long) ioc->pdir_base, 4*1024) == (unsigned long) ioc->pdir_base);
@@ -1612,7 +1610,7 @@ ioc_iova_init(struct ioc *ioc)
prefetch_spill_page = virt_to_phys(addr);
- DBG_INIT("%s() prefetch spill addr: 0x%lx\n", __FUNCTION__, prefetch_spill_page);
+ DBG_INIT("%s() prefetch spill addr: 0x%lx\n", __func__, prefetch_spill_page);
}
/*
** Set all the PDIR entries valid w/ the spill page as the target
@@ -1641,7 +1639,7 @@ ioc_resource_init(struct ioc *ioc)
/* resource map size dictated by pdir_size */
ioc->res_size = ioc->pdir_size / PDIR_ENTRY_SIZE; /* entries */
ioc->res_size >>= 3; /* convert bit count to byte count */
- DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, ioc->res_size);
+ DBG_INIT("%s() res_size 0x%x\n", __func__, ioc->res_size);
ioc->res_map = (char *) __get_free_pages(GFP_KERNEL,
get_order(ioc->res_size));
@@ -1664,7 +1662,7 @@ ioc_resource_init(struct ioc *ioc)
| prefetch_spill_page);
#endif
- DBG_INIT("%s() res_map %x %p\n", __FUNCTION__,
+ DBG_INIT("%s() res_map %x %p\n", __func__,
ioc->res_size, (void *) ioc->res_map);
}
@@ -1767,7 +1765,7 @@ ioc_init(u64 hpa, void *handle)
iovp_size = (1 << iovp_shift);
iovp_mask = ~(iovp_size - 1);
- DBG_INIT("%s: PAGE_SIZE %ldK, iovp_size %ldK\n", __FUNCTION__,
+ DBG_INIT("%s: PAGE_SIZE %ldK, iovp_size %ldK\n", __func__,
PAGE_SIZE >> 10, iovp_size >> 10);
if (!ioc->name) {
@@ -2137,7 +2135,7 @@ sba_page_override(char *str)
break;
default:
printk("%s: unknown/unsupported iommu page size %ld\n",
- __FUNCTION__, page_size);
+ __func__, page_size);
}
return 1;
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
index 9898febf609..969fe9f443c 100644
--- a/arch/ia64/hp/sim/simeth.c
+++ b/arch/ia64/hp/sim/simeth.c
@@ -222,7 +222,7 @@ simeth_probe1(void)
}
if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
- panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+ panic("%s: out of interrupt vectors!\n", __func__);
dev->irq = rc;
/*
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index ef252df50e1..eb0c32a85fd 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -1000,7 +1000,7 @@ simrs_init (void)
if (!state->irq) {
if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
panic("%s: out of interrupt vectors!\n",
- __FUNCTION__);
+ __func__);
state->irq = rc;
ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
}
diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
index 85e82f32e48..256a7faeda0 100644
--- a/arch/ia64/ia32/ia32_signal.c
+++ b/arch/ia64/ia32/ia32_signal.c
@@ -766,8 +766,19 @@ get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
- if (!on_sig_stack(esp))
+ int onstack = sas_ss_flags(esp);
+
+ if (onstack == 0)
esp = current->sas_ss_sp + current->sas_ss_size;
+ else if (onstack == SS_ONSTACK) {
+ /*
+ * If we are on the alternate signal stack and would
+ * overflow it, don't. Return an always-bogus address
+ * instead so we will die with SIGSEGV.
+ */
+ if (!likely(on_sig_stack(esp - frame_size)))
+ return (void __user *) -1L;
+ }
}
/* Legacy stack switching not supported */
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index d025a22eb22..b1bf51fe97b 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -32,13 +32,8 @@
#include <linux/shm.h>
#include <linux/slab.h>
#include <linux/uio.h>
-#include <linux/nfs_fs.h>
+#include <linux/socket.h>
#include <linux/quota.h>
-#include <linux/sunrpc/svc.h>
-#include <linux/nfsd/nfsd.h>
-#include <linux/nfsd/cache.h>
-#include <linux/nfsd/xdr.h>
-#include <linux/nfsd/syscall.h>
#include <linux/poll.h>
#include <linux/eventpoll.h>
#include <linux/personality.h>
diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c
index f1cf2df97a2..fbe742ad2fd 100644
--- a/arch/ia64/kernel/crash.c
+++ b/arch/ia64/kernel/crash.c
@@ -155,7 +155,7 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
if (val == DIE_INIT_MONARCH_LEAVE)
ia64_mca_printk(KERN_NOTICE
"%s: kdump not configured\n",
- __FUNCTION__);
+ __func__);
return NOTIFY_DONE;
}
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 919070a9aed..728d7247a1a 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -379,8 +379,8 @@ efi_get_pal_addr (void)
* a dedicated ITR for the PAL code.
*/
if ((vaddr & mask) == (KERNEL_START & mask)) {
- printk(KERN_INFO "%s: no need to install ITR for "
- "PAL code\n", __FUNCTION__);
+ printk(KERN_INFO "%s: no need to install ITR for PAL code\n",
+ __func__);
continue;
}
@@ -399,7 +399,7 @@ efi_get_pal_addr (void)
return __va(md->phys_addr);
}
printk(KERN_WARNING "%s: no PAL-code memory-descriptor found\n",
- __FUNCTION__);
+ __func__);
return NULL;
}
@@ -543,12 +543,30 @@ efi_init (void)
for (i = 0, p = efi_map_start; p < efi_map_end;
++i, p += efi_desc_size)
{
+ const char *unit;
+ unsigned long size;
+
md = p;
- printk("mem%02u: type=%u, attr=0x%lx, "
- "range=[0x%016lx-0x%016lx) (%luMB)\n",
+ size = md->num_pages << EFI_PAGE_SHIFT;
+
+ if ((size >> 40) > 0) {
+ size >>= 40;
+ unit = "TB";
+ } else if ((size >> 30) > 0) {
+ size >>= 30;
+ unit = "GB";
+ } else if ((size >> 20) > 0) {
+ size >>= 20;
+ unit = "MB";
+ } else {
+ size >>= 10;
+ unit = "KB";
+ }
+
+ printk("mem%02d: type=%2u, attr=0x%016lx, "
+ "range=[0x%016lx-0x%016lx) (%4lu%s)\n",
i, md->type, md->attribute, md->phys_addr,
- md->phys_addr + efi_md_size(md),
- md->num_pages >> (20 - EFI_PAGE_SHIFT));
+ md->phys_addr + efi_md_size(md), size, unit);
}
}
#endif
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 398e2fd1cd2..082c31dcfd9 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -345,7 +345,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
if (cpus_empty(mask))
return;
- if (reassign_irq_vector(irq, first_cpu(mask)))
+ if (irq_prepare_move(irq, first_cpu(mask)))
return;
dest = cpu_physical_id(first_cpu(mask));
@@ -397,6 +397,7 @@ iosapic_end_level_irq (unsigned int irq)
struct iosapic_rte_info *rte;
int do_unmask_irq = 0;
+ irq_complete_move(irq);
if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
do_unmask_irq = 1;
mask_irq(irq);
@@ -450,6 +451,7 @@ iosapic_ack_edge_irq (unsigned int irq)
{
irq_desc_t *idesc = irq_desc + irq;
+ irq_complete_move(irq);
move_native_irq(irq);
/*
* Once we have recorded IRQ_PENDING already, we can mask the
@@ -532,7 +534,7 @@ iosapic_reassign_vector (int irq)
if (iosapic_intr_info[irq].count) {
new_irq = create_irq();
if (new_irq < 0)
- panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+ panic("%s: out of interrupt vectors!\n", __func__);
printk(KERN_INFO "Reassigning vector %d to %d\n",
irq_to_vector(irq), irq_to_vector(new_irq));
memcpy(&iosapic_intr_info[new_irq], &iosapic_intr_info[irq],
@@ -597,7 +599,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
index = find_iosapic(gsi);
if (index < 0) {
printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n",
- __FUNCTION__, gsi);
+ __func__, gsi);
return -ENODEV;
}
@@ -606,7 +608,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
rte = iosapic_alloc_rte();
if (!rte) {
printk(KERN_WARNING "%s: cannot allocate memory\n",
- __FUNCTION__);
+ __func__);
return -ENOMEM;
}
@@ -623,7 +625,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
(info->trigger != trigger || info->polarity != polarity)){
printk (KERN_WARNING
"%s: cannot override the interrupt\n",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
rte->refcnt++;
@@ -645,7 +647,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
if (idesc->chip != &no_irq_type)
printk(KERN_WARNING
"%s: changing vector %d from %s to %s\n",
- __FUNCTION__, irq_to_vector(irq),
+ __func__, irq_to_vector(irq),
idesc->chip->name, irq_type->name);
idesc->chip = irq_type;
}
@@ -918,7 +920,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
case ACPI_INTERRUPT_INIT:
irq = create_irq();
if (irq < 0)
- panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+ panic("%s: out of interrupt vectors!\n", __func__);
vector = irq_to_vector(irq);
delivery = IOSAPIC_INIT;
break;
@@ -929,7 +931,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
mask = 1;
break;
default:
- printk(KERN_ERR "%s: invalid int type 0x%x\n", __FUNCTION__,
+ printk(KERN_ERR "%s: invalid int type 0x%x\n", __func__,
int_type);
return -1;
}
@@ -994,7 +996,7 @@ iosapic_system_init (int system_pcat_compat)
*/
printk(KERN_INFO
"%s: Disabling PC-AT compatible 8259 interrupts\n",
- __FUNCTION__);
+ __func__);
outb(0xff, 0xA1);
outb(0xff, 0x21);
}
@@ -1009,7 +1011,7 @@ iosapic_alloc (void)
if (!iosapic_lists[index].addr)
return index;
- printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: failed to allocate iosapic\n", __func__);
return -1;
}
@@ -1107,14 +1109,14 @@ iosapic_remove (unsigned int gsi_base)
index = find_iosapic(gsi_base);
if (index < 0) {
printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",
- __FUNCTION__, gsi_base);
+ __func__, gsi_base);
goto out;
}
if (iosapic_lists[index].rtes_inuse) {
err = -EBUSY;
printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",
- __FUNCTION__, gsi_base);
+ __func__, gsi_base);
goto out;
}
@@ -1135,7 +1137,7 @@ map_iosapic_to_node(unsigned int gsi_base, int node)
index = find_iosapic(gsi_base);
if (index < 0) {
printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n",
- __FUNCTION__, gsi_base);
+ __func__, gsi_base);
return;
}
iosapic_lists[index].node = node;
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 0b52f19ed04..d8be23fbe6b 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -260,6 +260,8 @@ void __setup_vector_irq(int cpu)
}
#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG))
+#define IA64_IRQ_MOVE_VECTOR IA64_DEF_FIRST_DEVICE_VECTOR
+
static enum vector_domain_type {
VECTOR_DOMAIN_NONE,
VECTOR_DOMAIN_PERCPU
@@ -272,6 +274,101 @@ static cpumask_t vector_allocation_domain(int cpu)
return CPU_MASK_ALL;
}
+static int __irq_prepare_move(int irq, int cpu)
+{
+ struct irq_cfg *cfg = &irq_cfg[irq];
+ int vector;
+ cpumask_t domain;
+
+ if (cfg->move_in_progress || cfg->move_cleanup_count)
+ return -EBUSY;
+ if (cfg->vector == IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu))
+ return -EINVAL;
+ if (cpu_isset(cpu, cfg->domain))
+ return 0;
+ domain = vector_allocation_domain(cpu);
+ vector = find_unassigned_vector(domain);
+ if (vector < 0)
+ return -ENOSPC;
+ cfg->move_in_progress = 1;
+ cfg->old_domain = cfg->domain;
+ cfg->vector = IRQ_VECTOR_UNASSIGNED;
+ cfg->domain = CPU_MASK_NONE;
+ BUG_ON(__bind_irq_vector(irq, vector, domain));
+ return 0;
+}
+
+int irq_prepare_move(int irq, int cpu)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&vector_lock, flags);
+ ret = __irq_prepare_move(irq, cpu);
+ spin_unlock_irqrestore(&vector_lock, flags);
+ return ret;
+}
+
+void irq_complete_move(unsigned irq)
+{
+ struct irq_cfg *cfg = &irq_cfg[irq];
+ cpumask_t cleanup_mask;
+ int i;
+
+ if (likely(!cfg->move_in_progress))
+ return;
+
+ if (unlikely(cpu_isset(smp_processor_id(), cfg->old_domain)))
+ return;
+
+ cpus_and(cleanup_mask, cfg->old_domain, cpu_online_map);
+ cfg->move_cleanup_count = cpus_weight(cleanup_mask);
+ for_each_cpu_mask(i, cleanup_mask)
+ platform_send_ipi(i, IA64_IRQ_MOVE_VECTOR, IA64_IPI_DM_INT, 0);
+ cfg->move_in_progress = 0;
+}
+
+static irqreturn_t smp_irq_move_cleanup_interrupt(int irq, void *dev_id)
+{
+ int me = smp_processor_id();
+ ia64_vector vector;
+ unsigned long flags;
+
+ for (vector = IA64_FIRST_DEVICE_VECTOR;
+ vector < IA64_LAST_DEVICE_VECTOR; vector++) {
+ int irq;
+ struct irq_desc *desc;
+ struct irq_cfg *cfg;
+ irq = __get_cpu_var(vector_irq)[vector];
+ if (irq < 0)
+ continue;
+
+ desc = irq_desc + irq;
+ cfg = irq_cfg + irq;
+ spin_lock(&desc->lock);
+ if (!cfg->move_cleanup_count)
+ goto unlock;
+
+ if (!cpu_isset(me, cfg->old_domain))
+ goto unlock;
+
+ spin_lock_irqsave(&vector_lock, flags);
+ __get_cpu_var(vector_irq)[vector] = -1;
+ cpu_clear(me, vector_table[vector]);
+ spin_unlock_irqrestore(&vector_lock, flags);
+ cfg->move_cleanup_count--;
+ unlock:
+ spin_unlock(&desc->lock);
+ }
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq_move_irqaction = {
+ .handler = smp_irq_move_cleanup_interrupt,
+ .flags = IRQF_DISABLED,
+ .name = "irq_move"
+};
+
static int __init parse_vector_domain(char *arg)
{
if (!arg)
@@ -303,36 +400,6 @@ void destroy_and_reserve_irq(unsigned int irq)
spin_unlock_irqrestore(&vector_lock, flags);
}
-static int __reassign_irq_vector(int irq, int cpu)
-{
- struct irq_cfg *cfg = &irq_cfg[irq];
- int vector;
- cpumask_t domain;
-
- if (cfg->vector == IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu))
- return -EINVAL;
- if (cpu_isset(cpu, cfg->domain))
- return 0;
- domain = vector_allocation_domain(cpu);
- vector = find_unassigned_vector(domain);
- if (vector < 0)
- return -ENOSPC;
- __clear_irq_vector(irq);
- BUG_ON(__bind_irq_vector(irq, vector, domain));
- return 0;
-}
-
-int reassign_irq_vector(int irq, int cpu)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&vector_lock, flags);
- ret = __reassign_irq_vector(irq, cpu);
- spin_unlock_irqrestore(&vector_lock, flags);
- return ret;
-}
-
/*
* Dynamic irq allocate and deallocation for MSI
*/
@@ -440,7 +507,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
if (unlikely(irq < 0)) {
printk(KERN_ERR "%s: Unexpected interrupt "
"vector %d on CPU %d is not mapped "
- "to any IRQ!\n", __FUNCTION__, vector,
+ "to any IRQ!\n", __func__, vector,
smp_processor_id());
} else
generic_handle_irq(irq);
@@ -505,7 +572,7 @@ void ia64_process_pending_intr(void)
if (unlikely(irq < 0)) {
printk(KERN_ERR "%s: Unexpected interrupt "
"vector %d on CPU %d not being mapped "
- "to any IRQ!!\n", __FUNCTION__, vector,
+ "to any IRQ!!\n", __func__, vector,
smp_processor_id());
} else {
vectors_in_migration[irq]=0;
@@ -578,6 +645,13 @@ init_IRQ (void)
register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &tlb_irqaction);
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)
+ if (vector_domain_type != VECTOR_DOMAIN_NONE) {
+ BUG_ON(IA64_FIRST_DEVICE_VECTOR != IA64_IRQ_MOVE_VECTOR);
+ IA64_FIRST_DEVICE_VECTOR++;
+ register_percpu_irq(IA64_IRQ_MOVE_VECTOR, &irq_move_irqaction);
+ }
+#endif
#endif
#ifdef CONFIG_PERFMON
pfm_init_percpu();
@@ -592,11 +666,7 @@ ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect)
unsigned long ipi_data;
unsigned long phys_cpu_id;
-#ifdef CONFIG_SMP
phys_cpu_id = cpu_physical_id(cpu);
-#else
- phys_cpu_id = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
-#endif
/*
* cpu number is in 8bit ID and 8bit EID
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index b618487cdc8..8d9a446a0d1 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -838,7 +838,7 @@ out:
return 1;
}
-int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{
struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -1001,6 +1001,11 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
return 1;
}
+/* ia64 does not need this */
+void __kprobes jprobe_return(void)
+{
+}
+
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 6e17aed5313..6c18221dba3 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -413,8 +413,8 @@ ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe)
IA64_LOG_INDEX_INC(sal_info_type);
IA64_LOG_UNLOCK(sal_info_type);
if (irq_safe) {
- IA64_MCA_DEBUG("%s: SAL error record type %d retrieved. "
- "Record length = %ld\n", __FUNCTION__, sal_info_type, total_len);
+ IA64_MCA_DEBUG("%s: SAL error record type %d retrieved. Record length = %ld\n",
+ __func__, sal_info_type, total_len);
}
*buffer = (u8 *) log_buffer;
return total_len;
@@ -518,7 +518,7 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg)
static DEFINE_SPINLOCK(cpe_history_lock);
IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n",
- __FUNCTION__, cpe_irq, smp_processor_id());
+ __func__, cpe_irq, smp_processor_id());
/* SAL spec states this should run w/ interrupts enabled */
local_irq_enable();
@@ -594,7 +594,7 @@ ia64_mca_register_cpev (int cpev)
}
IA64_MCA_DEBUG("%s: corrected platform error "
- "vector %#x registered\n", __FUNCTION__, cpev);
+ "vector %#x registered\n", __func__, cpev);
}
#endif /* CONFIG_ACPI */
@@ -621,12 +621,11 @@ ia64_mca_cmc_vector_setup (void)
cmcv.cmcv_vector = IA64_CMC_VECTOR;
ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval);
- IA64_MCA_DEBUG("%s: CPU %d corrected "
- "machine check vector %#x registered.\n",
- __FUNCTION__, smp_processor_id(), IA64_CMC_VECTOR);
+ IA64_MCA_DEBUG("%s: CPU %d corrected machine check vector %#x registered.\n",
+ __func__, smp_processor_id(), IA64_CMC_VECTOR);
IA64_MCA_DEBUG("%s: CPU %d CMCV = %#016lx\n",
- __FUNCTION__, smp_processor_id(), ia64_getreg(_IA64_REG_CR_CMCV));
+ __func__, smp_processor_id(), ia64_getreg(_IA64_REG_CR_CMCV));
}
/*
@@ -651,9 +650,8 @@ ia64_mca_cmc_vector_disable (void *dummy)
cmcv.cmcv_mask = 1; /* Mask/disable interrupt */
ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval);
- IA64_MCA_DEBUG("%s: CPU %d corrected "
- "machine check vector %#x disabled.\n",
- __FUNCTION__, smp_processor_id(), cmcv.cmcv_vector);
+ IA64_MCA_DEBUG("%s: CPU %d corrected machine check vector %#x disabled.\n",
+ __func__, smp_processor_id(), cmcv.cmcv_vector);
}
/*
@@ -678,9 +676,8 @@ ia64_mca_cmc_vector_enable (void *dummy)
cmcv.cmcv_mask = 0; /* Unmask/enable interrupt */
ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval);
- IA64_MCA_DEBUG("%s: CPU %d corrected "
- "machine check vector %#x enabled.\n",
- __FUNCTION__, smp_processor_id(), cmcv.cmcv_vector);
+ IA64_MCA_DEBUG("%s: CPU %d corrected machine check vector %#x enabled.\n",
+ __func__, smp_processor_id(), cmcv.cmcv_vector);
}
/*
@@ -767,7 +764,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg)
local_irq_save(flags);
if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", get_irq_regs(),
(long)&nd, 0, 0) == NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
/* Register with the SAL monarch that the slave has
@@ -777,7 +774,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg)
if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", get_irq_regs(),
(long)&nd, 0, 0) == NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
/* Wait for the monarch cpu to exit. */
while (monarch_cpu != -1)
@@ -785,7 +782,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg)
if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", get_irq_regs(),
(long)&nd, 0, 0) == NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
/* Enable all interrupts */
@@ -1230,7 +1227,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA;
if (sos->monarch) {
@@ -1246,7 +1243,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
ia64_mca_wakeup_all();
if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
} else {
while (cpu_isset(cpu, mca_cpu))
cpu_relax(); /* spin until monarch wakes us */
@@ -1276,7 +1273,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
}
if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover)
== NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
if (atomic_dec_return(&mca_count) > 0) {
@@ -1328,7 +1325,7 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg)
static DEFINE_SPINLOCK(cmc_history_lock);
IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n",
- __FUNCTION__, cmc_irq, smp_processor_id());
+ __func__, cmc_irq, smp_processor_id());
/* SAL spec states this should run w/ interrupts enabled */
local_irq_enable();
@@ -1614,7 +1611,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
*/
if (!sos->monarch && atomic_add_return(1, &slaves) == num_online_cpus()) {
mprintk(KERN_WARNING "%s: Promoting cpu %d to monarch.\n",
- __FUNCTION__, cpu);
+ __func__, cpu);
atomic_dec(&slaves);
sos->monarch = 1;
}
@@ -1626,7 +1623,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
*/
if (sos->monarch && atomic_add_return(1, &monarchs) > 1) {
mprintk(KERN_WARNING "%s: Demoting cpu %d to slave.\n",
- __FUNCTION__, cpu);
+ __func__, cpu);
atomic_dec(&monarchs);
sos->monarch = 0;
}
@@ -1637,15 +1634,15 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
cpu_relax(); /* spin until monarch enters */
if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
while (monarch_cpu != -1)
cpu_relax(); /* spin until monarch leaves */
if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
mprintk("Slave on cpu %d returning to normal service.\n", cpu);
set_curr_task(cpu, previous_current);
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
@@ -1656,7 +1653,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
monarch_cpu = cpu;
if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
/*
* Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
@@ -1673,10 +1670,10 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
*/
if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
- ia64_mca_spin(__FUNCTION__);
+ ia64_mca_spin(__func__);
mprintk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
atomic_dec(&monarchs);
set_curr_task(cpu, previous_current);
@@ -1884,7 +1881,7 @@ ia64_mca_init(void)
.priority = 0/* we need to notified last */
};
- IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
+ IA64_MCA_DEBUG("%s: begin\n", __func__);
/* Clear the Rendez checkin flag for all cpus */
for(i = 0 ; i < NR_CPUS; i++)
@@ -1928,7 +1925,7 @@ ia64_mca_init(void)
return;
}
- IA64_MCA_DEBUG("%s: registered MCA rendezvous spinloop and wakeup mech.\n", __FUNCTION__);
+ IA64_MCA_DEBUG("%s: registered MCA rendezvous spinloop and wakeup mech.\n", __func__);
ia64_mc_info.imi_mca_handler = ia64_tpa(mca_hldlr_ptr->fp);
/*
@@ -1949,7 +1946,7 @@ ia64_mca_init(void)
return;
}
- IA64_MCA_DEBUG("%s: registered OS MCA handler with SAL at 0x%lx, gp = 0x%lx\n", __FUNCTION__,
+ IA64_MCA_DEBUG("%s: registered OS MCA handler with SAL at 0x%lx, gp = 0x%lx\n", __func__,
ia64_mc_info.imi_mca_handler, ia64_tpa(mca_hldlr_ptr->gp));
/*
@@ -1961,7 +1958,7 @@ ia64_mca_init(void)
ia64_mc_info.imi_slave_init_handler = ia64_tpa(init_hldlr_ptr_slave->fp);
ia64_mc_info.imi_slave_init_handler_size = 0;
- IA64_MCA_DEBUG("%s: OS INIT handler at %lx\n", __FUNCTION__,
+ IA64_MCA_DEBUG("%s: OS INIT handler at %lx\n", __func__,
ia64_mc_info.imi_monarch_init_handler);
/* Register the os init handler with SAL */
@@ -1982,7 +1979,7 @@ ia64_mca_init(void)
return;
}
- IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__);
+ IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __func__);
/*
* Configure the CMCI/P vector and handler. Interrupts for CMC are
@@ -2042,7 +2039,7 @@ ia64_mca_late_init(void)
cmc_polling_enabled = 0;
schedule_work(&cmc_enable_work);
- IA64_MCA_DEBUG("%s: CMCI/P setup and enabled.\n", __FUNCTION__);
+ IA64_MCA_DEBUG("%s: CMCI/P setup and enabled.\n", __func__);
#ifdef CONFIG_ACPI
/* Setup the CPEI/P vector and handler */
@@ -2065,17 +2062,17 @@ ia64_mca_late_init(void)
ia64_cpe_irq = irq;
ia64_mca_register_cpev(cpe_vector);
IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n",
- __FUNCTION__);
+ __func__);
return 0;
}
printk(KERN_ERR "%s: Failed to find irq for CPE "
"interrupt handler, vector %d\n",
- __FUNCTION__, cpe_vector);
+ __func__, cpe_vector);
}
/* If platform doesn't support CPEI, get the timer going. */
if (cpe_poll_enabled) {
ia64_mca_cpe_poll(0UL);
- IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __FUNCTION__);
+ IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __func__);
}
}
#endif
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index e58f4367cf1..e83e2ea3b3e 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -493,7 +493,7 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
mod->arch.opd->sh_addralign = 8;
mod->arch.opd->sh_size = fdescs * sizeof(struct fdesc);
DEBUGP("%s: core.plt=%lx, init.plt=%lx, got=%lx, fdesc=%lx\n",
- __FUNCTION__, mod->arch.core_plt->sh_size, mod->arch.init_plt->sh_size,
+ __func__, mod->arch.core_plt->sh_size, mod->arch.init_plt->sh_size,
mod->arch.got->sh_size, mod->arch.opd->sh_size);
return 0;
}
@@ -585,7 +585,7 @@ get_plt (struct module *mod, const struct insn *insn, uint64_t value, int *okp)
#if ARCH_MODULE_DEBUG
if (plt_target(plt) != target_ip) {
printk("%s: mistargeted PLT: wanted %lx, got %lx\n",
- __FUNCTION__, target_ip, plt_target(plt));
+ __func__, target_ip, plt_target(plt));
*okp = 0;
return 0;
}
@@ -703,7 +703,7 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
if (r_type == R_IA64_PCREL21BI) {
if (!is_internal(mod, val)) {
printk(KERN_ERR "%s: %s reloc against non-local symbol (%lx)\n",
- __FUNCTION__, reloc_name[r_type], val);
+ __func__, reloc_name[r_type], val);
return -ENOEXEC;
}
format = RF_INSN21B;
@@ -737,7 +737,7 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
case R_IA64_LDXMOV:
if (gp_addressable(mod, val)) {
/* turn "ld8" into "mov": */
- DEBUGP("%s: patching ld8 at %p to mov\n", __FUNCTION__, location);
+ DEBUGP("%s: patching ld8 at %p to mov\n", __func__, location);
ia64_patch((u64) location, 0x1fff80fe000UL, 0x10000000000UL);
}
return 0;
@@ -771,7 +771,7 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
if (!ok)
return -ENOEXEC;
- DEBUGP("%s: [%p]<-%016lx = %s(%lx)\n", __FUNCTION__, location, val,
+ DEBUGP("%s: [%p]<-%016lx = %s(%lx)\n", __func__, location, val,
reloc_name[r_type] ? reloc_name[r_type] : "?", sym->st_value + addend);
switch (format) {
@@ -807,7 +807,7 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
Elf64_Shdr *target_sec;
int ret;
- DEBUGP("%s: applying section %u (%u relocs) to %u\n", __FUNCTION__,
+ DEBUGP("%s: applying section %u (%u relocs) to %u\n", __func__,
relsec, n, sechdrs[relsec].sh_info);
target_sec = sechdrs + sechdrs[relsec].sh_info;
@@ -835,7 +835,7 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
gp = mod->core_size / 2;
gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
mod->arch.gp = gp;
- DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
+ DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
}
for (i = 0; i < n; i++) {
@@ -903,7 +903,7 @@ register_unwind_table (struct module *mod)
init = start + num_core;
}
- DEBUGP("%s: name=%s, gp=%lx, num_init=%lu, num_core=%lu\n", __FUNCTION__,
+ DEBUGP("%s: name=%s, gp=%lx, num_init=%lu, num_core=%lu\n", __func__,
mod->name, mod->arch.gp, num_init, num_core);
/*
@@ -912,13 +912,13 @@ register_unwind_table (struct module *mod)
if (num_core > 0) {
mod->arch.core_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp,
core, core + num_core);
- DEBUGP("%s: core: handle=%p [%p-%p)\n", __FUNCTION__,
+ DEBUGP("%s: core: handle=%p [%p-%p)\n", __func__,
mod->arch.core_unw_table, core, core + num_core);
}
if (num_init > 0) {
mod->arch.init_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp,
init, init + num_init);
- DEBUGP("%s: init: handle=%p [%p-%p)\n", __FUNCTION__,
+ DEBUGP("%s: init: handle=%p [%p-%p)\n", __func__,
mod->arch.init_unw_table, init, init + num_init);
}
}
@@ -926,7 +926,7 @@ register_unwind_table (struct module *mod)
int
module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod)
{
- DEBUGP("%s: init: entry=%p\n", __FUNCTION__, mod->init);
+ DEBUGP("%s: init: entry=%p\n", __func__, mod->init);
if (mod->arch.unwind)
register_unwind_table(mod);
return 0;
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index e86d0295979..60c6ef67ebb 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -57,7 +57,7 @@ static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
if (!cpu_online(cpu))
return;
- if (reassign_irq_vector(irq, cpu))
+ if (irq_prepare_move(irq, cpu))
return;
read_msi_msg(irq, &msg);
@@ -119,6 +119,7 @@ void ia64_teardown_msi_irq(unsigned int irq)
static void ia64_ack_msi_irq(unsigned int irq)
{
+ irq_complete_move(irq);
move_native_irq(irq);
ia64_eoi();
}
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index f6b99719f10..a2aabfdc80d 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -227,12 +227,12 @@
#ifdef PFM_DEBUGGING
#define DPRINT(a) \
do { \
- if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
+ if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __func__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
} while (0)
#define DPRINT_ovfl(a) \
do { \
- if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
+ if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __func__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
} while (0)
#endif
diff --git a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c
index a7af1cb419f..5f637bbfccc 100644
--- a/arch/ia64/kernel/perfmon_default_smpl.c
+++ b/arch/ia64/kernel/perfmon_default_smpl.c
@@ -24,12 +24,12 @@ MODULE_LICENSE("GPL");
#ifdef DEFAULT_DEBUG
#define DPRINT(a) \
do { \
- if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+ if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d ", __func__, __LINE__, smp_processor_id()); printk a; } \
} while (0)
#define DPRINT_ovfl(a) \
do { \
- if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+ if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d ", __func__, __LINE__, smp_processor_id()); printk a; } \
} while (0)
#else
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 331d6768b5d..ab784ec4319 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -698,52 +698,6 @@ thread_matches (struct task_struct *thread, unsigned long addr)
}
/*
- * GDB apparently wants to be able to read the register-backing store
- * of any thread when attached to a given process. If we are peeking
- * or poking an address that happens to reside in the kernel-backing
- * store of another thread, we need to attach to that thread, because
- * otherwise we end up accessing stale data.
- *
- * task_list_lock must be read-locked before calling this routine!
- */
-static struct task_struct *
-find_thread_for_addr (struct task_struct *child, unsigned long addr)
-{
- struct task_struct *p;
- struct mm_struct *mm;
- struct list_head *this, *next;
- int mm_users;
-
- if (!(mm = get_task_mm(child)))
- return child;
-
- /* -1 because of our get_task_mm(): */
- mm_users = atomic_read(&mm->mm_users) - 1;
- if (mm_users <= 1)
- goto out; /* not multi-threaded */
-
- /*
- * Traverse the current process' children list. Every task that
- * one attaches to becomes a child. And it is only attached children
- * of the debugger that are of interest (ptrace_check_attach checks
- * for this).
- */
- list_for_each_safe(this, next, &current->children) {
- p = list_entry(this, struct task_struct, sibling);
- if (p->tgid != child->tgid)
- continue;
- if (thread_matches(p, addr)) {
- child = p;
- goto out;
- }
- }
-
- out:
- mmput(mm);
- return child;
-}
-
-/*
* Write f32-f127 back to task->thread.fph if it has been modified.
*/
inline void
@@ -826,14 +780,14 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt,
if ((long)((unsigned long)child + IA64_STK_OFFSET - sp)
< IA64_PT_REGS_SIZE) {
dprintk("ptrace.%s: ran off the top of the kernel "
- "stack\n", __FUNCTION__);
+ "stack\n", __func__);
return;
}
if (unw_get_pr (&prev_info, &pr) < 0) {
unw_get_rp(&prev_info, &ip);
dprintk("ptrace.%s: failed to read "
"predicate register (ip=0x%lx)\n",
- __FUNCTION__, ip);
+ __func__, ip);
return;
}
if (unw_is_intr_frame(&info)
@@ -908,7 +862,7 @@ static int
access_uarea (struct task_struct *child, unsigned long addr,
unsigned long *data, int write_access)
{
- unsigned long *ptr, regnum, urbs_end, rnat_addr, cfm;
+ unsigned long *ptr, regnum, urbs_end, cfm;
struct switch_stack *sw;
struct pt_regs *pt;
# define pt_reg_addr(pt, reg) ((void *) \
@@ -1011,14 +965,9 @@ access_uarea (struct task_struct *child, unsigned long addr,
* the kernel was entered.
*
* Furthermore, when changing the contents of
- * PT_AR_BSP (or PT_CFM) we MUST copy any
- * users-level stacked registers that are
- * stored on the kernel stack back to
- * user-space because otherwise, we might end
- * up clobbering kernel stacked registers.
- * Also, if this happens while the task is
- * blocked in a system call, which convert the
- * state such that the non-system-call exit
+ * PT_AR_BSP (or PT_CFM) while the task is
+ * blocked in a system call, convert the state
+ * so that the non-system-call exit
* path is used. This ensures that the proper
* state will be picked up when resuming
* execution. However, it *also* means that
@@ -1035,10 +984,6 @@ access_uarea (struct task_struct *child, unsigned long addr,
urbs_end = ia64_get_user_rbs_end(child, pt, &cfm);
if (write_access) {
if (*data != urbs_end) {
- if (ia64_sync_user_rbs(child, sw,
- pt->ar_bspstore,
- urbs_end) < 0)
- return -1;
if (in_syscall(pt))
convert_to_non_syscall(child,
pt,
@@ -1058,10 +1003,6 @@ access_uarea (struct task_struct *child, unsigned long addr,
urbs_end = ia64_get_user_rbs_end(child, pt, &cfm);
if (write_access) {
if (((cfm ^ *data) & PFM_MASK) != 0) {
- if (ia64_sync_user_rbs(child, sw,
- pt->ar_bspstore,
- urbs_end) < 0)
- return -1;
if (in_syscall(pt))
convert_to_non_syscall(child,
pt,
@@ -1093,16 +1034,8 @@ access_uarea (struct task_struct *child, unsigned long addr,
return 0;
case PT_AR_RNAT:
- urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
- rnat_addr = (long) ia64_rse_rnat_addr((long *)
- urbs_end);
- if (write_access)
- return ia64_poke(child, sw, urbs_end,
- rnat_addr, *data);
- else
- return ia64_peek(child, sw, urbs_end,
- rnat_addr, data);
-
+ ptr = pt_reg_addr(pt, ar_rnat);
+ break;
case PT_R1:
ptr = pt_reg_addr(pt, r1);
break;
@@ -1521,215 +1454,97 @@ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
return ret;
}
-/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure the single step bit is not set.
- */
void
-ptrace_disable (struct task_struct *child)
+user_enable_single_step (struct task_struct *child)
{
struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
- /* make sure the single step/taken-branch trap bits are not set: */
- clear_tsk_thread_flag(child, TIF_SINGLESTEP);
- child_psr->ss = 0;
- child_psr->tb = 0;
+ set_tsk_thread_flag(child, TIF_SINGLESTEP);
+ child_psr->ss = 1;
}
-asmlinkage long
-sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
+void
+user_enable_block_step (struct task_struct *child)
{
- struct pt_regs *pt;
- unsigned long urbs_end, peek_or_poke;
- struct task_struct *child;
- struct switch_stack *sw;
- long ret;
- struct unw_frame_info info;
+ struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- ret = ptrace_traceme();
- goto out;
- }
+ set_tsk_thread_flag(child, TIF_SINGLESTEP);
+ child_psr->tb = 1;
+}
- peek_or_poke = (request == PTRACE_PEEKTEXT
- || request == PTRACE_PEEKDATA
- || request == PTRACE_POKETEXT
- || request == PTRACE_POKEDATA);
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- {
- child = find_task_by_pid(pid);
- if (child) {
- if (peek_or_poke)
- child = find_thread_for_addr(child, addr);
- get_task_struct(child);
- }
- }
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
- ret = -EPERM;
- if (pid == 1) /* no messing around with init! */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- if (!ret)
- arch_ptrace_attach(child);
- goto out_tsk;
- }
+void
+user_disable_single_step (struct task_struct *child)
+{
+ struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
+ /* make sure the single step/taken-branch trap bits are not set: */
+ clear_tsk_thread_flag(child, TIF_SINGLESTEP);
+ child_psr->ss = 0;
+ child_psr->tb = 0;
+}
- pt = task_pt_regs(child);
- sw = (struct switch_stack *) (child->thread.ksp + 16);
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void
+ptrace_disable (struct task_struct *child)
+{
+ user_disable_single_step(child);
+}
+long
+arch_ptrace (struct task_struct *child, long request, long addr, long data)
+{
switch (request) {
- case PTRACE_PEEKTEXT:
- case PTRACE_PEEKDATA:
+ case PTRACE_PEEKTEXT:
+ case PTRACE_PEEKDATA:
/* read word at location addr */
- urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
- ret = ia64_peek(child, sw, urbs_end, addr, &data);
- if (ret == 0) {
- ret = data;
- /* ensure "ret" is not mistaken as an error code: */
- force_successful_syscall_return();
- }
- goto out_tsk;
-
- case PTRACE_POKETEXT:
- case PTRACE_POKEDATA:
- /* write the word at location addr */
- urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
- ret = ia64_poke(child, sw, urbs_end, addr, data);
-
- /* Make sure user RBS has the latest data */
- unw_init_from_blocked_task(&info, child);
- do_sync_rbs(&info, ia64_sync_user_rbs);
+ if (access_process_vm(child, addr, &data, sizeof(data), 0)
+ != sizeof(data))
+ return -EIO;
+ /* ensure return value is not mistaken for error code */
+ force_successful_syscall_return();
+ return data;
- goto out_tsk;
+ /* PTRACE_POKETEXT and PTRACE_POKEDATA is handled
+ * by the generic ptrace_request().
+ */
- case PTRACE_PEEKUSR:
+ case PTRACE_PEEKUSR:
/* read the word at addr in the USER area */
- if (access_uarea(child, addr, &data, 0) < 0) {
- ret = -EIO;
- goto out_tsk;
- }
- ret = data;
- /* ensure "ret" is not mistaken as an error code */
+ if (access_uarea(child, addr, &data, 0) < 0)
+ return -EIO;
+ /* ensure return value is not mistaken for error code */
force_successful_syscall_return();
- goto out_tsk;
+ return data;
- case PTRACE_POKEUSR:
+ case PTRACE_POKEUSR:
/* write the word at addr in the USER area */
- if (access_uarea(child, addr, &data, 1) < 0) {
- ret = -EIO;
- goto out_tsk;
- }
- ret = 0;
- goto out_tsk;
+ if (access_uarea(child, addr, &data, 1) < 0)
+ return -EIO;
+ return 0;
- case PTRACE_OLD_GETSIGINFO:
+ case PTRACE_OLD_GETSIGINFO:
/* for backwards-compatibility */
- ret = ptrace_request(child, PTRACE_GETSIGINFO, addr, data);
- goto out_tsk;
+ return ptrace_request(child, PTRACE_GETSIGINFO, addr, data);
- case PTRACE_OLD_SETSIGINFO:
+ case PTRACE_OLD_SETSIGINFO:
/* for backwards-compatibility */
- ret = ptrace_request(child, PTRACE_SETSIGINFO, addr, data);
- goto out_tsk;
-
- case PTRACE_SYSCALL:
- /* continue and stop at next (return from) syscall */
- case PTRACE_CONT:
- /* restart after signal. */
- ret = -EIO;
- if (!valid_signal(data))
- goto out_tsk;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
+ return ptrace_request(child, PTRACE_SETSIGINFO, addr, data);
- /*
- * Make sure the single step/taken-branch trap bits
- * are not set:
- */
- clear_tsk_thread_flag(child, TIF_SINGLESTEP);
- ia64_psr(pt)->ss = 0;
- ia64_psr(pt)->tb = 0;
+ case PTRACE_GETREGS:
+ return ptrace_getregs(child,
+ (struct pt_all_user_regs __user *) data);
- wake_up_process(child);
- ret = 0;
- goto out_tsk;
+ case PTRACE_SETREGS:
+ return ptrace_setregs(child,
+ (struct pt_all_user_regs __user *) data);
- case PTRACE_KILL:
- /*
- * Make the child exit. Best I can do is send it a
- * sigkill. Perhaps it should be put in the status
- * that it wants to exit.
- */
- if (child->exit_state == EXIT_ZOMBIE)
- /* already dead */
- goto out_tsk;
- child->exit_code = SIGKILL;
-
- ptrace_disable(child);
- wake_up_process(child);
- ret = 0;
- goto out_tsk;
-
- case PTRACE_SINGLESTEP:
- /* let child execute for one instruction */
- case PTRACE_SINGLEBLOCK:
- ret = -EIO;
- if (!valid_signal(data))
- goto out_tsk;
-
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- set_tsk_thread_flag(child, TIF_SINGLESTEP);
- if (request == PTRACE_SINGLESTEP) {
- ia64_psr(pt)->ss = 1;
- } else {
- ia64_psr(pt)->tb = 1;
- }
- child->exit_code = data;
-
- /* give it a chance to run. */
- wake_up_process(child);
- ret = 0;
- goto out_tsk;
-
- case PTRACE_DETACH:
- /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- goto out_tsk;
-
- case PTRACE_GETREGS:
- ret = ptrace_getregs(child,
- (struct pt_all_user_regs __user *) data);
- goto out_tsk;
-
- case PTRACE_SETREGS:
- ret = ptrace_setregs(child,
- (struct pt_all_user_regs __user *) data);
- goto out_tsk;
-
- default:
- ret = ptrace_request(child, request, addr, data);
- goto out_tsk;
+ default:
+ return ptrace_request(child, request, addr, data);
}
- out_tsk:
- put_task_struct(child);
- out:
- unlock_kernel();
- return ret;
}
diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c
index f44fe841216..a3022dc48ef 100644
--- a/arch/ia64/kernel/sal.c
+++ b/arch/ia64/kernel/sal.c
@@ -109,6 +109,13 @@ check_versions (struct ia64_sal_systab *systab)
sal_revision = SAL_VERSION_CODE(2, 8);
sal_version = SAL_VERSION_CODE(0, 0);
}
+
+ if (ia64_platform_is("sn2") && (sal_revision == SAL_VERSION_CODE(2, 9)))
+ /*
+ * SGI Altix has hard-coded version 2.9 in their prom
+ * but they actually implement 3.2, so let's fix it here.
+ */
+ sal_revision = SAL_VERSION_CODE(3, 2);
}
static void __init
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index ebd1a09f320..4aa9eaea76c 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -690,7 +690,7 @@ get_model_name(__u8 family, __u8 model)
if (overflow++ == 0)
printk(KERN_ERR
"%s: Table overflow. Some processor model information will be missing\n",
- __FUNCTION__);
+ __func__);
return "Unknown";
}
@@ -785,7 +785,7 @@ get_max_cacheline_size (void)
status = ia64_pal_cache_summary(&levels, &unique_caches);
if (status != 0) {
printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
- __FUNCTION__, status);
+ __func__, status);
max = SMP_CACHE_BYTES;
/* Safest setup for "flush_icache_range()" */
ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT;
@@ -798,7 +798,7 @@ get_max_cacheline_size (void)
if (status != 0) {
printk(KERN_ERR
"%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n",
- __FUNCTION__, l, status);
+ __func__, l, status);
max = SMP_CACHE_BYTES;
/* The safest setup for "flush_icache_range()" */
cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
@@ -814,7 +814,7 @@ get_max_cacheline_size (void)
if (status != 0) {
printk(KERN_ERR
"%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n",
- __FUNCTION__, l, status);
+ __func__, l, status);
/* The safest setup for "flush_icache_range()" */
cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
}
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 309da3567bc..5740296c35a 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -342,15 +342,33 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
new_sp = scr->pt.r12;
tramp_addr = (unsigned long) __kernel_sigtramp;
- if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) == 0) {
- new_sp = current->sas_ss_sp + current->sas_ss_size;
- /*
- * We need to check for the register stack being on the signal stack
- * separately, because it's switched separately (memory stack is switched
- * in the kernel, register stack is switched in the signal trampoline).
- */
- if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
- new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ int onstack = sas_ss_flags(new_sp);
+
+ if (onstack == 0) {
+ new_sp = current->sas_ss_sp + current->sas_ss_size;
+ /*
+ * We need to check for the register stack being on the
+ * signal stack separately, because it's switched
+ * separately (memory stack is switched in the kernel,
+ * register stack is switched in the signal trampoline).
+ */
+ if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
+ new_rbs = ALIGN(current->sas_ss_sp,
+ sizeof(long));
+ } else if (onstack == SS_ONSTACK) {
+ unsigned long check_sp;
+
+ /*
+ * If we are on the alternate signal stack and would
+ * overflow it, don't. Return an always-bogus address
+ * instead so we will die with SIGSEGV.
+ */
+ check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN;
+ if (!likely(on_sig_stack(check_sp)))
+ return force_sigsegv_info(sig, (void __user *)
+ check_sp);
+ }
}
frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 52f70bbc192..6903361d11a 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -28,7 +28,7 @@ extern int die_if_kernel(char *str, struct pt_regs *regs, long err);
#undef DEBUG_UNALIGNED_TRAP
#ifdef DEBUG_UNALIGNED_TRAP
-# define DPRINT(a...) do { printk("%s %u: ", __FUNCTION__, __LINE__); printk (a); } while (0)
+# define DPRINT(a...) do { printk("%s %u: ", __func__, __LINE__); printk (a); } while (0)
# define DDUMP(str,vp,len) dump(str, vp, len)
static void
@@ -674,7 +674,7 @@ emulate_load_updates (update_t type, load_store_t ld, struct pt_regs *regs, unsi
* just in case.
*/
if (ld.x6_op == 1 || ld.x6_op == 3) {
- printk(KERN_ERR "%s: register update on speculative load, error\n", __FUNCTION__);
+ printk(KERN_ERR "%s: register update on speculative load, error\n", __func__);
if (die_if_kernel("unaligned reference on speculative load with register update\n",
regs, 30))
return;
@@ -1104,7 +1104,7 @@ emulate_load_floatpair (unsigned long ifa, load_store_t ld, struct pt_regs *regs
*/
if (ld.x6_op == 1 || ld.x6_op == 3)
printk(KERN_ERR "%s: register update on speculative load pair, error\n",
- __FUNCTION__);
+ __func__);
setreg(ld.r3, ifa, 0, regs);
}
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
index c1bdb513181..67810b77d99 100644
--- a/arch/ia64/kernel/unwind.c
+++ b/arch/ia64/kernel/unwind.c
@@ -257,7 +257,7 @@ pt_regs_off (unsigned long reg)
off = unw.pt_regs_offsets[reg];
if (off < 0) {
- UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg);
+ UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __func__, reg);
off = 0;
}
return (unsigned long) off;
@@ -268,13 +268,13 @@ get_scratch_regs (struct unw_frame_info *info)
{
if (!info->pt) {
/* This should not happen with valid unwind info. */
- UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __FUNCTION__);
+ UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __func__);
if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
info->pt = (unsigned long) ((struct pt_regs *) info->psp - 1);
else
info->pt = info->sp - 16;
}
- UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __FUNCTION__, info->sp, info->pt);
+ UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __func__, info->sp, info->pt);
return (struct pt_regs *) info->pt;
}
@@ -294,7 +294,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
return 0;
}
UNW_DPRINT(0, "unwind.%s: trying to access non-existent r%u\n",
- __FUNCTION__, regnum);
+ __func__, regnum);
return -1;
}
@@ -341,7 +341,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
{
UNW_DPRINT(0, "unwind.%s: %p outside of regstk "
"[0x%lx-0x%lx)\n",
- __FUNCTION__, (void *) addr,
+ __func__, (void *) addr,
info->regstk.limit,
info->regstk.top);
return -1;
@@ -374,7 +374,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
|| (unsigned long) addr >= info->regstk.top)
{
UNW_DPRINT(0, "unwind.%s: ignoring attempt to access register outside "
- "of rbs\n", __FUNCTION__);
+ "of rbs\n", __func__);
return -1;
}
if ((unsigned long) nat_addr >= info->regstk.top)
@@ -385,7 +385,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
if (write) {
if (read_only(addr)) {
UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
- __FUNCTION__);
+ __func__);
} else {
*addr = *val;
if (*nat)
@@ -427,13 +427,13 @@ unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int
default:
UNW_DPRINT(0, "unwind.%s: trying to access non-existent b%u\n",
- __FUNCTION__, regnum);
+ __func__, regnum);
return -1;
}
if (write)
if (read_only(addr)) {
UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
- __FUNCTION__);
+ __func__);
} else
*addr = *val;
else
@@ -450,7 +450,7 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val,
if ((unsigned) (regnum - 2) >= 126) {
UNW_DPRINT(0, "unwind.%s: trying to access non-existent f%u\n",
- __FUNCTION__, regnum);
+ __func__, regnum);
return -1;
}
@@ -482,7 +482,7 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val,
if (write)
if (read_only(addr)) {
UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
- __FUNCTION__);
+ __func__);
} else
*addr = *val;
else
@@ -572,14 +572,14 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int
default:
UNW_DPRINT(0, "unwind.%s: trying to access non-existent ar%u\n",
- __FUNCTION__, regnum);
+ __func__, regnum);
return -1;
}
if (write) {
if (read_only(addr)) {
UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
- __FUNCTION__);
+ __func__);
} else
*addr = *val;
} else
@@ -600,7 +600,7 @@ unw_access_pr (struct unw_frame_info *info, unsigned long *val, int write)
if (write) {
if (read_only(addr)) {
UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
- __FUNCTION__);
+ __func__);
} else
*addr = *val;
} else
@@ -699,7 +699,7 @@ decode_abreg (unsigned char abreg, int memory)
default:
break;
}
- UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __FUNCTION__, abreg);
+ UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __func__, abreg);
return UNW_REG_LC;
}
@@ -739,7 +739,7 @@ spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim, unw_word
return;
}
}
- UNW_DPRINT(0, "unwind.%s: excess spill!\n", __FUNCTION__);
+ UNW_DPRINT(0, "unwind.%s: excess spill!\n", __func__);
}
static inline void
@@ -855,11 +855,11 @@ desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr)
{
if (abi == 3 && context == 'i') {
sr->flags |= UNW_FLAG_INTERRUPT_FRAME;
- UNW_DPRINT(3, "unwind.%s: interrupt frame\n", __FUNCTION__);
+ UNW_DPRINT(3, "unwind.%s: interrupt frame\n", __func__);
}
else
UNW_DPRINT(0, "unwind%s: ignoring unwabi(abi=0x%x,context=0x%x)\n",
- __FUNCTION__, abi, context);
+ __func__, abi, context);
}
static inline void
@@ -1347,7 +1347,7 @@ script_emit (struct unw_script *script, struct unw_insn insn)
{
if (script->count >= UNW_MAX_SCRIPT_LEN) {
UNW_DPRINT(0, "unwind.%s: script exceeds maximum size of %u instructions!\n",
- __FUNCTION__, UNW_MAX_SCRIPT_LEN);
+ __func__, UNW_MAX_SCRIPT_LEN);
return;
}
script->insn[script->count++] = insn;
@@ -1389,7 +1389,7 @@ emit_nat_info (struct unw_state_record *sr, int i, struct unw_script *script)
default:
UNW_DPRINT(0, "unwind.%s: don't know how to emit nat info for where = %u\n",
- __FUNCTION__, r->where);
+ __func__, r->where);
return;
}
insn.opc = opc;
@@ -1446,7 +1446,7 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
val = offsetof(struct pt_regs, f6) + 16*(rval - 6);
else
UNW_DPRINT(0, "unwind.%s: kernel may not touch f%lu\n",
- __FUNCTION__, rval);
+ __func__, rval);
}
break;
@@ -1474,7 +1474,7 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
default:
UNW_DPRINT(0, "unwind%s: register %u has unexpected `where' value of %u\n",
- __FUNCTION__, i, r->where);
+ __func__, i, r->where);
break;
}
insn.opc = opc;
@@ -1547,10 +1547,10 @@ build_script (struct unw_frame_info *info)
r->when = UNW_WHEN_NEVER;
sr.pr_val = info->pr;
- UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __FUNCTION__, ip);
+ UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __func__, ip);
script = script_new(ip);
if (!script) {
- UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n", __FUNCTION__);
+ UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n", __func__);
STAT(unw.stat.script.build_time += ia64_get_itc() - start);
return NULL;
}
@@ -1569,7 +1569,7 @@ build_script (struct unw_frame_info *info)
if (!e) {
/* no info, return default unwinder (leaf proc, no mem stack, no saved regs) */
UNW_DPRINT(1, "unwind.%s: no unwind info for ip=0x%lx (prev ip=0x%lx)\n",
- __FUNCTION__, ip, unw.cache[info->prev_script].ip);
+ __func__, ip, unw.cache[info->prev_script].ip);
sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
sr.curr.reg[UNW_REG_RP].when = -1;
sr.curr.reg[UNW_REG_RP].val = 0;
@@ -1618,13 +1618,13 @@ build_script (struct unw_frame_info *info)
sr.curr.reg[UNW_REG_RP].when = -1;
sr.curr.reg[UNW_REG_RP].val = sr.return_link_reg;
UNW_DPRINT(1, "unwind.%s: using default for rp at ip=0x%lx where=%d val=0x%lx\n",
- __FUNCTION__, ip, sr.curr.reg[UNW_REG_RP].where,
+ __func__, ip, sr.curr.reg[UNW_REG_RP].where,
sr.curr.reg[UNW_REG_RP].val);
}
#ifdef UNW_DEBUG
UNW_DPRINT(1, "unwind.%s: state record for func 0x%lx, t=%u:\n",
- __FUNCTION__, table->segment_base + e->start_offset, sr.when_target);
+ __func__, table->segment_base + e->start_offset, sr.when_target);
for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) {
if (r->where != UNW_WHERE_NONE || r->when != UNW_WHEN_NEVER) {
UNW_DPRINT(1, " %s <- ", unw.preg_name[r - sr.curr.reg]);
@@ -1746,7 +1746,7 @@ run_script (struct unw_script *script, struct unw_frame_info *state)
} else {
s[dst] = 0;
UNW_DPRINT(0, "unwind.%s: no state->pt, dst=%ld, val=%ld\n",
- __FUNCTION__, dst, val);
+ __func__, dst, val);
}
break;
@@ -1756,7 +1756,7 @@ run_script (struct unw_script *script, struct unw_frame_info *state)
else {
s[dst] = 0;
UNW_DPRINT(0, "unwind.%s: UNW_INSN_MOVE_CONST bad val=%ld\n",
- __FUNCTION__, val);
+ __func__, val);
}
break;
@@ -1791,7 +1791,7 @@ run_script (struct unw_script *script, struct unw_frame_info *state)
|| s[val] < TASK_SIZE)
{
UNW_DPRINT(0, "unwind.%s: rejecting bad psp=0x%lx\n",
- __FUNCTION__, s[val]);
+ __func__, s[val]);
break;
}
#endif
@@ -1825,7 +1825,7 @@ find_save_locs (struct unw_frame_info *info)
if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) {
/* don't let obviously bad addresses pollute the cache */
/* FIXME: should really be level 0 but it occurs too often. KAO */
- UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __FUNCTION__, info->ip);
+ UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __func__, info->ip);
info->rp_loc = NULL;
return -1;
}
@@ -1838,7 +1838,7 @@ find_save_locs (struct unw_frame_info *info)
spin_unlock_irqrestore(&unw.lock, flags);
UNW_DPRINT(0,
"unwind.%s: failed to locate/build unwind script for ip %lx\n",
- __FUNCTION__, info->ip);
+ __func__, info->ip);
return -1;
}
have_write_lock = 1;
@@ -1882,21 +1882,21 @@ unw_unwind (struct unw_frame_info *info)
if (!unw_valid(info, info->rp_loc)) {
/* FIXME: should really be level 0 but it occurs too often. KAO */
UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n",
- __FUNCTION__, info->ip);
+ __func__, info->ip);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
/* restore the ip */
ip = info->ip = *info->rp_loc;
if (ip < GATE_ADDR) {
- UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip);
+ UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __func__, ip);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
/* validate the previous stack frame pointer */
if (!unw_valid(info, info->pfs_loc)) {
- UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__);
+ UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __func__);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
@@ -1912,13 +1912,13 @@ unw_unwind (struct unw_frame_info *info)
num_regs = *info->cfm_loc & 0x7f; /* size of frame */
info->pfs_loc =
(unsigned long *) (info->pt + offsetof(struct pt_regs, ar_pfs));
- UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __FUNCTION__, info->pt);
+ UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __func__, info->pt);
} else
num_regs = (*info->cfm_loc >> 7) & 0x7f; /* size of locals */
info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->bsp, -num_regs);
if (info->bsp < info->regstk.limit || info->bsp > info->regstk.top) {
UNW_DPRINT(0, "unwind.%s: bsp (0x%lx) out of range [0x%lx-0x%lx]\n",
- __FUNCTION__, info->bsp, info->regstk.limit, info->regstk.top);
+ __func__, info->bsp, info->regstk.limit, info->regstk.top);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
@@ -1927,14 +1927,14 @@ unw_unwind (struct unw_frame_info *info)
info->sp = info->psp;
if (info->sp < info->memstk.top || info->sp > info->memstk.limit) {
UNW_DPRINT(0, "unwind.%s: sp (0x%lx) out of range [0x%lx-0x%lx]\n",
- __FUNCTION__, info->sp, info->memstk.top, info->memstk.limit);
+ __func__, info->sp, info->memstk.top, info->memstk.limit);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
if (info->ip == prev_ip && info->sp == prev_sp && info->bsp == prev_bsp) {
UNW_DPRINT(0, "unwind.%s: ip, sp, bsp unchanged; stopping here (ip=0x%lx)\n",
- __FUNCTION__, ip);
+ __func__, ip);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
@@ -1961,7 +1961,7 @@ unw_unwind_to_user (struct unw_frame_info *info)
if ((long)((unsigned long)info->task + IA64_STK_OFFSET - sp)
< IA64_PT_REGS_SIZE) {
UNW_DPRINT(0, "unwind.%s: ran off the top of the kernel stack\n",
- __FUNCTION__);
+ __func__);
break;
}
if (unw_is_intr_frame(info) &&
@@ -1971,13 +1971,13 @@ unw_unwind_to_user (struct unw_frame_info *info)
unw_get_rp(info, &ip);
UNW_DPRINT(0, "unwind.%s: failed to read "
"predicate register (ip=0x%lx)\n",
- __FUNCTION__, ip);
+ __func__, ip);
return -1;
}
} while (unw_unwind(info) >= 0);
unw_get_ip(info, &ip);
UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n",
- __FUNCTION__, ip);
+ __func__, ip);
return -1;
}
EXPORT_SYMBOL(unw_unwind_to_user);
@@ -2028,7 +2028,7 @@ init_frame_info (struct unw_frame_info *info, struct task_struct *t,
" pr 0x%lx\n"
" sw 0x%lx\n"
" sp 0x%lx\n",
- __FUNCTION__, (unsigned long) t, rbslimit, rbstop, stktop, stklimit,
+ __func__, (unsigned long) t, rbslimit, rbstop, stktop, stklimit,
info->pr, (unsigned long) info->sw, info->sp);
STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags));
}
@@ -2047,7 +2047,7 @@ unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct
" bsp 0x%lx\n"
" sol 0x%lx\n"
" ip 0x%lx\n",
- __FUNCTION__, info->bsp, sol, info->ip);
+ __func__, info->bsp, sol, info->ip);
find_save_locs(info);
}
@@ -2058,7 +2058,7 @@ unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t)
{
struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16);
- UNW_DPRINT(1, "unwind.%s\n", __FUNCTION__);
+ UNW_DPRINT(1, "unwind.%s\n", __func__);
unw_init_frame_info(info, t, sw);
}
EXPORT_SYMBOL(unw_init_from_blocked_task);
@@ -2088,7 +2088,7 @@ unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned lon
if (end - start <= 0) {
UNW_DPRINT(0, "unwind.%s: ignoring attempt to insert empty unwind table\n",
- __FUNCTION__);
+ __func__);
return NULL;
}
@@ -2119,14 +2119,14 @@ unw_remove_unwind_table (void *handle)
if (!handle) {
UNW_DPRINT(0, "unwind.%s: ignoring attempt to remove non-existent unwind table\n",
- __FUNCTION__);
+ __func__);
return;
}
table = handle;
if (table == &unw.kernel_table) {
UNW_DPRINT(0, "unwind.%s: sorry, freeing the kernel's unwind table is a "
- "no-can-do!\n", __FUNCTION__);
+ "no-can-do!\n", __func__);
return;
}
@@ -2139,7 +2139,7 @@ unw_remove_unwind_table (void *handle)
break;
if (!prev) {
UNW_DPRINT(0, "unwind.%s: failed to find unwind table %p\n",
- __FUNCTION__, (void *) table);
+ __func__, (void *) table);
spin_unlock_irqrestore(&unw.lock, flags);
return;
}
@@ -2185,7 +2185,7 @@ create_gate_table (void)
}
if (!punw) {
- printk("%s: failed to find gate DSO's unwind table!\n", __FUNCTION__);
+ printk("%s: failed to find gate DSO's unwind table!\n", __func__);
return 0;
}
@@ -2202,7 +2202,7 @@ create_gate_table (void)
unw.gate_table = kmalloc(size, GFP_KERNEL);
if (!unw.gate_table) {
unw.gate_table_size = 0;
- printk(KERN_ERR "%s: unable to create unwind data for gate page!\n", __FUNCTION__);
+ printk(KERN_ERR "%s: unable to create unwind data for gate page!\n", __func__);
return 0;
}
unw.gate_table_size = size;
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 3e69881648a..23088bed111 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -26,7 +26,7 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap)
if (!user_mode(regs)) {
/* kprobe_running() needs smp_processor_id() */
preempt_disable();
- if (kprobe_running() && kprobes_fault_handler(regs, trap))
+ if (kprobe_running() && kprobe_fault_handler(regs, trap))
ret = 1;
preempt_enable();
}
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 25aef6211a5..a4ca657c72c 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -714,7 +714,7 @@ int arch_add_memory(int nid, u64 start, u64 size)
if (ret)
printk("%s: Problem encountered in __add_pages() as ret=%d\n",
- __FUNCTION__, ret);
+ __func__, ret);
return ret;
}
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
index 245dc1fedc2..f5959c0c181 100644
--- a/arch/ia64/pci/fixup.c
+++ b/arch/ia64/pci/fixup.c
@@ -63,7 +63,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
pci_read_config_word(pdev, PCI_COMMAND, &config);
if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
- printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
+ dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n");
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 8fd7e825192..e282c348dcd 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -765,7 +765,7 @@ static void __init set_pci_cacheline_size(void)
status = ia64_pal_cache_summary(&levels, &unique_caches);
if (status != 0) {
printk(KERN_ERR "%s: ia64_pal_cache_summary() failed "
- "(status=%ld)\n", __FUNCTION__, status);
+ "(status=%ld)\n", __func__, status);
return;
}
@@ -773,7 +773,7 @@ static void __init set_pci_cacheline_size(void)
/* cache_type (data_or_unified)= */ 2, &cci);
if (status != 0) {
printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed "
- "(status=%ld)\n", __FUNCTION__, status);
+ "(status=%ld)\n", __func__, status);
return;
}
pci_cache_line_size = (1 << cci.pcci_line_size) / 4;
diff --git a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c
index b663168da55..0101c7924a4 100644
--- a/arch/ia64/sn/kernel/huberror.c
+++ b/arch/ia64/sn/kernel/huberror.c
@@ -37,7 +37,7 @@ static irqreturn_t hub_eint_handler(int irq, void *arg)
(u64) nasid, 0, 0, 0, 0, 0, 0);
if ((int)ret_stuff.v0)
- panic("%s: Fatal %s Error", __FUNCTION__,
+ panic("%s: Fatal %s Error", __func__,
((nasid & 1) ? "TIO" : "HUBII"));
if (!(nasid & 1)) /* Not a TIO, handle CRB errors */
@@ -48,7 +48,7 @@ static irqreturn_t hub_eint_handler(int irq, void *arg)
(u64) nasid, 0, 0, 0, 0, 0, 0);
if ((int)ret_stuff.v0)
- panic("%s: Fatal TIO Error", __FUNCTION__);
+ panic("%s: Fatal TIO Error", __func__);
} else
bte_error_handler((unsigned long)NODEPDA(nasid_to_cnodeid(nasid)));
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c
index 3c7178f5dce..6568942a95f 100644
--- a/arch/ia64/sn/kernel/io_acpi_init.c
+++ b/arch/ia64/sn/kernel/io_acpi_init.c
@@ -133,7 +133,7 @@ sn_get_bussoft_ptr(struct pci_bus *bus)
if (ACPI_FAILURE(status)) {
printk(KERN_ERR "%s: "
"acpi_get_vendor_resource() failed (0x%x) for: ",
- __FUNCTION__, status);
+ __func__, status);
acpi_ns_print_node_pathname(handle, NULL);
printk("\n");
return NULL;
@@ -145,7 +145,7 @@ sn_get_bussoft_ptr(struct pci_bus *bus)
sizeof(struct pcibus_bussoft *)) {
printk(KERN_ERR
"%s: Invalid vendor data length %d\n",
- __FUNCTION__, vendor->byte_length);
+ __func__, vendor->byte_length);
kfree(buffer.pointer);
return NULL;
}
@@ -184,7 +184,7 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info,
if (ACPI_FAILURE(status)) {
printk(KERN_ERR
"%s: acpi_get_vendor_resource() failed (0x%x) for: ",
- __FUNCTION__, status);
+ __func__, status);
acpi_ns_print_node_pathname(handle, NULL);
printk("\n");
return 1;
@@ -196,7 +196,7 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info,
sizeof(struct pci_devdev_info *)) {
printk(KERN_ERR
"%s: Invalid vendor data length: %d for: ",
- __FUNCTION__, vendor->byte_length);
+ __func__, vendor->byte_length);
acpi_ns_print_node_pathname(handle, NULL);
printk("\n");
ret = 1;
@@ -205,7 +205,7 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info,
pcidev_ptr = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
if (!pcidev_ptr)
- panic("%s: Unable to alloc memory for pcidev_info", __FUNCTION__);
+ panic("%s: Unable to alloc memory for pcidev_info", __func__);
memcpy(&addr, vendor->byte_data, sizeof(struct pcidev_info *));
pcidev_prom_ptr = __va(addr);
@@ -214,7 +214,7 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info,
/* Get the IRQ info */
irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
if (!irq_info)
- panic("%s: Unable to alloc memory for sn_irq_info", __FUNCTION__);
+ panic("%s: Unable to alloc memory for sn_irq_info", __func__);
if (pcidev_ptr->pdi_sn_irq_info) {
irq_info_prom = __va(pcidev_ptr->pdi_sn_irq_info);
@@ -249,10 +249,10 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle)
status = acpi_get_parent(child, &parent);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR "%s: acpi_get_parent() failed "
- "(0x%x) for: ", __FUNCTION__, status);
+ "(0x%x) for: ", __func__, status);
acpi_ns_print_node_pathname(child, NULL);
printk("\n");
- panic("%s: Unable to find host devfn\n", __FUNCTION__);
+ panic("%s: Unable to find host devfn\n", __func__);
}
if (parent == rootbus_handle)
break;
@@ -260,7 +260,7 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle)
}
if (!child) {
printk(KERN_ERR "%s: Unable to find root bus for: ",
- __FUNCTION__);
+ __func__);
acpi_ns_print_node_pathname(device_handle, NULL);
printk("\n");
BUG();
@@ -269,10 +269,10 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle)
status = acpi_evaluate_integer(child, METHOD_NAME__ADR, NULL, &adr);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR "%s: Unable to get _ADR (0x%x) for: ",
- __FUNCTION__, status);
+ __func__, status);
acpi_ns_print_node_pathname(child, NULL);
printk("\n");
- panic("%s: Unable to find host devfn\n", __FUNCTION__);
+ panic("%s: Unable to find host devfn\n", __func__);
}
slot = (adr >> 16) & 0xffff;
@@ -308,7 +308,7 @@ find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv)
if (ACPI_FAILURE(status)) {
printk(KERN_ERR
"%s: acpi_get_parent() failed (0x%x) for: ",
- __FUNCTION__, status);
+ __func__, status);
acpi_ns_print_node_pathname(handle, NULL);
printk("\n");
return AE_OK;
@@ -318,7 +318,7 @@ find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv)
if (ACPI_FAILURE(status)) {
printk(KERN_ERR
"%s: Failed to find _BBN in parent of: ",
- __FUNCTION__);
+ __func__);
acpi_ns_print_node_pathname(handle, NULL);
printk("\n");
return AE_OK;
@@ -358,14 +358,14 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info,
if (segment != pci_domain_nr(dev)) {
printk(KERN_ERR
"%s: Segment number mismatch, 0x%lx vs 0x%x for: ",
- __FUNCTION__, segment, pci_domain_nr(dev));
+ __func__, segment, pci_domain_nr(dev));
acpi_ns_print_node_pathname(rootbus_handle, NULL);
printk("\n");
return 1;
}
} else {
printk(KERN_ERR "%s: Unable to get __SEG from: ",
- __FUNCTION__);
+ __func__);
acpi_ns_print_node_pathname(rootbus_handle, NULL);
printk("\n");
return 1;
@@ -386,7 +386,7 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info,
if (!pcidev_match.handle) {
printk(KERN_ERR
"%s: Could not find matching ACPI device for %s.\n",
- __FUNCTION__, pci_name(dev));
+ __func__, pci_name(dev));
return 1;
}
@@ -422,7 +422,7 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) {
panic("%s: Failure obtaining pcidev_info for %s\n",
- __FUNCTION__, pci_name(dev));
+ __func__, pci_name(dev));
}
if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) {
@@ -463,7 +463,7 @@ sn_acpi_bus_fixup(struct pci_bus *bus)
printk(KERN_ERR
"%s: 0x%04x:0x%02x Unable to "
"obtain prom_bussoft_ptr\n",
- __FUNCTION__, pci_domain_nr(bus), bus->number);
+ __func__, pci_domain_nr(bus), bus->number);
return;
}
sn_common_bus_fixup(bus, prom_bussoft_ptr);
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c
index c4eb84f9e78..8a924a5661d 100644
--- a/arch/ia64/sn/kernel/io_common.c
+++ b/arch/ia64/sn/kernel/io_common.c
@@ -364,7 +364,7 @@ void sn_bus_store_sysdata(struct pci_dev *dev)
element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL);
if (!element) {
- dev_dbg(&dev->dev, "%s: out of memory!\n", __FUNCTION__);
+ dev_dbg(&dev->dev, "%s: out of memory!\n", __func__);
return;
}
element->sysdata = SN_PCIDEV_INFO(dev);
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 906b93674b7..c3aa851d1ca 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -209,11 +209,11 @@ sn_io_slot_fixup(struct pci_dev *dev)
pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
if (!pcidev_info)
- panic("%s: Unable to alloc memory for pcidev_info", __FUNCTION__);
+ panic("%s: Unable to alloc memory for pcidev_info", __func__);
sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
if (!sn_irq_info)
- panic("%s: Unable to alloc memory for sn_irq_info", __FUNCTION__);
+ panic("%s: Unable to alloc memory for sn_irq_info", __func__);
/* Call to retrieve pci device information needed by kernel. */
status = sal_get_pcidev_info((u64) pci_domain_nr(dev),
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c
index 868c9aa64fe..27793f7aa99 100644
--- a/arch/ia64/sn/kernel/mca.c
+++ b/arch/ia64/sn/kernel/mca.c
@@ -100,7 +100,7 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
if (!newbuf) {
mutex_unlock(&sn_oemdata_mutex);
printk(KERN_ERR "%s: unable to extend sn_oemdata\n",
- __FUNCTION__);
+ __func__);
return 1;
}
vfree(*sn_oemdata);
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 511db2fd7bf..18b94b792d5 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -116,7 +116,7 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size,
*dma_handle = provider->dma_map_consistent(pdev, phys_addr, size,
SN_DMA_ADDR_PHYS);
if (!*dma_handle) {
- printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
+ printk(KERN_ERR "%s: out of ATEs\n", __func__);
free_pages((unsigned long)cpuaddr, get_order(size));
return NULL;
}
@@ -179,7 +179,7 @@ dma_addr_t sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size,
phys_addr = __pa(cpu_addr);
dma_addr = provider->dma_map(pdev, phys_addr, size, SN_DMA_ADDR_PHYS);
if (!dma_addr) {
- printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
+ printk(KERN_ERR "%s: out of ATEs\n", __func__);
return 0;
}
return dma_addr;
@@ -266,7 +266,7 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries,
SN_DMA_ADDR_PHYS);
if (!sg->dma_address) {
- printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
+ printk(KERN_ERR "%s: out of ATEs\n", __func__);
/*
* Free any successfully allocated entries.
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index ef048a67477..529462c0157 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -88,7 +88,7 @@ tioca_gart_init(struct tioca_kernel *tioca_kern)
break;
default:
printk(KERN_ERR "%s: Invalid CA_APERATURE_SIZE "
- "0x%lx\n", __FUNCTION__, (ulong) CA_APERATURE_SIZE);
+ "0x%lx\n", __func__, (ulong) CA_APERATURE_SIZE);
return -1;
}
@@ -124,7 +124,7 @@ tioca_gart_init(struct tioca_kernel *tioca_kern)
if (!tmp) {
printk(KERN_ERR "%s: Could not allocate "
"%lu bytes (order %d) for GART\n",
- __FUNCTION__,
+ __func__,
tioca_kern->ca_gart_size,
get_order(tioca_kern->ca_gart_size));
return -ENOMEM;
@@ -341,7 +341,7 @@ tioca_dma_d48(struct pci_dev *pdev, u64 paddr)
if (node_upper > 64) {
printk(KERN_ERR "%s: coretalk addr 0x%p node id out "
- "of range\n", __FUNCTION__, (void *)ct_addr);
+ "of range\n", __func__, (void *)ct_addr);
return 0;
}
@@ -349,7 +349,7 @@ tioca_dma_d48(struct pci_dev *pdev, u64 paddr)
if (node_upper != (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)) {
printk(KERN_ERR "%s: coretalk upper node (%u) "
"mismatch with ca_agp_dma_addr_extn (%lu)\n",
- __FUNCTION__,
+ __func__,
node_upper, (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT));
return 0;
}
@@ -597,7 +597,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
if (is_shub1() && sn_sal_rev() < 0x0406) {
printk
(KERN_ERR "%s: SGI prom rev 4.06 or greater required "
- "for tioca support\n", __FUNCTION__);
+ "for tioca support\n", __func__);
return NULL;
}
@@ -651,7 +651,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
printk(KERN_WARNING
"%s: Unable to get irq %d. "
"Error interrupts won't be routed for TIOCA bus %d\n",
- __FUNCTION__, SGI_TIOCA_ERROR,
+ __func__, SGI_TIOCA_ERROR,
(int)tioca_common->ca_common.bs_persist_busnum);
sn_set_err_irq_affinity(SGI_TIOCA_ERROR);
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c
index 999f14f986e..9b3c1137302 100644
--- a/arch/ia64/sn/pci/tioce_provider.c
+++ b/arch/ia64/sn/pci/tioce_provider.c
@@ -494,7 +494,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
if (&map->ce_dmamap_list == &ce_kern->ce_dmamap_list) {
printk(KERN_WARNING
"%s: %s - no map found for bus_addr 0x%lx\n",
- __FUNCTION__, pci_name(pdev), bus_addr);
+ __func__, pci_name(pdev), bus_addr);
} else if (--map->refcnt == 0) {
for (i = 0; i < map->ate_count; i++) {
map->ate_shadow[i] = 0;
@@ -1030,7 +1030,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
"%s: Unable to get irq %d. "
"Error interrupts won't be routed for "
"TIOCE bus %04x:%02x\n",
- __FUNCTION__, SGI_PCIASIC_ERROR,
+ __func__, SGI_PCIASIC_ERROR,
tioce_common->ce_pcibus.bs_persist_segment,
tioce_common->ce_pcibus.bs_persist_busnum);
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 6dfa3b3c0e2..18a9c5f4b00 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -742,7 +742,9 @@ sys_call_table:
.long sys_epoll_pwait /* 315 */
.long sys_utimensat
.long sys_signalfd
- .long sys_ni_syscall
+ .long sys_timerfd_create
.long sys_eventfd
.long sys_fallocate /* 320 */
+ .long sys_timerfd_settime
+ .long sys_timerfd_gettime
diff --git a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig
index 648113075f9..670b0a99cfa 100644
--- a/arch/m68knommu/defconfig
+++ b/arch/m68knommu/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23
-# Thu Oct 18 13:17:38 2007
+# Linux kernel version: 2.6.25-rc3
+# Mon Feb 25 15:03:00 2008
#
CONFIG_M68K=y
# CONFIG_MMU is not set
@@ -15,8 +15,10 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
CONFIG_TIME_LOW_RES=y
CONFIG_NO_IOPORT=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -31,12 +33,14 @@ CONFIG_LOCALVERSION_AUTO=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_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
@@ -48,15 +52,22 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
# CONFIG_VM_EVENT_COUNTERS is not set
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 is not set
+# CONFIG_HAVE_KPROBES is not set
+CONFIG_SLABINFO=y
CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
@@ -83,6 +94,8 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
#
# Processor type and features
@@ -121,6 +134,7 @@ CONFIG_M5272C3=y
# CONFIG_MOD5272 is not set
CONFIG_FREESCALE=y
CONFIG_4KSTACKS=y
+CONFIG_HZ=100
#
# RAM configuration
@@ -147,6 +161,7 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=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_ZONE_DMA_FLAG=1
@@ -159,10 +174,6 @@ CONFIG_VIRT_TO_BUS=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
#
-# PCCARD (PCMCIA/CardBus) support
-#
-
-#
# Executable file formats
#
CONFIG_BINFMT_FLAT=y
@@ -205,6 +216,7 @@ CONFIG_IP_FIB_HASH=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
@@ -229,10 +241,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
# CONFIG_NET_SCHED is not set
#
@@ -240,6 +248,7 @@ 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
@@ -283,6 +292,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
@@ -339,10 +349,11 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -360,9 +371,15 @@ CONFIG_NETDEVICES=y
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
+# CONFIG_VETH is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
# CONFIG_MII 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_B44 is not set
CONFIG_FEC=y
# CONFIG_FEC2 is not set
# CONFIG_NETDEV_1000 is not set
@@ -377,7 +394,7 @@ CONFIG_FEC=y
CONFIG_PPP=y
# CONFIG_PPP_MULTILINK is not set
# CONFIG_PPP_FILTER is not set
-# CONFIG_PPP_ASYNC is not set
+CONFIG_PPP_ASYNC=y
# CONFIG_PPP_SYNC_TTY is not set
# CONFIG_PPP_DEFLATE is not set
# CONFIG_PPP_BSDCOMP is not set
@@ -386,7 +403,6 @@ CONFIG_PPP=y
# CONFIG_PPPOL2TP is not set
# CONFIG_SLIP is not set
CONFIG_SLHC=y
-# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
@@ -418,12 +434,16 @@ CONFIG_SLHC=y
#
# Non-8250 serial port support
#
-CONFIG_SERIAL_COLDFIRE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_COLDFIRE is not set
+CONFIG_SERIAL_MCF=y
+CONFIG_SERIAL_MCF_BAUDRATE=19200
+CONFIG_SERIAL_MCF_CONSOLE=y
# CONFIG_UNIX98_PTYS is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
@@ -439,6 +459,14 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -450,20 +478,20 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
#
# Graphics support
#
+# 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
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-# CONFIG_FB is not set
#
# Sound
@@ -471,23 +499,11 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_SOUND is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_RTC_CLASS is not set
#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
# Userspace I/O
#
# CONFIG_UIO is not set
@@ -505,11 +521,9 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
+# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# 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
@@ -535,7 +549,6 @@ CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
#
@@ -551,42 +564,27 @@ CONFIG_RAMFS=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_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_NFS_FS is not set
-# CONFIG_NFSD is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
# CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
# CONFIG_DLM is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
# CONFIG_ENABLE_MUST_CHECK is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
@@ -594,6 +592,7 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_SAMPLES is not set
# CONFIG_FULLDEBUG is not set
# CONFIG_HIGHPROFILE is not set
# CONFIG_BOOTPARAM is not set
@@ -605,6 +604,7 @@ CONFIG_MSDOS_PARTITION=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
#
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
index 1b02b882006..fca2e49917a 100644
--- a/arch/m68knommu/kernel/syscalltable.S
+++ b/arch/m68knommu/kernel/syscalltable.S
@@ -336,9 +336,11 @@ ENTRY(sys_call_table)
.long sys_epoll_pwait /* 315 */
.long sys_utimensat
.long sys_signalfd
- .long sys_ni_syscall
+ .long sys_timerfd_create
.long sys_eventfd
.long sys_fallocate /* 320 */
+ .long sys_timerfd_settime
+ .long sys_timerfd_gettime
.rept NR_syscalls-(.-sys_call_table)/4
.long sys_ni_syscall
diff --git a/arch/m68knommu/platform/68328/timers.c b/arch/m68knommu/platform/68328/timers.c
index 9159fd05c9a..6bafefa546e 100644
--- a/arch/m68knommu/platform/68328/timers.c
+++ b/arch/m68knommu/platform/68328/timers.c
@@ -67,16 +67,6 @@ static irqreturn_t hw_tick(int irq, void *dummy)
/***************************************************************************/
-static irqreturn_t hw_tick(int irq, void *dummy)
-{
- /* Reset Timer1 */
- TSTAT &= 0;
-
- return arch_timer_interrupt(irq, dummy);
-}
-
-/***************************************************************************/
-
static struct irqaction m68328_timer_irq = {
.name = "timer",
.flags = IRQF_DISABLED | IRQF_TIMER,
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 1b6b0fa5028..8d36f186890 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -92,17 +92,17 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
iv->sprom.revision = 3;
if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
- str2eaddr(buf, iv->sprom.r1.et0mac);
+ str2eaddr(buf, iv->sprom.et0mac);
if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
- str2eaddr(buf, iv->sprom.r1.et1mac);
+ str2eaddr(buf, iv->sprom.et1mac);
if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
- iv->sprom.r1.et0phyaddr = simple_strtoul(buf, NULL, 10);
+ iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 10);
if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
- iv->sprom.r1.et1phyaddr = simple_strtoul(buf, NULL, 10);
+ iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 10);
if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
- iv->sprom.r1.et0mdcport = simple_strtoul(buf, NULL, 10);
+ iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
- iv->sprom.r1.et1mdcport = simple_strtoul(buf, NULL, 10);
+ iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
return 0;
}
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c
index 5a017eaee71..d1d90c9ef2f 100644
--- a/arch/mips/bcm47xx/wgt634u.c
+++ b/arch/mips/bcm47xx/wgt634u.c
@@ -9,6 +9,7 @@
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/leds.h>
+#include <linux/mtd/physmap.h>
#include <linux/ssb/ssb.h>
#include <asm/mach-bcm47xx/bcm47xx.h>
@@ -43,6 +44,61 @@ static struct platform_device wgt634u_gpio_leds = {
}
};
+
+/* 8MiB flash. The struct mtd_partition matches original Netgear WGT634U
+ firmware. */
+static struct mtd_partition wgt634u_partitions[] = {
+ {
+ .name = "cfe",
+ .offset = 0,
+ .size = 0x60000, /* 384k */
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "config",
+ .offset = 0x60000,
+ .size = 0x20000 /* 128k */
+ },
+ {
+ .name = "linux",
+ .offset = 0x80000,
+ .size = 0x140000 /* 1280k */
+ },
+ {
+ .name = "jffs",
+ .offset = 0x1c0000,
+ .size = 0x620000 /* 6272k */
+ },
+ {
+ .name = "nvram",
+ .offset = 0x7e0000,
+ .size = 0x20000 /* 128k */
+ },
+};
+
+static struct physmap_flash_data wgt634u_flash_data = {
+ .parts = wgt634u_partitions,
+ .nr_parts = ARRAY_SIZE(wgt634u_partitions)
+};
+
+static struct resource wgt634u_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device wgt634u_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = { .platform_data = &wgt634u_flash_data, },
+ .resource = &wgt634u_flash_resource,
+ .num_resources = 1,
+};
+
+/* Platform devices */
+static struct platform_device *wgt634u_devices[] __initdata = {
+ &wgt634u_flash,
+ &wgt634u_gpio_leds,
+};
+
static int __init wgt634u_init(void)
{
/* There is no easy way to detect that we are running on a WGT634U
@@ -50,13 +106,20 @@ static int __init wgt634u_init(void)
* been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
*/
- u8 *et0mac = ssb_bcm47xx.sprom.r1.et0mac;
+ u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
if (et0mac[0] == 0x00 &&
((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
- (et0mac[1] == 0x0f && et0mac[2] == 0xb5)))
- return platform_device_register(&wgt634u_gpio_leds);
- else
+ (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
+ struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+ wgt634u_flash_data.width = mcore->flash_buswidth;
+ wgt634u_flash_resource.start = mcore->flash_window;
+ wgt634u_flash_resource.end = mcore->flash_window
+ + mcore->flash_window_size
+ - 1;
+ return platform_add_devices(wgt634u_devices,
+ ARRAY_SIZE(wgt634u_devices));
+ } else
return -ENODEV;
}
diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig
new file mode 100644
index 00000000000..c0e42e74dfb
--- /dev/null
+++ b/arch/mips/configs/bcm47xx_defconfig
@@ -0,0 +1,1939 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.25-rc2
+# Mon Feb 18 11:55:24 2008
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_BASLER_EXCITE is not set
+CONFIG_BCM47XX=y
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_WR_PPMC is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_CEVT_R4K=y
+CONFIG_CSRC_R4K=y
+CONFIG_CFE=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
+CONFIG_KEXEC=y
+# CONFIG_SECCOMP is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_NS=y
+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=y
+# CONFIG_RESOURCE_COUNTERS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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_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_KPROBES is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_LRO=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_DEFAULT_BIC=y
+# CONFIG_DEFAULT_CUBIC is not set
+# CONFIG_DEFAULT_HTCP is not set
+# CONFIG_DEFAULT_VEGAS is not set
+# CONFIG_DEFAULT_WESTWOOD is not set
+# CONFIG_DEFAULT_RENO is not set
+CONFIG_DEFAULT_TCP_CONG="bic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=m
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+CONFIG_IP_DCCP_TFRC_LIB=m
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+CONFIG_TIPC=m
+CONFIG_TIPC_ADVANCED=y
+CONFIG_TIPC_ZONES=3
+CONFIG_TIPC_CLUSTERS=1
+CONFIG_TIPC_NODES=255
+CONFIG_TIPC_SLAVE_NODES=0
+CONFIG_TIPC_PORTS=8191
+CONFIG_TIPC_LOG=0
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# 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=y
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RR=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_FLOW is not set
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_SCH_FIFO=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+CONFIG_KINGSUN_DONGLE=m
+CONFIG_KSDAZZLE_DONGLE=m
+CONFIG_KS959_DONGLE=m
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+# CONFIG_BT_L2CAP is not set
+# CONFIG_BT_SCO is not set
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+
+#
+# Wireless
+#
+CONFIG_CFG80211=m
+CONFIG_NL80211=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_MAC80211=m
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
+# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
+
+#
+# Selecting 'y' for an algorithm will
+#
+
+#
+# build the algorithm into mac80211.
+#
+CONFIG_MAC80211_RC_DEFAULT="pid"
+CONFIG_MAC80211_RC_PID=y
+# CONFIG_MAC80211_RC_SIMPLE is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
+# CONFIG_MAC80211_DEBUG is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+CONFIG_RFKILL=m
+CONFIG_RFKILL_INPUT=m
+CONFIG_RFKILL_LEDS=y
+CONFIG_NET_9P=m
+CONFIG_NET_9P_FD=m
+# CONFIG_NET_9P_DEBUG 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=m
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_ABSENT=y
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+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=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_ATA_OVER_ETH=m
+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_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_NETLINK is not set
+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=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+CONFIG_ISCSI_TCP=m
+# 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_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_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# 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_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_IFB is not set
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_ICPLUS_PHY=m
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
+# CONFIG_NET_TULIP 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_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+CONFIG_B44=y
+CONFIG_B44_PCI_AUTOSELECT=y
+CONFIG_B44_PCICORE_AUTOSELECT=y
+CONFIG_B44_PCI=y
+# CONFIG_FORCEDETH is not set
+# CONFIG_TC35815 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# 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_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8180 is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_ADM8211 is not set
+# CONFIG_P54_COMMON is not set
+CONFIG_ATH5K=m
+# CONFIG_IWL4965 is not set
+# CONFIG_IWL3945 is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_BCM43XX is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+# CONFIG_RT2X00 is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_WAN is not set
+CONFIG_ATM_DRIVERS=y
+CONFIG_ATM_DUMMY=m
+CONFIG_ATM_TCP=m
+# CONFIG_ATM_LANAI is not set
+# CONFIG_ATM_ENI is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+# CONFIG_ATM_NICSTAR is not set
+# CONFIG_ATM_IDT77252 is not set
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+# CONFIG_ATM_IA is not set
+# CONFIG_ATM_FORE200E_MAYBE is not set
+# CONFIG_ATM_HE is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+# CONFIG_PPPOL2TP is not set
+CONFIG_SLIP=m
+# CONFIG_SLIP_COMPRESSED is not set
+CONFIG_SLHC=m
+# CONFIG_SLIP_SMART is not set
+# CONFIG_SLIP_MODE_SLIP6 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=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE 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 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED 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_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+# CONFIG_W1_MASTER_GPIO is not set
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+# CONFIG_W1_SLAVE_DS2433_CRC is not set
+CONFIG_W1_SLAVE_DS2760=m
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+CONFIG_SSB=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_SERIAL=y
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+CONFIG_SSB_DRIVER_PCICORE=y
+CONFIG_SSB_PCICORE_HOSTMODE=y
+CONFIG_SSB_DRIVER_MIPS=y
+CONFIG_SSB_DRIVER_EXTIF=y
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_DRM 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=m
+
+#
+# Display hardware drivers
+#
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# PCI devices
+#
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_OXYGEN is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_HIFIER is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VIRTUOSO is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+
+#
+# ALSA MIPS devices
+#
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE 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 is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_SSB is not set
+# 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 is not set
+CONFIG_USB_U132_HCD=m
+# CONFIG_USB_SL811_HCD is not set
+CONFIG_USB_R8A66597_HCD=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+# CONFIG_USB_STORAGE_ISD200 is not set
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_EZUSB=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRCABLE=m
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_CH341=m
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+# CONFIG_USB_SERIAL_IUU is not set
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_MOS7720=m
+CONFIG_USB_SERIAL_MOS7840=m
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OTI6858=m
+CONFIG_USB_SERIAL_HP4X=m
+CONFIG_USB_SERIAL_SAFE=m
+# CONFIG_USB_SERIAL_SAFE_PADDED is not set
+CONFIG_USB_SERIAL_SIERRAWIRELESS=m
+# CONFIG_USB_SERIAL_TI is not set
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_DEBUG=m
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_BERRY_CHARGE=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+# CONFIG_USB_APPLEDISPLAY is not set
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_IOWARRIOR=m
+CONFIG_USB_TEST=m
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+CONFIG_USB_GADGET_NET2280=y
+CONFIG_USB_NET2280=m
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_MIDI_GADGET=m
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO 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_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# 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=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_NOLOCK=m
+CONFIG_GFS2_FS_LOCKING_DLM=m
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+CONFIG_ADFS_FS=m
+# CONFIG_ADFS_FS_RW is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_SUNRPC_BIND34=y
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+# CONFIG_NCPFS_SMALLDOS is not set
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# 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 is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_KARMA_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+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=m
+CONFIG_NLS_ISO8859_1=m
+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=m
+CONFIG_DLM_DEBUG=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# 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 is not set
+# CONFIG_SAMPLES is not set
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=m
+# CONFIG_CRYPTO_SEQIV is not set
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_XTS=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_SEED=m
+# CONFIG_CRYPTO_SALSA20 is not set
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig
new file mode 100644
index 00000000000..ec188be9a67
--- /dev/null
+++ b/arch/mips/configs/ip28_defconfig
@@ -0,0 +1,891 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.25-rc1
+# Mon Feb 11 15:58:54 2008
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+CONFIG_SGI_IP28=y
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_WR_PPMC is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_ARC=y
+CONFIG_CEVT_R4K=y
+CONFIG_CSRC_R4K=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_I8259=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
+CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_SGI_HAS_DS1286=y
+CONFIG_SGI_HAS_INDYDOG=y
+CONFIG_SGI_HAS_SEEQ=y
+CONFIG_SGI_HAS_WD93=y
+CONFIG_SGI_HAS_ZILOG=y
+CONFIG_SGI_HAS_I8042=y
+CONFIG_DEFAULT_SGI_PARTITION=y
+CONFIG_MIPS_L1_CACHE_SHIFT=7
+CONFIG_ARC_CONSOLE=y
+CONFIG_ARC_PROMLIB=y
+CONFIG_ARC64=y
+CONFIG_BOOT_ELF64=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+CONFIG_CPU_R10000=y
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R10000=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_MIPS_INSANE_LARGE is not set
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=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 is not set
+# 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=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+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_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_KPROBES is not set
+# CONFIG_PROC_PAGE_MONITOR 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_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLOCK_COMPAT=y
+
+#
+# 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_PREEMPT_RCU is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_EISA=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_ISA=y
+CONFIG_EISA=y
+CONFIG_EISA_NAMES=y
+CONFIG_MMU=y
+CONFIG_I8253=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# 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=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL 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_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
+
+#
+# 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
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+# CONFIG_PNP is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# 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 is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# 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=y
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# 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_SGIWD93_SCSI=y
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+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_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_AX88796 is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_DM9000 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA 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_NET_PCI is not set
+# CONFIG_B44 is not set
+CONFIG_SGISEEQ=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# 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 is not set
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+# CONFIG_MOUSE_PS2_SYNAPTICS is not set
+# CONFIG_MOUSE_PS2_LIFEBOOK is not set
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD 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=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_IP22_ZILOG=y
+CONFIG_SERIAL_IP22_ZILOG_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+CONFIG_SGI_DS1286=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_INDYDOG=y
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# 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 is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# 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_EXT4DEV_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# 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_VXFS_FS is not set
+# CONFIG_MINIX_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=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS 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 is not set
+# CONFIG_SYSV68_PARTITION is not set
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+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 is not set
+# CONFIG_SAMPLES is not set
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+# CONFIG_CRYPTO_SEQIV is not set
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# 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
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
deleted file mode 100644
index 72ca147f942..00000000000
--- a/arch/mips/configs/qemu_defconfig
+++ /dev/null
@@ -1,800 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:39 2007
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_DMA_COHERENT=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_I8259=y
-CONFIG_CPU_BIG_ENDIAN=y
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_HAVE_STD_PC_SERIAL_PORT=y
-
-#
-# CPU selection
-#
-CONFIG_CPU_MIPS32_R1=y
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_CPU_MIPS32=y
-CONFIG_CPU_MIPSR1=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_SPARSEMEM_STATIC=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-# CONFIG_HZ_48 is not set
-CONFIG_HZ_100=y
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-# CONFIG_HZ_1000 is not set
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=100
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-# CONFIG_SWAP is not set
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_PRINTK=y
-# CONFIG_BUG is not set
-CONFIG_ELF_CORE=y
-# CONFIG_BASE_FULL is not set
-# CONFIG_FUTEX is not set
-# CONFIG_EPOLL is not set
-# CONFIG_SHMEM is not set
-CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_TINY_SHMEM=y
-CONFIG_BASE_SMALL=1
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-CONFIG_DEFAULT_NOOP=y
-CONFIG_DEFAULT_IOSCHED="noop"
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_ISA=y
-CONFIG_MMU=y
-CONFIG_PCSPEAKER=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
-
-#
-# Power management options
-#
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER 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=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_SYN_COOKIES is not set
-# 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_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_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
-# CONFIG_NETFILTER is not set
-# CONFIG_BRIDGE 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
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=y
-CONFIG_PROC_EVENTS=y
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
-# CONFIG_ATA is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_DM9000 is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_ISA=y
-# CONFIG_E2100 is not set
-# CONFIG_EWRK3 is not set
-# CONFIG_EEXPRESS is not set
-# CONFIG_EEXPRESS_PRO is not set
-# CONFIG_HPLAN_PLUS is not set
-# CONFIG_HPLAN is not set
-# CONFIG_LP486E is not set
-# CONFIG_ETH16I is not set
-CONFIG_NE2000=y
-# CONFIG_NET_PCI is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS 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=y
-CONFIG_GENERIC_ACL=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-CONFIG_NFS_DIRECTIO=y
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Kernel hacking
-#
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
index 971adf6ef4f..fb50cc78b28 100644
--- a/arch/mips/kernel/irq-rm7000.c
+++ b/arch/mips/kernel/irq-rm7000.c
@@ -33,6 +33,7 @@ static struct irq_chip rm7k_irq_controller = {
.mask = mask_rm7k_irq,
.mask_ack = mask_rm7k_irq,
.unmask = unmask_rm7k_irq,
+ .eoi = unmask_rm7k_irq
};
void __init rm7k_cpu_irq_init(void)
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
index 7b04583bd80..ed9febe63d7 100644
--- a/arch/mips/kernel/irq-rm9000.c
+++ b/arch/mips/kernel/irq-rm9000.c
@@ -75,6 +75,7 @@ static struct irq_chip rm9k_irq_controller = {
.mask = mask_rm9k_irq,
.mask_ack = mask_rm9k_irq,
.unmask = unmask_rm9k_irq,
+ .eoi = unmask_rm9k_irq
};
static struct irq_chip rm9k_perfcounter_irq = {
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
index bb4f00c0cbe..df4d3f2f740 100644
--- a/arch/mips/kernel/mips-mt-fpaff.c
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -36,7 +36,7 @@ unsigned long mt_fpemul_threshold = 0;
*/
static inline struct task_struct *find_process_by_pid(pid_t pid)
{
- return pid ? find_task_by_pid(pid) : current;
+ return pid ? find_task_by_vpid(pid) : current;
}
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index f798139e888..08a9c5070ea 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -663,6 +663,9 @@ einval: li v0, -EINVAL
sys sys_ni_syscall 0
sys sys_eventfd 1
sys sys_fallocate 6 /* 4320 */
+ sys sys_timerfd_create 2
+ sys sys_timerfd_gettime 2
+ sys sys_timerfd_settime 4
.endm
/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index a626be6baea..dc597b600c6 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -478,4 +478,7 @@ sys_call_table:
PTR sys_ni_syscall
PTR sys_eventfd
PTR sys_fallocate
+ PTR sys_timerfd_create /* 5280 */
+ PTR sys_timerfd_gettime
+ PTR sys_timerfd_settime
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 9d5bcaf1b38..12940eca789 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -404,4 +404,7 @@ EXPORT(sysn32_call_table)
PTR sys_ni_syscall
PTR sys_eventfd
PTR sys_fallocate
+ PTR sys_timerfd_create
+ PTR sys_timerfd_gettime /* 5285 */
+ PTR sys_timerfd_settime
.size sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index fd2019c1ec2..9a275efb4f0 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -526,4 +526,7 @@ sys_call_table:
PTR sys_ni_syscall
PTR sys_eventfd
PTR sys32_fallocate /* 4320 */
+ PTR sys_timerfd_create
+ PTR sys_timerfd_gettime
+ PTR sys_timerfd_settime
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 672fba84b2c..c357762b801 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -111,7 +111,7 @@ asmlinkage int irix_prctl(unsigned option, ...)
printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",
current->comm, current->pid);
read_lock(&tasklist_lock);
- task = find_task_by_pid(va_arg(args, pid_t));
+ task = find_task_by_vpid(va_arg(args, pid_t));
error = -ESRCH;
if (error)
error = (task->run_list.next != NULL);
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 53ec05267a9..2c4f7e11f0d 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -364,20 +364,23 @@ static inline int has_valid_asid(const struct mm_struct *mm)
static inline void local_r4k_flush_cache_range(void * args)
{
struct vm_area_struct *vma = args;
+ int exec = vma->vm_flags & VM_EXEC;
if (!(has_valid_asid(vma->vm_mm)))
return;
r4k_blast_dcache();
+ if (exec)
+ r4k_blast_icache();
}
static void r4k_flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
- if (!cpu_has_dc_aliases)
- return;
+ int exec = vma->vm_flags & VM_EXEC;
- r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1);
+ if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
+ r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1);
}
static inline void local_r4k_flush_cache_mm(void * args)
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 81f30ac2bff..6a24651971d 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -92,12 +92,17 @@ EXPORT_SYMBOL(__flush_dcache_page);
void __flush_anon_page(struct page *page, unsigned long vmaddr)
{
- if (pages_do_alias((unsigned long)page_address(page), vmaddr)) {
- void *kaddr;
+ unsigned long addr = (unsigned long) page_address(page);
- kaddr = kmap_coherent(page, vmaddr);
- flush_data_cache_page((unsigned long)kaddr);
- kunmap_coherent();
+ if (pages_do_alias(addr, vmaddr)) {
+ if (page_mapped(page) && !Page_dcache_dirty(page)) {
+ void *kaddr;
+
+ kaddr = kmap_coherent(page, vmaddr);
+ flush_data_cache_page((unsigned long)kaddr);
+ kunmap_coherent();
+ } else
+ flush_data_cache_page(addr);
}
}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 480dec04f55..c7aed133d11 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -211,7 +211,8 @@ void copy_user_highpage(struct page *to, struct page *from,
void *vfrom, *vto;
vto = kmap_atomic(to, KM_USER1);
- if (cpu_has_dc_aliases && page_mapped(from)) {
+ if (cpu_has_dc_aliases &&
+ page_mapped(from) && !Page_dcache_dirty(from)) {
vfrom = kmap_coherent(from, vaddr);
copy_page(vto, vfrom);
kunmap_coherent();
@@ -234,7 +235,8 @@ void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
- if (cpu_has_dc_aliases && page_mapped(page)) {
+ if (cpu_has_dc_aliases &&
+ page_mapped(page) && !Page_dcache_dirty(page)) {
void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(vto, src, len);
kunmap_coherent();
@@ -253,7 +255,8 @@ void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
- if (cpu_has_dc_aliases && page_mapped(page)) {
+ if (cpu_has_dc_aliases &&
+ page_mapped(page) && !Page_dcache_dirty(page)) {
void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(dst, vfrom, len);
kunmap_coherent();
diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
index a3e98c243a8..89925ec57d6 100644
--- a/arch/mips/mm/pg-sb1.c
+++ b/arch/mips/mm/pg-sb1.c
@@ -216,7 +216,7 @@ void sb1_dma_init(void)
int i;
for (i = 0; i < DM_NUM_CHANNELS; i++) {
- const u64 base_val = CPHYSADDR(&page_descr[i]) |
+ const u64 base_val = CPHYSADDR((unsigned long)&page_descr[i]) |
V_DM_DSCR_BASE_RINGSZ(1);
void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
@@ -228,11 +228,11 @@ void sb1_dma_init(void)
void clear_page(void *page)
{
- u64 to_phys = CPHYSADDR(page);
+ u64 to_phys = CPHYSADDR((unsigned long)page);
unsigned int cpu = smp_processor_id();
/* if the page is not in KSEG0, use old way */
- if ((long)KSEGX(page) != (long)CKSEG0)
+ if ((long)KSEGX((unsigned long)page) != (long)CKSEG0)
return clear_page_cpu(page);
page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM |
@@ -252,13 +252,13 @@ void clear_page(void *page)
void copy_page(void *to, void *from)
{
- u64 from_phys = CPHYSADDR(from);
- u64 to_phys = CPHYSADDR(to);
+ u64 from_phys = CPHYSADDR((unsigned long)from);
+ u64 to_phys = CPHYSADDR((unsigned long)to);
unsigned int cpu = smp_processor_id();
/* if any page is not in KSEG0, use old way */
- if ((long)KSEGX(to) != (long)CKSEG0
- || (long)KSEGX(from) != (long)CKSEG0)
+ if ((long)KSEGX((unsigned long)to) != (long)CKSEG0
+ || (long)KSEGX((unsigned long)from) != (long)CKSEG0)
return copy_page_cpu(to, from);
page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 6e6981fd793..f9471d77c09 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -177,8 +177,15 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
continue;
r = &dev->resource[idx];
+ if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
+ continue;
+ if ((idx == PCI_ROM_RESOURCE) &&
+ (!(r->flags & IORESOURCE_ROM_ENABLE)))
+ continue;
if (!r->start && r->end) {
- printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
+ printk(KERN_ERR "PCI: Device %s not available "
+ "because of resource collisions\n",
+ pci_name(dev));
return -EINVAL;
}
if (r->flags & IORESOURCE_IO)
@@ -186,10 +193,9 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
if (r->flags & IORESOURCE_MEM)
cmd |= PCI_COMMAND_MEMORY;
}
- if (dev->resource[PCI_ROM_RESOURCE].start)
- cmd |= PCI_COMMAND_MEMORY;
if (cmd != old_cmd) {
- printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
+ printk("PCI: Enabling device %s (%04x -> %04x)\n",
+ pci_name(dev), old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
return 0;
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index 183c460b9ca..bd9eeb43ed0 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -110,7 +110,6 @@ static void __cpuinit bcm1480_smp_finish(void)
sb1480_clockevent_init();
local_irq_enable();
- bcm1480_smp_finish();
}
/*
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index eedc3a5e0d9..6a6409adc56 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -63,6 +63,10 @@ config GENERIC_HARDIRQS
config HOTPLUG_CPU
def_bool n
+config HZ
+ int
+ default 1000
+
mainmenu "Matsushita MN10300/AM33 Kernel Configuration"
source "init/Kconfig"
diff --git a/arch/mn10300/configs/asb2303_defconfig b/arch/mn10300/configs/asb2303_defconfig
index ca9876a111d..3aa8906b3de 100644
--- a/arch/mn10300/configs/asb2303_defconfig
+++ b/arch/mn10300/configs/asb2303_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc2
-# Fri Nov 16 13:36:38 2007
+# Linux kernel version: 2.6.25-rc2
+# Tue Feb 19 18:52:24 2008
#
CONFIG_MN10300=y
CONFIG_AM33=y
@@ -21,6 +21,7 @@ CONFIG_ARCH_HAS_ILOG2_U32=y
# CONFIG_ARCH_SUPPORTS_AOUT is not set
CONFIG_GENERIC_HARDIRQS=y
# CONFIG_HOTPLUG_CPU is not set
+CONFIG_HZ=1000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -38,15 +39,16 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
-# CONFIG_FAIR_GROUP_SCHED is not set
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_USER_SCHED is not set
+# CONFIG_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 is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
@@ -57,22 +59,33 @@ CONFIG_SYSCTL_SYSCALL=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_VM_EVENT_COUNTERS is not set
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+# CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_KPROBES is not set
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
# CONFIG_BLOCK is not set
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
#
# Matsushita MN10300 system setup
@@ -206,6 +219,7 @@ 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
@@ -311,6 +325,8 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_PARPORT is not set
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HAVE_IDE is not set
#
# SCSI device support
@@ -345,7 +361,6 @@ CONFIG_SMC91X=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
@@ -405,6 +420,7 @@ CONFIG_RTC=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
#
@@ -444,6 +460,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_RTC_CLASS is not set
@@ -455,10 +472,10 @@ CONFIG_SSB_POSSIBLE=y
#
# File systems
#
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -554,5 +571,3 @@ CONFIG_HAS_DMA=y
#
# Profiling support
#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c
index c5451592d40..e94c25e8ca0 100644
--- a/arch/mn10300/kernel/gdb-io-ttysm.c
+++ b/arch/mn10300/kernel/gdb-io-ttysm.c
@@ -196,6 +196,7 @@ int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
try_again:
/* pull chars out of the buffer */
ix = gdbstub_rx_outp;
+ barrier();
if (ix == gdbstub_rx_inp) {
if (nonblock)
return -EAGAIN;
@@ -207,6 +208,7 @@ try_again:
ch = gdbstub_rx_buffer[ix++];
st = gdbstub_rx_buffer[ix++];
+ barrier();
gdbstub_rx_outp = ix & (PAGE_SIZE - 1);
st &= SC01STR_RXF | SC01STR_RBF | SC01STR_FEF | SC01STR_PEF |
diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c
index ff492e3b345..babb7c2ac37 100644
--- a/arch/mn10300/kernel/time.c
+++ b/arch/mn10300/kernel/time.c
@@ -84,11 +84,13 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
/* advance the kernel's time tracking system */
profile_tick(CPU_PROFILING);
do_timer(1);
- update_process_times(user_mode(get_irq_regs()));
check_rtc_time();
}
write_sequnlock(&xtime_lock);
+
+ update_process_times(user_mode(get_irq_regs()));
+
return IRQ_HANDLED;
}
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
index 8b9dc6d9dcc..fcb9a03d46a 100644
--- a/arch/mn10300/kernel/traps.c
+++ b/arch/mn10300/kernel/traps.c
@@ -391,7 +391,7 @@ static asmlinkage void unsupported_syscall(struct pt_regs *regs,
if (code == EXCEP_SYSCALL15 && !user_mode(regs)) {
if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_BUG) {
#ifdef CONFIG_GDBSTUB
- __gdbstub_bug_trap();
+ gdbstub_intercept(regs, code);
#endif
}
}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5b8d8382b76..1189d8d6170 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -90,6 +90,7 @@ config PPC
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_KPROBES
+ select HAVE_KRETPROBES
config EARLY_PRINTK
bool
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 6845482f009..1c6ce3536e4 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -176,7 +176,7 @@ define archhelp
@echo ' *_defconfig - Select default config from arch/$(ARCH)/configs'
endef
-install: vdso_install
+install:
$(Q)$(MAKE) $(build)=$(boot) install
vdso_install:
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 63d07ccbb9d..e3993a60758 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -35,10 +35,10 @@ endif
BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -I$(srctree)/$(src)/libfdt
-$(obj)/4xx.o: BOOTCFLAGS += -mcpu=440
-$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
-$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=440
-$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=440
+$(obj)/4xx.o: BOOTCFLAGS += -mcpu=405
+$(obj)/ebony.o: BOOTCFLAGS += -mcpu=405
+$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
+$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
diff --git a/arch/powerpc/boot/cuboot-bamboo.c b/arch/powerpc/boot/cuboot-bamboo.c
index 900c7ff2b7e..b5c30f766c4 100644
--- a/arch/powerpc/boot/cuboot-bamboo.c
+++ b/arch/powerpc/boot/cuboot-bamboo.c
@@ -17,6 +17,7 @@
#include "44x.h"
#include "cuboot.h"
+#define TARGET_4xx
#define TARGET_44x
#include "ppcboot.h"
diff --git a/arch/powerpc/boot/cuboot-ebony.c b/arch/powerpc/boot/cuboot-ebony.c
index c5f37ce172e..56564ba37f6 100644
--- a/arch/powerpc/boot/cuboot-ebony.c
+++ b/arch/powerpc/boot/cuboot-ebony.c
@@ -17,6 +17,7 @@
#include "44x.h"
#include "cuboot.h"
+#define TARGET_4xx
#define TARGET_44x
#include "ppcboot.h"
diff --git a/arch/powerpc/boot/cuboot-katmai.c b/arch/powerpc/boot/cuboot-katmai.c
index c021167f938..5434d70b566 100644
--- a/arch/powerpc/boot/cuboot-katmai.c
+++ b/arch/powerpc/boot/cuboot-katmai.c
@@ -22,6 +22,7 @@
#include "44x.h"
#include "cuboot.h"
+#define TARGET_4xx
#define TARGET_44x
#include "ppcboot.h"
diff --git a/arch/powerpc/boot/cuboot-taishan.c b/arch/powerpc/boot/cuboot-taishan.c
index f66455a45ab..b55b80467ee 100644
--- a/arch/powerpc/boot/cuboot-taishan.c
+++ b/arch/powerpc/boot/cuboot-taishan.c
@@ -21,7 +21,9 @@
#include "dcr.h"
#include "4xx.h"
+#define TARGET_4xx
#define TARGET_44x
+#define TARGET_440GX
#include "ppcboot.h"
static bd_t bd;
diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c
index bdedebe1bc1..3db93e85e9e 100644
--- a/arch/powerpc/boot/cuboot-warp.c
+++ b/arch/powerpc/boot/cuboot-warp.c
@@ -11,6 +11,7 @@
#include "4xx.h"
#include "cuboot.h"
+#define TARGET_4xx
#define TARGET_44x
#include "ppcboot.h"
diff --git a/arch/powerpc/boot/dts/bamboo.dts b/arch/powerpc/boot/dts/bamboo.dts
index 29f1a6f3e37..7dc37c9a744 100644
--- a/arch/powerpc/boot/dts/bamboo.dts
+++ b/arch/powerpc/boot/dts/bamboo.dts
@@ -185,7 +185,6 @@
};
IIC0: i2c@ef600700 {
- device_type = "i2c";
compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic";
reg = <ef600700 14>;
interrupt-parent = <&UIC0>;
@@ -193,7 +192,6 @@
};
IIC1: i2c@ef600800 {
- device_type = "i2c";
compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic";
reg = <ef600800 14>;
interrupt-parent = <&UIC0>;
@@ -201,7 +199,6 @@
};
ZMII0: emac-zmii@ef600d00 {
- device_type = "zmii-interface";
compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii";
reg = <ef600d00 c>;
};
diff --git a/arch/powerpc/boot/dts/ebony.dts b/arch/powerpc/boot/dts/ebony.dts
index 7aad135a44b..0b000cb7ed8 100644
--- a/arch/powerpc/boot/dts/ebony.dts
+++ b/arch/powerpc/boot/dts/ebony.dts
@@ -216,7 +216,6 @@
IIC0: i2c@40000400 {
/* FIXME */
- device_type = "i2c";
compatible = "ibm,iic-440gp", "ibm,iic";
reg = <40000400 14>;
interrupt-parent = <&UIC0>;
@@ -224,7 +223,6 @@
};
IIC1: i2c@40000500 {
/* FIXME */
- device_type = "i2c";
compatible = "ibm,iic-440gp", "ibm,iic";
reg = <40000500 14>;
interrupt-parent = <&UIC0>;
diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts
index 5dd3d15f0fe..ae68fefc01b 100644
--- a/arch/powerpc/boot/dts/haleakala.dts
+++ b/arch/powerpc/boot/dts/haleakala.dts
@@ -235,7 +235,7 @@
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
- compatible = "ibm,plb-pciex-405exr", "ibm,plb-pciex";
+ compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
primary;
port = <0>; /* port number */
reg = <a0000000 20000000 /* Config space access */
diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts
index 9bdfc0ff3c2..fc86e5a3afc 100644
--- a/arch/powerpc/boot/dts/katmai.dts
+++ b/arch/powerpc/boot/dts/katmai.dts
@@ -38,8 +38,8 @@
timebase-frequency = <0>; /* Filled in by zImage */
i-cache-line-size = <20>;
d-cache-line-size = <20>;
- i-cache-size = <20000>;
- d-cache-size = <20000>;
+ i-cache-size = <8000>;
+ d-cache-size = <8000>;
dcr-controller;
dcr-access-method = "native";
};
@@ -136,11 +136,11 @@
};
POB0: opb {
- compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
+ compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
#address-cells = <1>;
#size-cells = <1>;
- ranges = <00000000 4 e0000000 20000000>;
- clock-frequency = <0>; /* Filled in by zImage */
+ ranges = <00000000 4 e0000000 20000000>;
+ clock-frequency = <0>; /* Filled in by zImage */
EBC0: ebc {
compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc";
@@ -153,41 +153,40 @@
};
UART0: serial@10000200 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <10000200 8>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <10000200 8>;
virtual-reg = <a0000200>;
- clock-frequency = <0>; /* Filled in by zImage */
- current-speed = <1c200>;
- interrupt-parent = <&UIC0>;
- interrupts = <0 4>;
- };
+ clock-frequency = <0>; /* Filled in by zImage */
+ current-speed = <1c200>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0 4>;
+ };
UART1: serial@10000300 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <10000300 8>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <10000300 8>;
virtual-reg = <a0000300>;
- clock-frequency = <0>;
- current-speed = <0>;
- interrupt-parent = <&UIC0>;
- interrupts = <1 4>;
- };
+ clock-frequency = <0>;
+ current-speed = <0>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <1 4>;
+ };
UART2: serial@10000600 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <10000600 8>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <10000600 8>;
virtual-reg = <a0000600>;
- clock-frequency = <0>;
- current-speed = <0>;
- interrupt-parent = <&UIC1>;
- interrupts = <5 4>;
- };
+ clock-frequency = <0>;
+ current-speed = <0>;
+ interrupt-parent = <&UIC1>;
+ interrupts = <5 4>;
+ };
IIC0: i2c@10000400 {
- device_type = "i2c";
compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
reg = <10000400 14>;
interrupt-parent = <&UIC0>;
@@ -195,7 +194,6 @@
};
IIC1: i2c@10000500 {
- device_type = "i2c";
compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
reg = <10000500 14>;
interrupt-parent = <&UIC0>;
diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
index 67c7ea179a0..8baef61f31c 100644
--- a/arch/powerpc/boot/dts/kilauea.dts
+++ b/arch/powerpc/boot/dts/kilauea.dts
@@ -182,7 +182,6 @@
};
IIC0: i2c@ef600400 {
- device_type = "i2c";
compatible = "ibm,iic-405ex", "ibm,iic";
reg = <ef600400 14>;
interrupt-parent = <&UIC0>;
@@ -190,7 +189,6 @@
};
IIC1: i2c@ef600500 {
- device_type = "i2c";
compatible = "ibm,iic-405ex", "ibm,iic";
reg = <ef600500 14>;
interrupt-parent = <&UIC0>;
@@ -199,7 +197,6 @@
RGMII0: emac-rgmii@ef600b00 {
- device_type = "rgmii-interface";
compatible = "ibm,rgmii-405ex", "ibm,rgmii";
reg = <ef600b00 104>;
has-mdio;
diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts
index bdd70e4596a..710c0116817 100644
--- a/arch/powerpc/boot/dts/makalu.dts
+++ b/arch/powerpc/boot/dts/makalu.dts
@@ -182,7 +182,6 @@
};
IIC0: i2c@ef600400 {
- device_type = "i2c";
compatible = "ibm,iic-405ex", "ibm,iic";
reg = <ef600400 14>;
interrupt-parent = <&UIC0>;
@@ -190,7 +189,6 @@
};
IIC1: i2c@ef600500 {
- device_type = "i2c";
compatible = "ibm,iic-405ex", "ibm,iic";
reg = <ef600500 14>;
interrupt-parent = <&UIC0>;
@@ -199,7 +197,6 @@
RGMII0: emac-rgmii@ef600b00 {
- device_type = "rgmii-interface";
compatible = "ibm,rgmii-405ex", "ibm,rgmii";
reg = <ef600b00 104>;
has-mdio;
diff --git a/arch/powerpc/boot/dts/rainier.dts b/arch/powerpc/boot/dts/rainier.dts
index d3c2ac394ce..f947c75a2e9 100644
--- a/arch/powerpc/boot/dts/rainier.dts
+++ b/arch/powerpc/boot/dts/rainier.dts
@@ -229,7 +229,6 @@
};
IIC0: i2c@ef600700 {
- device_type = "i2c";
compatible = "ibm,iic-440grx", "ibm,iic";
reg = <ef600700 14>;
interrupt-parent = <&UIC0>;
@@ -237,7 +236,6 @@
};
IIC1: i2c@ef600800 {
- device_type = "i2c";
compatible = "ibm,iic-440grx", "ibm,iic";
reg = <ef600800 14>;
interrupt-parent = <&UIC0>;
@@ -245,13 +243,11 @@
};
ZMII0: emac-zmii@ef600d00 {
- device_type = "zmii-interface";
compatible = "ibm,zmii-440grx", "ibm,zmii";
reg = <ef600d00 c>;
};
RGMII0: emac-rgmii@ef601000 {
- device_type = "rgmii-interface";
compatible = "ibm,rgmii-440grx", "ibm,rgmii";
reg = <ef601000 8>;
has-mdio;
diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts
index 5c13d46f441..8db9515d7dc 100644
--- a/arch/powerpc/boot/dts/sequoia.dts
+++ b/arch/powerpc/boot/dts/sequoia.dts
@@ -244,7 +244,6 @@
};
IIC0: i2c@ef600700 {
- device_type = "i2c";
compatible = "ibm,iic-440epx", "ibm,iic";
reg = <ef600700 14>;
interrupt-parent = <&UIC0>;
@@ -252,7 +251,6 @@
};
IIC1: i2c@ef600800 {
- device_type = "i2c";
compatible = "ibm,iic-440epx", "ibm,iic";
reg = <ef600800 14>;
interrupt-parent = <&UIC0>;
@@ -260,13 +258,11 @@
};
ZMII0: emac-zmii@ef600d00 {
- device_type = "zmii-interface";
compatible = "ibm,zmii-440epx", "ibm,zmii";
reg = <ef600d00 c>;
};
RGMII0: emac-rgmii@ef601000 {
- device_type = "rgmii-interface";
compatible = "ibm,rgmii-440epx", "ibm,rgmii";
reg = <ef601000 8>;
has-mdio;
diff --git a/arch/powerpc/boot/dts/taishan.dts b/arch/powerpc/boot/dts/taishan.dts
index 0706a4a13b9..8278068c802 100644
--- a/arch/powerpc/boot/dts/taishan.dts
+++ b/arch/powerpc/boot/dts/taishan.dts
@@ -203,7 +203,6 @@
IIC0: i2c@40000400 {
/* FIXME */
- device_type = "i2c";
compatible = "ibm,iic-440gp", "ibm,iic";
reg = <40000400 14>;
interrupt-parent = <&UIC0>;
@@ -211,7 +210,6 @@
};
IIC1: i2c@40000500 {
/* FIXME */
- device_type = "i2c";
compatible = "ibm,iic-440gp", "ibm,iic";
reg = <40000500 14>;
interrupt-parent = <&UIC0>;
@@ -225,13 +223,11 @@
};
ZMII0: emac-zmii@40000780 {
- device_type = "zgmii-interface";
compatible = "ibm,zmii-440gx", "ibm,zmii";
reg = <40000780 c>;
};
RGMII0: emac-rgmii@40000790 {
- device_type = "rgmii-interface";
compatible = "ibm,rgmii";
reg = <40000790 8>;
};
diff --git a/arch/powerpc/configs/bamboo_defconfig b/arch/powerpc/configs/bamboo_defconfig
index 1ed9afc9b28..c44db554cdc 100644
--- a/arch/powerpc/configs/bamboo_defconfig
+++ b/arch/powerpc/configs/bamboo_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Mon Dec 24 10:49:50 2007
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:36:39 2008
#
# CONFIG_PPC64 is not set
@@ -30,6 +30,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -68,17 +69,18 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# 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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# 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
@@ -92,11 +94,13 @@ 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_VM_EVENT_COUNTERS=y
@@ -104,6 +108,13 @@ CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -131,13 +142,15 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
# CONFIG_PPC4xx_PCI_EXPRESS is not set
#
# Platform support
#
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
@@ -147,8 +160,10 @@ CONFIG_BAMBOO=y
# CONFIG_TAISHAN is not set
# CONFIG_KATMAI is not set
# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
CONFIG_440EP=y
CONFIG_IBM440EP_ERR42=y
+# CONFIG_IPIC is not set
# CONFIG_MPIC is not set
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -159,7 +174,6 @@ CONFIG_IBM440EP_ERR42=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
#
@@ -175,13 +189,18 @@ 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_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -201,8 +220,6 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE="bamboo.dts"
CONFIG_ISA_DMA_API=y
#
@@ -302,6 +319,7 @@ 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
@@ -348,7 +366,7 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_XILINX_SYSACE is not set
@@ -357,6 +375,8 @@ CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -385,7 +405,6 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
@@ -414,6 +433,9 @@ CONFIG_NETDEV_1000=y
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED 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
@@ -438,6 +460,7 @@ CONFIG_NETDEV_10000=y
# CONFIG_NIU is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
# CONFIG_TR is not set
#
@@ -450,7 +473,6 @@ CONFIG_NETDEV_10000=y
# CONFIG_HIPPI 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
@@ -473,6 +495,7 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -518,6 +541,7 @@ CONFIG_DEVPORT=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
# CONFIG_WATCHDOG is not set
#
@@ -566,12 +590,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk 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_INFINIBAND is not set
# CONFIG_EDAC is not set
@@ -596,12 +617,10 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -643,8 +662,10 @@ CONFIG_TMPFS=y
# CONFIG_EFS_FS is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -675,7 +696,6 @@ CONFIG_SUNRPC=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
# CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
#
# Library routines
@@ -692,10 +712,6 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_KPROBES is not set
-# CONFIG_MARKERS is not set
#
# Kernel hacking
@@ -705,7 +721,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -714,6 +730,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS 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
@@ -726,9 +743,9 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -737,6 +754,7 @@ CONFIG_FORCED_INLINING=y
CONFIG_DEBUGGER=y
# CONFIG_KGDB is not set
# CONFIG_XMON is not set
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -749,6 +767,7 @@ CONFIG_DEBUGGER=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
@@ -766,6 +785,9 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -780,11 +802,14 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/ebony_defconfig b/arch/powerpc/configs/ebony_defconfig
index cf860f16665..07c8d4ce175 100644
--- a/arch/powerpc/configs/ebony_defconfig
+++ b/arch/powerpc/configs/ebony_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Mon Dec 24 11:16:26 2007
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:50:44 2008
#
# CONFIG_PPC64 is not set
@@ -29,6 +29,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -67,17 +68,18 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# 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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# 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
@@ -91,11 +93,13 @@ 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_VM_EVENT_COUNTERS=y
@@ -103,6 +107,13 @@ CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -130,13 +141,15 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
# CONFIG_PPC4xx_PCI_EXPRESS is not set
#
# Platform support
#
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
@@ -146,7 +159,9 @@ CONFIG_EBONY=y
# CONFIG_TAISHAN is not set
# CONFIG_KATMAI is not set
# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
CONFIG_440GP=y
+# CONFIG_IPIC is not set
# CONFIG_MPIC is not set
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -157,8 +172,8 @@ CONFIG_440GP=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
+CONFIG_OF_RTC=y
#
# Kernel options
@@ -173,13 +188,18 @@ 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_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -198,8 +218,6 @@ CONFIG_VIRT_TO_BUS=y
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE="ebony.dts"
CONFIG_ISA_DMA_API=y
#
@@ -299,6 +317,7 @@ 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
@@ -335,6 +354,7 @@ CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
#
# User Modules And Translation Layers
@@ -420,7 +440,7 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_XILINX_SYSACE is not set
@@ -429,6 +449,8 @@ CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -457,7 +479,6 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
@@ -486,6 +507,9 @@ CONFIG_NETDEV_1000=y
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED 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
@@ -510,6 +534,7 @@ CONFIG_NETDEV_10000=y
# CONFIG_NIU is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
# CONFIG_TR is not set
#
@@ -522,7 +547,6 @@ CONFIG_NETDEV_10000=y
# CONFIG_HIPPI 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
@@ -545,6 +569,7 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -590,6 +615,7 @@ CONFIG_DEVPORT=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
# CONFIG_WATCHDOG is not set
#
@@ -638,12 +664,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk 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_INFINIBAND is not set
# CONFIG_EDAC is not set
@@ -668,12 +691,10 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -726,8 +747,10 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -758,7 +781,6 @@ CONFIG_SUNRPC=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
# CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
#
# Library routines
@@ -776,7 +798,6 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-# CONFIG_INSTRUMENTATION is not set
#
# Kernel hacking
@@ -786,7 +807,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -795,6 +816,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS 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
@@ -807,15 +829,16 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUGGER is not set
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -828,6 +851,7 @@ CONFIG_FORCED_INLINING=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
@@ -845,6 +869,9 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -859,11 +886,13 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
# CONFIG_CRYPTO_HW is not set
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/ep405_defconfig b/arch/powerpc/configs/ep405_defconfig
index 3829c916625..e24240a9a04 100644
--- a/arch/powerpc/configs/ep405_defconfig
+++ b/arch/powerpc/configs/ep405_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Mon Dec 24 11:17:13 2007
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:50:09 2008
#
# CONFIG_PPC64 is not set
@@ -26,6 +26,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -64,17 +65,18 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# 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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# 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
@@ -88,11 +90,13 @@ 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_VM_EVENT_COUNTERS=y
@@ -100,6 +104,13 @@ CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -127,13 +138,15 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
# CONFIG_PPC4xx_PCI_EXPRESS is not set
#
# Platform support
#
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
@@ -145,6 +158,7 @@ CONFIG_EP405=y
CONFIG_405GP=y
CONFIG_IBM405_ERR77=y
CONFIG_IBM405_ERR51=y
+# CONFIG_IPIC is not set
# CONFIG_MPIC is not set
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -155,7 +169,6 @@ CONFIG_IBM405_ERR51=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
#
@@ -171,13 +184,18 @@ 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_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -196,11 +214,7 @@ CONFIG_VIRT_TO_BUS=y
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
# CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
-CONFIG_HIBERNATION_UP_POSSIBLE=y
CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE="ep405.dts"
CONFIG_ISA_DMA_API=y
#
@@ -300,6 +314,7 @@ 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
@@ -336,6 +351,7 @@ CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
#
# User Modules And Translation Layers
@@ -423,7 +439,7 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_XILINX_SYSACE is not set
@@ -432,6 +448,8 @@ CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -460,7 +478,6 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
@@ -489,6 +506,9 @@ CONFIG_NETDEV_1000=y
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED 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
@@ -513,6 +533,7 @@ CONFIG_NETDEV_10000=y
# CONFIG_NIU is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
# CONFIG_TR is not set
#
@@ -534,7 +555,6 @@ CONFIG_NETDEV_10000=y
# CONFIG_HIPPI 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
@@ -557,6 +577,7 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -602,6 +623,7 @@ CONFIG_DEVPORT=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
# CONFIG_WATCHDOG is not set
#
@@ -647,6 +669,7 @@ 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
@@ -697,10 +720,6 @@ CONFIG_USB_MON=y
#
# USB port drivers
#
-
-#
-# USB Serial Converter support
-#
# CONFIG_USB_SERIAL is not set
#
@@ -725,16 +744,9 @@ CONFIG_USB_MON=y
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST 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_INFINIBAND is not set
# CONFIG_EDAC is not set
@@ -759,12 +771,10 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -807,8 +817,10 @@ CONFIG_TMPFS=y
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -839,7 +851,6 @@ CONFIG_SUNRPC=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
# CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
#
# Library routines
@@ -856,10 +867,6 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_KPROBES is not set
-# CONFIG_MARKERS is not set
#
# Kernel hacking
@@ -869,7 +876,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -878,6 +885,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS 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
@@ -890,15 +898,16 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUGGER is not set
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -911,6 +920,7 @@ CONFIG_FORCED_INLINING=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
@@ -928,6 +938,9 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -942,11 +955,14 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/kilauea_defconfig b/arch/powerpc/configs/kilauea_defconfig
index 8dca3d451c0..2f475391f1d 100644
--- a/arch/powerpc/configs/kilauea_defconfig
+++ b/arch/powerpc/configs/kilauea_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Thu Jan 3 14:21:31 2008
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:51:43 2008
#
# CONFIG_PPC64 is not set
@@ -26,6 +26,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -64,15 +65,18 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# 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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
# CONFIG_FAIR_GROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# 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
@@ -86,11 +90,13 @@ 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_VM_EVENT_COUNTERS=y
@@ -98,6 +104,13 @@ CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -125,13 +138,15 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
CONFIG_PPC4xx_PCI_EXPRESS=y
#
# Platform support
#
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
@@ -141,6 +156,7 @@ CONFIG_KILAUEA=y
# CONFIG_WALNUT is not set
# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
CONFIG_405EX=y
+# CONFIG_IPIC is not set
# CONFIG_MPIC is not set
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -151,7 +167,6 @@ CONFIG_405EX=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
#
@@ -167,13 +182,18 @@ 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_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -192,11 +212,7 @@ CONFIG_VIRT_TO_BUS=y
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
# CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
-CONFIG_HIBERNATION_UP_POSSIBLE=y
CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE="kilauea.dts"
CONFIG_ISA_DMA_API=y
#
@@ -296,6 +312,7 @@ 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
@@ -332,6 +349,7 @@ CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
#
# User Modules And Translation Layers
@@ -418,11 +436,12 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_XILINX_SYSACE is not set
# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -451,7 +470,6 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
@@ -489,7 +507,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
# CONFIG_HIPPI 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
@@ -512,6 +529,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -557,6 +575,7 @@ CONFIG_DEVPORT=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
# CONFIG_WATCHDOG is not set
#
@@ -598,6 +617,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
@@ -622,12 +642,10 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -670,8 +688,10 @@ CONFIG_TMPFS=y
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -702,7 +722,6 @@ CONFIG_SUNRPC=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
# CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
#
# Library routines
@@ -719,7 +738,6 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-# CONFIG_INSTRUMENTATION is not set
#
# Kernel hacking
@@ -729,7 +747,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -738,6 +756,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS 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
@@ -750,15 +769,16 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUGGER is not set
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -771,6 +791,7 @@ CONFIG_FORCED_INLINING=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
@@ -788,6 +809,9 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -802,11 +826,14 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/makalu_defconfig b/arch/powerpc/configs/makalu_defconfig
index c5db0265e5d..9ef4d8a312c 100644
--- a/arch/powerpc/configs/makalu_defconfig
+++ b/arch/powerpc/configs/makalu_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Mon Dec 24 11:18:32 2007
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:52:30 2008
#
# CONFIG_PPC64 is not set
@@ -26,6 +26,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -64,15 +65,18 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# 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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
# CONFIG_FAIR_GROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# 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
@@ -86,11 +90,13 @@ 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_VM_EVENT_COUNTERS=y
@@ -98,6 +104,13 @@ CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -125,13 +138,15 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
CONFIG_PPC4xx_PCI_EXPRESS=y
#
# Platform support
#
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
@@ -141,6 +156,7 @@ CONFIG_MAKALU=y
# CONFIG_WALNUT is not set
# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
CONFIG_405EX=y
+# CONFIG_IPIC is not set
# CONFIG_MPIC is not set
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -151,7 +167,6 @@ CONFIG_405EX=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
#
@@ -167,13 +182,18 @@ 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_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -192,11 +212,7 @@ CONFIG_VIRT_TO_BUS=y
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
# CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
-CONFIG_HIBERNATION_UP_POSSIBLE=y
CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE="kilauea.dts"
CONFIG_ISA_DMA_API=y
#
@@ -296,6 +312,7 @@ 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
@@ -332,6 +349,7 @@ CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
#
# User Modules And Translation Layers
@@ -418,11 +436,12 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_XILINX_SYSACE is not set
# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -451,7 +470,6 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
@@ -489,7 +507,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
# CONFIG_HIPPI 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
@@ -512,6 +529,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -557,6 +575,7 @@ CONFIG_DEVPORT=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
# CONFIG_WATCHDOG is not set
#
@@ -598,6 +617,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
@@ -622,12 +642,10 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -670,8 +688,10 @@ CONFIG_TMPFS=y
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -702,7 +722,6 @@ CONFIG_SUNRPC=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
# CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
#
# Library routines
@@ -719,7 +738,6 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-# CONFIG_INSTRUMENTATION is not set
#
# Kernel hacking
@@ -729,7 +747,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -738,6 +756,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS 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
@@ -750,15 +769,16 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUGGER is not set
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -771,6 +791,7 @@ CONFIG_FORCED_INLINING=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
@@ -788,6 +809,9 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -802,11 +826,14 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig
new file mode 100644
index 00000000000..57bd775ef77
--- /dev/null
+++ b/arch/powerpc/configs/ppc44x_defconfig
@@ -0,0 +1,904 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:57:35 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=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 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_SYSFS_DEPRECATED=y
+# 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
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG 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_PREEMPT_RCU is not set
+CONFIG_PPC4xx_PCI_EXPRESS=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_BAMBOO=y
+CONFIG_EBONY=y
+CONFIG_SEQUOIA=y
+CONFIG_TAISHAN=y
+CONFIG_KATMAI=y
+CONFIG_RAINIER=y
+CONFIG_WARP=y
+CONFIG_440EP=y
+CONFIG_440EPX=y
+CONFIG_440GRX=y
+CONFIG_440GP=y
+CONFIG_440GX=y
+CONFIG_440SPe=y
+CONFIG_IBM440EP_ERR42=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+CONFIG_OF_RTC=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM 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
+# CONFIG_HZ_100 is not set
+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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+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_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x01000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# 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_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL 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_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
+
+#
+# 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
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 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_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# 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 is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XILINX_SYSACE 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_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS 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
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# 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 is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+CONFIG_IBM_NEW_EMAC_RGMII=y
+CONFIG_IBM_NEW_EMAC_TAH=y
+CONFIG_IBM_NEW_EMAC_EMAC4=y
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED 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_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 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_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+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_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM 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
+
+#
+# Sound
+#
+# CONFIG_SOUND 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 is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_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_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# 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_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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=y
+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_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS 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 is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+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_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS 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 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_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/rainier_defconfig b/arch/powerpc/configs/rainier_defconfig
index 7b95001a22a..dec18ca7351 100644
--- a/arch/powerpc/configs/rainier_defconfig
+++ b/arch/powerpc/configs/rainier_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Mon Dec 24 11:22:40 2007
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:53:10 2008
#
# CONFIG_PPC64 is not set
@@ -29,6 +29,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -67,17 +68,18 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# 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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# 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
@@ -91,11 +93,13 @@ 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_VM_EVENT_COUNTERS=y
@@ -103,6 +107,13 @@ CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -130,13 +141,15 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
# CONFIG_PPC4xx_PCI_EXPRESS is not set
#
# Platform support
#
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
@@ -146,7 +159,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_TAISHAN is not set
# CONFIG_KATMAI is not set
CONFIG_RAINIER=y
+# CONFIG_WARP is not set
CONFIG_440GRX=y
+# CONFIG_IPIC is not set
# CONFIG_MPIC is not set
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -157,7 +172,6 @@ CONFIG_440GRX=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
#
@@ -173,13 +187,18 @@ 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_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -199,8 +218,6 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE="rainier.dts"
CONFIG_ISA_DMA_API=y
#
@@ -300,6 +317,7 @@ 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
@@ -336,6 +354,7 @@ CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
#
# User Modules And Translation Layers
@@ -422,7 +441,7 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_XILINX_SYSACE is not set
@@ -431,6 +450,8 @@ CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -461,7 +482,6 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_NET_ETHERNET is not set
CONFIG_IBM_NEW_EMAC_ZMII=y
@@ -472,6 +492,9 @@ CONFIG_NETDEV_1000=y
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED 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
@@ -496,6 +519,7 @@ CONFIG_NETDEV_10000=y
# CONFIG_NIU is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
# CONFIG_TR is not set
#
@@ -508,7 +532,6 @@ CONFIG_NETDEV_10000=y
# CONFIG_HIPPI 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
@@ -531,6 +554,7 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -576,6 +600,7 @@ CONFIG_DEVPORT=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
# CONFIG_WATCHDOG is not set
#
@@ -624,12 +649,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk 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_INFINIBAND is not set
# CONFIG_EDAC is not set
@@ -654,12 +676,10 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -712,8 +732,10 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -744,7 +766,6 @@ CONFIG_SUNRPC=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
# CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
#
# Library routines
@@ -762,10 +783,6 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_KPROBES is not set
-# CONFIG_MARKERS is not set
#
# Kernel hacking
@@ -775,7 +792,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -784,6 +801,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS 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
@@ -796,9 +814,9 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -807,6 +825,7 @@ CONFIG_FORCED_INLINING=y
CONFIG_DEBUGGER=y
# CONFIG_KGDB is not set
# CONFIG_XMON is not set
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BDI_SWITCH is not set
CONFIG_PPC_EARLY_DEBUG=y
# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
@@ -832,6 +851,7 @@ CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
@@ -849,6 +869,9 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -863,11 +886,14 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/sequoia_defconfig b/arch/powerpc/configs/sequoia_defconfig
index abbfed6582e..dd5d6303c39 100644
--- a/arch/powerpc/configs/sequoia_defconfig
+++ b/arch/powerpc/configs/sequoia_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Mon Dec 24 11:23:22 2007
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:53:46 2008
#
# CONFIG_PPC64 is not set
@@ -30,6 +30,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -68,15 +69,18 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# 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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
# CONFIG_FAIR_GROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# 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
@@ -90,11 +94,13 @@ 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_VM_EVENT_COUNTERS=y
@@ -102,6 +108,13 @@ CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -129,13 +142,15 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
# CONFIG_PPC4xx_PCI_EXPRESS is not set
#
# Platform support
#
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
@@ -145,7 +160,9 @@ CONFIG_SEQUOIA=y
# CONFIG_TAISHAN is not set
# CONFIG_KATMAI is not set
# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
CONFIG_440EPX=y
+# CONFIG_IPIC is not set
# CONFIG_MPIC is not set
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -156,7 +173,6 @@ CONFIG_440EPX=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
#
@@ -172,13 +188,18 @@ 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_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -198,8 +219,6 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE="sequoia.dts"
CONFIG_ISA_DMA_API=y
#
@@ -299,6 +318,7 @@ 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
@@ -335,6 +355,7 @@ CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
#
# User Modules And Translation Layers
@@ -421,7 +442,7 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_XILINX_SYSACE is not set
@@ -430,6 +451,8 @@ CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -458,7 +481,6 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
@@ -487,6 +509,9 @@ CONFIG_NETDEV_1000=y
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED 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
@@ -511,6 +536,7 @@ CONFIG_NETDEV_10000=y
# CONFIG_NIU is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
# CONFIG_TR is not set
#
@@ -523,7 +549,6 @@ CONFIG_NETDEV_10000=y
# CONFIG_HIPPI 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
@@ -546,6 +571,7 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -591,6 +617,7 @@ CONFIG_DEVPORT=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
# CONFIG_WATCHDOG is not set
#
@@ -639,12 +666,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk 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_INFINIBAND is not set
# CONFIG_EDAC is not set
@@ -669,12 +693,10 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -727,8 +749,10 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -759,7 +783,6 @@ CONFIG_SUNRPC=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
# CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
#
# Library routines
@@ -777,7 +800,6 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-# CONFIG_INSTRUMENTATION is not set
#
# Kernel hacking
@@ -787,7 +809,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -796,6 +818,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS 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
@@ -808,9 +831,9 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -819,6 +842,7 @@ CONFIG_FORCED_INLINING=y
CONFIG_DEBUGGER=y
# CONFIG_KGDB is not set
# CONFIG_XMON is not set
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BDI_SWITCH is not set
CONFIG_PPC_EARLY_DEBUG=y
# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
@@ -844,6 +868,7 @@ CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
@@ -861,6 +886,9 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -875,11 +903,14 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/taishan_defconfig b/arch/powerpc/configs/taishan_defconfig
index ade84b92877..087aedce133 100644
--- a/arch/powerpc/configs/taishan_defconfig
+++ b/arch/powerpc/configs/taishan_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Mon Dec 24 11:23:39 2007
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:40:44 2008
#
# CONFIG_PPC64 is not set
@@ -29,6 +29,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -67,17 +68,18 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# 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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# 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
@@ -91,11 +93,13 @@ 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_VM_EVENT_COUNTERS=y
@@ -103,6 +107,13 @@ CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -130,13 +141,15 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
# CONFIG_PPC4xx_PCI_EXPRESS is not set
#
# Platform support
#
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
@@ -146,7 +159,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_TAISHAN=y
# CONFIG_KATMAI is not set
# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
CONFIG_440GX=y
+# CONFIG_IPIC is not set
# CONFIG_MPIC is not set
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -157,7 +172,6 @@ CONFIG_440GX=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
#
@@ -173,13 +187,18 @@ 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_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -199,8 +218,6 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE="taishan.dts"
CONFIG_ISA_DMA_API=y
#
@@ -300,6 +317,7 @@ 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
@@ -346,7 +364,7 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_XILINX_SYSACE is not set
@@ -355,6 +373,8 @@ CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -385,7 +405,6 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
@@ -414,6 +433,9 @@ CONFIG_NETDEV_1000=y
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED 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
@@ -438,6 +460,7 @@ CONFIG_NETDEV_10000=y
# CONFIG_NIU is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
# CONFIG_TR is not set
#
@@ -450,7 +473,6 @@ CONFIG_NETDEV_10000=y
# CONFIG_HIPPI 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
@@ -473,6 +495,7 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -518,6 +541,7 @@ CONFIG_DEVPORT=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
# CONFIG_WATCHDOG is not set
#
@@ -566,12 +590,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk 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_INFINIBAND is not set
# CONFIG_EDAC is not set
@@ -596,12 +617,10 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -643,8 +662,10 @@ CONFIG_TMPFS=y
# CONFIG_EFS_FS is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -675,7 +696,6 @@ CONFIG_SUNRPC=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
# CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
#
# Library routines
@@ -692,10 +712,6 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_KPROBES is not set
-# CONFIG_MARKERS is not set
#
# Kernel hacking
@@ -705,7 +721,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -714,6 +730,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS 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
@@ -726,9 +743,9 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -737,6 +754,7 @@ CONFIG_FORCED_INLINING=y
CONFIG_DEBUGGER=y
# CONFIG_KGDB is not set
# CONFIG_XMON is not set
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -749,6 +767,7 @@ CONFIG_DEBUGGER=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
@@ -766,6 +785,9 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -780,11 +802,14 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/walnut_defconfig b/arch/powerpc/configs/walnut_defconfig
index e431128e8e9..3b2689e5002 100644
--- a/arch/powerpc/configs/walnut_defconfig
+++ b/arch/powerpc/configs/walnut_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Mon Dec 24 11:23:58 2007
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:54:12 2008
#
# CONFIG_PPC64 is not set
@@ -26,6 +26,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -64,17 +65,18 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# 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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# 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
@@ -88,11 +90,13 @@ 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_VM_EVENT_COUNTERS=y
@@ -100,6 +104,13 @@ CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -127,13 +138,15 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
# CONFIG_PPC4xx_PCI_EXPRESS is not set
#
# Platform support
#
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
@@ -145,6 +158,7 @@ CONFIG_WALNUT=y
CONFIG_405GP=y
CONFIG_IBM405_ERR77=y
CONFIG_IBM405_ERR51=y
+# CONFIG_IPIC is not set
# CONFIG_MPIC is not set
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -155,8 +169,8 @@ CONFIG_IBM405_ERR51=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
+CONFIG_OF_RTC=y
#
# Kernel options
@@ -171,13 +185,18 @@ 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_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -196,11 +215,7 @@ CONFIG_VIRT_TO_BUS=y
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
# CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
-CONFIG_HIBERNATION_UP_POSSIBLE=y
CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE="walnut.dts"
CONFIG_ISA_DMA_API=y
#
@@ -300,6 +315,7 @@ 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
@@ -336,6 +352,7 @@ CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
#
# User Modules And Translation Layers
@@ -422,7 +439,7 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_XILINX_SYSACE is not set
@@ -431,6 +448,8 @@ CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -459,7 +478,6 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
@@ -488,6 +506,9 @@ CONFIG_NETDEV_1000=y
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED 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
@@ -512,6 +533,7 @@ CONFIG_NETDEV_10000=y
# CONFIG_NIU is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
# CONFIG_TR is not set
#
@@ -524,7 +546,6 @@ CONFIG_NETDEV_10000=y
# CONFIG_HIPPI 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
@@ -547,6 +568,7 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -592,6 +614,7 @@ CONFIG_DEVPORT=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
# CONFIG_WATCHDOG is not set
#
@@ -640,12 +663,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk 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_INFINIBAND is not set
# CONFIG_EDAC is not set
@@ -670,12 +690,10 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -718,8 +736,10 @@ CONFIG_TMPFS=y
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -750,7 +770,6 @@ CONFIG_SUNRPC=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
# CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
#
# Library routines
@@ -767,7 +786,6 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-# CONFIG_INSTRUMENTATION is not set
#
# Kernel hacking
@@ -777,7 +795,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -786,6 +804,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS 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
@@ -798,15 +817,16 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUGGER is not set
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -819,6 +839,7 @@ CONFIG_FORCED_INLINING=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
@@ -836,6 +857,9 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -850,11 +874,14 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/warp_defconfig b/arch/powerpc/configs/warp_defconfig
index 312557b5df5..2313c3e8ef6 100644
--- a/arch/powerpc/configs/warp_defconfig
+++ b/arch/powerpc/configs/warp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Tue Jan 8 12:23:23 2008
+# Linux kernel version: 2.6.25-rc2
+# Fri Feb 15 21:54:43 2008
#
# CONFIG_PPC64 is not set
@@ -30,6 +30,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -68,17 +69,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 is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# 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
@@ -92,17 +94,26 @@ CONFIG_KALLSYMS=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_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_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -130,12 +141,14 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
#
# Platform support
#
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
@@ -148,6 +161,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_WARP=y
CONFIG_440EP=y
CONFIG_IBM440EP_ERR42=y
+# CONFIG_IPIC is not set
# CONFIG_MPIC is not set
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -158,7 +172,6 @@ CONFIG_IBM440EP_ERR42=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
#
@@ -174,13 +187,18 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
+# CONFIG_SCHED_HRTICK is not set
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -200,8 +218,6 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="ip=on"
CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE="warp.dts"
CONFIG_ISA_DMA_API=y
#
@@ -244,6 +260,7 @@ 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
@@ -279,12 +296,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
#
# Core Netfilter Configuration
#
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
# CONFIG_NF_CONNTRACK is not set
# CONFIG_NETFILTER_XTABLES is not set
@@ -315,6 +333,7 @@ CONFIG_VLAN_8021Q=y
#
# 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
@@ -348,6 +367,7 @@ CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
#
# User Modules And Translation Layers
@@ -414,11 +434,11 @@ CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC_SMC=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_NDFC=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND_FSL_ELBC is not set
# CONFIG_MTD_ONENAND is not set
#
@@ -436,12 +456,14 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_XILINX_SYSACE is not set
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -471,7 +493,7 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
-# CONFIG_SCSI_WAIT_SCAN is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
# SCSI Transports
@@ -528,7 +550,6 @@ CONFIG_IBM_NEW_EMAC_ZMII=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
@@ -596,7 +617,6 @@ CONFIG_I2C_BOARDINFO=y
#
# I2C Hardware Bus support
#
-CONFIG_I2C_IBM_IIC=y
# CONFIG_I2C_MPC is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
@@ -608,14 +628,12 @@ CONFIG_I2C_IBM_IIC=y
#
# Miscellaneous I2C Chip support
#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
# CONFIG_DS1682 is not set
CONFIG_SENSORS_EEPROM=y
# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_TPS65010 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -632,7 +650,6 @@ CONFIG_SENSORS_EEPROM=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
-CONFIG_SENSORS_AD7414=y
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
@@ -668,6 +685,7 @@ CONFIG_SENSORS_AD7414=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
@@ -675,9 +693,11 @@ CONFIG_SENSORS_AD7414=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=y
# CONFIG_WATCHDOG is not set
#
@@ -721,6 +741,7 @@ CONFIG_USB_ARCH_HAS_OHCI=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
@@ -781,10 +802,6 @@ CONFIG_USB_MON=y
#
# USB port drivers
#
-
-#
-# USB Serial Converter support
-#
# CONFIG_USB_SERIAL is not set
#
@@ -808,14 +825,6 @@ CONFIG_USB_MON=y
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
# CONFIG_USB_GADGET is not set
CONFIG_MMC=m
# CONFIG_MMC_DEBUG is not set
@@ -832,6 +841,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# MMC/SD Host Controller Drivers
#
# CONFIG_MMC_WBSD is not set
+# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_EDAC is not set
# CONFIG_RTC_CLASS is not set
@@ -855,12 +865,10 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -915,8 +923,10 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -986,7 +996,6 @@ CONFIG_NLS_ISO8859_15=y
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=y
# CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
#
# Library routines
@@ -1004,7 +1013,6 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-# CONFIG_INSTRUMENTATION is not set
#
# Kernel hacking
@@ -1014,7 +1022,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -1035,15 +1043,16 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUGGER is not set
+# CONFIG_VIRQ_DEBUG is not set
CONFIG_BDI_SWITCH=y
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -1053,5 +1062,49 @@ CONFIG_BDI_SWITCH=y
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_SEQIV is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 5338e485571..c176c513566 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -274,7 +274,7 @@ no_kprobe:
* - When the probed function returns, this probe
* causes the handlers to fire
*/
-void kretprobe_trampoline_holder(void)
+static void __used kretprobe_trampoline_holder(void)
{
asm volatile(".global kretprobe_trampoline\n"
"kretprobe_trampoline:\n"
@@ -284,7 +284,8 @@ void kretprobe_trampoline_holder(void)
/*
* Called when the probe at kretprobe trampoline is hit
*/
-int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes trampoline_probe_handler(struct kprobe *p,
+ struct pt_regs *regs)
{
struct kretprobe_instance *ri = NULL;
struct hlist_head *head, empty_rp;
@@ -517,12 +518,12 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
return 1;
}
-void __kprobes jprobe_return(void)
+void __used __kprobes jprobe_return(void)
{
asm volatile("trap" ::: "memory");
}
-void __kprobes jprobe_return_end(void)
+static void __used __kprobes jprobe_return_end(void)
{
};
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 8b5efbce8d9..eac97f48b9b 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -865,12 +865,12 @@ static int __init early_init_dt_scan_root(unsigned long node,
return 1;
}
-static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
+static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
{
cell_t *p = *cellp;
*cellp = p + s;
- return of_read_ulong(p, s);
+ return of_read_number(p, s);
}
#ifdef CONFIG_PPC_PSERIES
@@ -883,8 +883,8 @@ static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
static int __init early_init_dt_scan_drconf_memory(unsigned long node)
{
cell_t *dm, *ls;
- unsigned long l, n;
- unsigned long base, size, lmb_size, flags;
+ unsigned long l, n, flags;
+ u64 base, size, lmb_size;
ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t))
@@ -959,14 +959,15 @@ static int __init early_init_dt_scan_memory(unsigned long node,
uname, l, reg[0], reg[1], reg[2], reg[3]);
while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
- unsigned long base, size;
+ u64 base, size;
base = dt_mem_next_cell(dt_root_addr_cells, &reg);
size = dt_mem_next_cell(dt_root_size_cells, &reg);
if (size == 0)
continue;
- DBG(" - %lx , %lx\n", base, size);
+ DBG(" - %llx , %llx\n", (unsigned long long)base,
+ (unsigned long long)size);
#ifdef CONFIG_PPC64
if (iommu_is_off) {
if (base >= 0x80000000ul)
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c
index 13929771bee..9eed1f68fca 100644
--- a/arch/powerpc/oprofile/op_model_cell.c
+++ b/arch/powerpc/oprofile/op_model_cell.c
@@ -1151,7 +1151,7 @@ static void cell_handle_interrupt(struct pt_regs *regs,
for (i = 0; i < num_counters; ++i) {
if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i))
&& ctr[i].enabled) {
- oprofile_add_pc(pc, is_kernel, i);
+ oprofile_add_ext_sample(pc, regs, i, is_kernel);
cbe_write_ctr(cpu, i, reset_value[i]);
}
}
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index c062c4cbbed..1bfb2191010 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -61,7 +61,7 @@ config WARP
select 440EP
help
This option enables support for the PIKA Warp(tm) Appliance. The Warp
- is a small computer replacement with up to 9 ports of FXO/FXS plus VOIP
+ is a small computer replacement with up to 9 ports of FXO/FXS plus VOIP
stations and trunks.
See http://www.pikatechnologies.com/ and follow the "PIKA for Computer
@@ -110,17 +110,17 @@ config 440GP
config 440GX
bool
- select IBM_NEW_EMAC_EMAC4
+ select IBM_NEW_EMAC_EMAC4
select IBM_NEW_EMAC_RGMII
- select IBM_NEW_EMAC_ZMII #test only
- select IBM_NEW_EMAC_TAH #test only
+ select IBM_NEW_EMAC_ZMII #test only
+ select IBM_NEW_EMAC_TAH #test only
config 440SP
bool
config 440SPe
- select IBM_NEW_EMAC_EMAC4
bool
+ select IBM_NEW_EMAC_EMAC4
# 44x errata/workaround config symbols, selected by the CPU models above
config IBM440EP_ERR42
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 9aa4425d80b..4d5fd1dbd40 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -199,6 +199,7 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
return 0;
}
+EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv);
/**
* mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index edab631a8dc..20ea0e118f2 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -113,7 +113,7 @@
/* IOMMU sizing */
#define IO_SEGMENT_SHIFT 28
-#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT)
+#define IO_PAGENO_BITS(shift) (IO_SEGMENT_SHIFT - (shift))
/* The high bit needs to be set on every DMA address */
#define SPIDER_DMA_OFFSET 0x80000000ul
@@ -123,7 +123,6 @@ struct iommu_window {
struct cbe_iommu *iommu;
unsigned long offset;
unsigned long size;
- unsigned long pte_offset;
unsigned int ioid;
struct iommu_table table;
};
@@ -200,7 +199,7 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
(window->ioid & IOPTE_IOID_Mask);
#endif
- io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
+ io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
@@ -232,7 +231,7 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages)
| (window->ioid & IOPTE_IOID_Mask);
#endif
- io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
+ io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
for (i = 0; i < npages; i++)
io_pte[i] = pte;
@@ -307,76 +306,84 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base)
return -ENODEV;
}
-static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu,
+static void cell_iommu_setup_stab(struct cbe_iommu *iommu,
unsigned long dbase, unsigned long dsize,
unsigned long fbase, unsigned long fsize)
{
struct page *page;
- int i;
- unsigned long reg, segments, pages_per_segment, ptab_size, stab_size,
- n_pte_pages, base;
-
- base = dbase;
- if (fsize != 0)
- base = min(fbase, dbase);
+ unsigned long segments, stab_size;
segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT;
- pages_per_segment = 1ull << IO_PAGENO_BITS;
- pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n",
- __FUNCTION__, iommu->nid, segments, pages_per_segment);
+ pr_debug("%s: iommu[%d]: segments: %lu\n",
+ __FUNCTION__, iommu->nid, segments);
/* set up the segment table */
stab_size = segments * sizeof(unsigned long);
page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size));
BUG_ON(!page);
iommu->stab = page_address(page);
- clear_page(iommu->stab);
+ memset(iommu->stab, 0, stab_size);
+}
+
+static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
+ unsigned long base, unsigned long size, unsigned long gap_base,
+ unsigned long gap_size, unsigned long page_shift)
+{
+ struct page *page;
+ int i;
+ unsigned long reg, segments, pages_per_segment, ptab_size,
+ n_pte_pages, start_seg, *ptab;
+
+ start_seg = base >> IO_SEGMENT_SHIFT;
+ segments = size >> IO_SEGMENT_SHIFT;
+ pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift);
+ /* PTEs for each segment must start on a 4K bounday */
+ pages_per_segment = max(pages_per_segment,
+ (1 << 12) / sizeof(unsigned long));
- /* ... and the page tables. Since these are contiguous, we can treat
- * the page tables as one array of ptes, like pSeries does.
- */
ptab_size = segments * pages_per_segment * sizeof(unsigned long);
pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__,
iommu->nid, ptab_size, get_order(ptab_size));
page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size));
BUG_ON(!page);
- iommu->ptab = page_address(page);
- memset(iommu->ptab, 0, ptab_size);
+ ptab = page_address(page);
+ memset(ptab, 0, ptab_size);
- /* allocate a bogus page for the end of each mapping */
- page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
- BUG_ON(!page);
- iommu->pad_page = page_address(page);
- clear_page(iommu->pad_page);
-
- /* number of pages needed for a page table */
- n_pte_pages = (pages_per_segment *
- sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT;
+ /* number of 4K pages needed for a page table */
+ n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12;
pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n",
- __FUNCTION__, iommu->nid, iommu->stab, iommu->ptab,
+ __FUNCTION__, iommu->nid, iommu->stab, ptab,
n_pte_pages);
/* initialise the STEs */
reg = IOSTE_V | ((n_pte_pages - 1) << 5);
- if (IOMMU_PAGE_SIZE == 0x1000)
- reg |= IOSTE_PS_4K;
- else if (IOMMU_PAGE_SIZE == 0x10000)
- reg |= IOSTE_PS_64K;
- else {
- extern void __unknown_page_size_error(void);
- __unknown_page_size_error();
+ switch (page_shift) {
+ case 12: reg |= IOSTE_PS_4K; break;
+ case 16: reg |= IOSTE_PS_64K; break;
+ case 20: reg |= IOSTE_PS_1M; break;
+ case 24: reg |= IOSTE_PS_16M; break;
+ default: BUG();
}
+ gap_base = gap_base >> IO_SEGMENT_SHIFT;
+ gap_size = gap_size >> IO_SEGMENT_SHIFT;
+
pr_debug("Setting up IOMMU stab:\n");
- for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) {
- iommu->stab[i] = reg |
- (__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i);
+ for (i = start_seg; i < (start_seg + segments); i++) {
+ if (i >= gap_base && i < (gap_base + gap_size)) {
+ pr_debug("\toverlap at %d, skipping\n", i);
+ continue;
+ }
+ iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) *
+ (i - start_seg));
pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
}
+
+ return ptab;
}
static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
@@ -423,7 +430,9 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
static void cell_iommu_setup_hardware(struct cbe_iommu *iommu,
unsigned long base, unsigned long size)
{
- cell_iommu_setup_page_tables(iommu, base, size, 0, 0);
+ cell_iommu_setup_stab(iommu, base, size, 0, 0);
+ iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0,
+ IOMMU_PAGE_SHIFT);
cell_iommu_enable_hardware(iommu);
}
@@ -464,6 +473,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
unsigned long pte_offset)
{
struct iommu_window *window;
+ struct page *page;
u32 ioid;
ioid = cell_iommu_get_ioid(np);
@@ -475,13 +485,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
window->size = size;
window->ioid = ioid;
window->iommu = iommu;
- window->pte_offset = pte_offset;
window->table.it_blocksize = 16;
window->table.it_base = (unsigned long)iommu->ptab;
window->table.it_index = iommu->nid;
- window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) +
- window->pte_offset;
+ window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset;
window->table.it_size = size >> IOMMU_PAGE_SHIFT;
iommu_init_table(&window->table, iommu->nid);
@@ -504,6 +512,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
* This code also assumes that we have a window that starts at 0,
* which is the case on all spider based blades.
*/
+ page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
+ BUG_ON(!page);
+ iommu->pad_page = page_address(page);
+ clear_page(iommu->pad_page);
+
__set_bit(0, window->table.it_map);
tce_build_cell(&window->table, window->table.it_offset, 1,
(unsigned long)iommu->pad_page, DMA_TO_DEVICE);
@@ -549,7 +562,7 @@ static void cell_dma_dev_setup_iommu(struct device *dev)
archdata->dma_data = &window->table;
}
-static void cell_dma_dev_setup_static(struct device *dev);
+static void cell_dma_dev_setup_fixed(struct device *dev);
static void cell_dma_dev_setup(struct device *dev)
{
@@ -557,7 +570,7 @@ static void cell_dma_dev_setup(struct device *dev)
/* Order is important here, these are not mutually exclusive */
if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
- cell_dma_dev_setup_static(dev);
+ cell_dma_dev_setup_fixed(dev);
else if (get_pci_dma_ops() == &dma_iommu_ops)
cell_dma_dev_setup_iommu(dev);
else if (get_pci_dma_ops() == &dma_direct_ops)
@@ -858,7 +871,7 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask)
return 0;
}
-static void cell_dma_dev_setup_static(struct device *dev)
+static void cell_dma_dev_setup_fixed(struct device *dev)
{
struct dev_archdata *archdata = &dev->archdata;
u64 addr;
@@ -869,35 +882,45 @@ static void cell_dma_dev_setup_static(struct device *dev)
dev_dbg(dev, "iommu: fixed addr = %lx\n", addr);
}
+static void insert_16M_pte(unsigned long addr, unsigned long *ptab,
+ unsigned long base_pte)
+{
+ unsigned long segment, offset;
+
+ segment = addr >> IO_SEGMENT_SHIFT;
+ offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24));
+ ptab = ptab + (segment * (1 << 12) / sizeof(unsigned long));
+
+ pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n",
+ addr, ptab, segment, offset);
+
+ ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask);
+}
+
static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
struct device_node *np, unsigned long dbase, unsigned long dsize,
unsigned long fbase, unsigned long fsize)
{
- unsigned long base_pte, uaddr, *io_pte;
- int i;
+ unsigned long base_pte, uaddr, ioaddr, *ptab;
- dma_iommu_fixed_base = fbase;
+ ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, dbase, dsize, 24);
- /* convert from bytes into page table indices */
- dbase = dbase >> IOMMU_PAGE_SHIFT;
- dsize = dsize >> IOMMU_PAGE_SHIFT;
- fbase = fbase >> IOMMU_PAGE_SHIFT;
- fsize = fsize >> IOMMU_PAGE_SHIFT;
+ dma_iommu_fixed_base = fbase;
pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
- io_pte = iommu->ptab;
base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW
| (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
- uaddr = 0;
- for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) {
+ for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
/* Don't touch the dynamic region */
- if (i >= dbase && i < (dbase + dsize)) {
- pr_debug("iommu: static/dynamic overlap, skipping\n");
+ ioaddr = uaddr + fbase;
+ if (ioaddr >= dbase && ioaddr < (dbase + dsize)) {
+ pr_debug("iommu: fixed/dynamic overlap, skipping\n");
continue;
}
- io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
+
+ insert_16M_pte(uaddr, ptab, base_pte);
}
mb();
@@ -995,7 +1018,9 @@ static int __init cell_iommu_fixed_mapping_init(void)
"fixed window 0x%lx-0x%lx\n", iommu->nid, dbase,
dbase + dsize, fbase, fbase + fsize);
- cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize);
+ cell_iommu_setup_stab(iommu, dbase, dsize, fbase, fsize);
+ iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0,
+ IOMMU_PAGE_SHIFT);
cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize,
fbase, fsize);
cell_iommu_enable_hardware(iommu);
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index a7f609b3b87..dda34650cb0 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -149,6 +149,11 @@ static void __init cell_init_irq(void)
mpic_init_IRQ();
}
+static void __init cell_set_dabrx(void)
+{
+ mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER);
+}
+
static void __init cell_setup_arch(void)
{
#ifdef CONFIG_SPU_BASE
@@ -158,6 +163,8 @@ static void __init cell_setup_arch(void)
cbe_regs_init();
+ cell_set_dabrx();
+
#ifdef CONFIG_CBE_RAS
cbe_ras_init();
#endif
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index e45cfa84911..712001f6b7d 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -81,9 +81,12 @@ struct spu_slb {
void spu_invalidate_slbs(struct spu *spu)
{
struct spu_priv2 __iomem *priv2 = spu->priv2;
+ unsigned long flags;
+ spin_lock_irqsave(&spu->register_lock, flags);
if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK)
out_be64(&priv2->slb_invalidate_all_W, 0UL);
+ spin_unlock_irqrestore(&spu->register_lock, flags);
}
EXPORT_SYMBOL_GPL(spu_invalidate_slbs);
@@ -148,7 +151,11 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
__func__, slbe, slb->vsid, slb->esid);
out_be64(&priv2->slb_index_W, slbe);
+ /* set invalid before writing vsid */
+ out_be64(&priv2->slb_esid_RW, 0);
+ /* now it's safe to write the vsid */
out_be64(&priv2->slb_vsid_RW, slb->vsid);
+ /* setting the new esid makes the entry valid again */
out_be64(&priv2->slb_esid_RW, slb->esid);
}
@@ -160,13 +167,6 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
pr_debug("%s\n", __FUNCTION__);
- if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags)) {
- /* SLBs are pre-loaded for context switch, so
- * we should never get here!
- */
- printk("%s: invalid access during switch!\n", __func__);
- return 1;
- }
slb.esid = (ea & ESID_MASK) | SLB_ESID_V;
switch(REGION_ID(ea)) {
@@ -226,11 +226,6 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
return 0;
}
- if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags)) {
- printk("%s: invalid access during switch!\n", __func__);
- return 1;
- }
-
spu->class_0_pending = 0;
spu->dar = ea;
spu->dsisr = dsisr;
@@ -302,9 +297,11 @@ void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
nr_slbs++;
}
+ spin_lock_irq(&spu->register_lock);
/* Add the set of SLBs */
for (i = 0; i < nr_slbs; i++)
spu_load_slb(spu, i, &slbs[i]);
+ spin_unlock_irq(&spu->register_lock);
}
EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs);
@@ -349,13 +346,14 @@ spu_irq_class_1(int irq, void *data)
if (stat & CLASS1_STORAGE_FAULT_INTR)
spu_mfc_dsisr_set(spu, 0ul);
spu_int_stat_clear(spu, 1, stat);
- spin_unlock(&spu->register_lock);
- pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
- dar, dsisr);
if (stat & CLASS1_SEGMENT_FAULT_INTR)
__spu_trap_data_seg(spu, dar);
+ spin_unlock(&spu->register_lock);
+ pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
+ dar, dsisr);
+
if (stat & CLASS1_STORAGE_FAULT_INTR)
__spu_trap_data_map(spu, dar, dsisr);
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 133995ed5cc..cf6c2c89211 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -109,13 +109,12 @@ void spu_forget(struct spu_context *ctx)
/*
* This is basically an open-coded spu_acquire_saved, except that
- * we don't acquire the state mutex interruptible.
+ * we don't acquire the state mutex interruptible, and we don't
+ * want this context to be rescheduled on release.
*/
mutex_lock(&ctx->state_mutex);
- if (ctx->state != SPU_STATE_SAVED) {
- set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
+ if (ctx->state != SPU_STATE_SAVED)
spu_deactivate(ctx);
- }
mm = ctx->owner;
ctx->owner = NULL;
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index c66c3756970..f7a7e8635fb 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -367,6 +367,13 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
return NOPFN_SIGBUS;
/*
+ * Because we release the mmap_sem, the context may be destroyed while
+ * we're in spu_wait. Grab an extra reference so it isn't destroyed
+ * in the meantime.
+ */
+ get_spu_context(ctx);
+
+ /*
* We have to wait for context to be loaded before we have
* pages to hand out to the user, but we don't want to wait
* with the mmap_sem held.
@@ -375,7 +382,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
* hanged.
*/
if (spu_acquire(ctx))
- return NOPFN_REFAULT;
+ goto refault;
if (ctx->state == SPU_STATE_SAVED) {
up_read(&current->mm->mmap_sem);
@@ -391,6 +398,9 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
if (!ret)
spu_release(ctx);
+
+refault:
+ put_spu_context(ctx);
return NOPFN_REFAULT;
}
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index fca22e18069..6221968c2a3 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -234,6 +234,7 @@ static int spu_run_fini(struct spu_context *ctx, u32 *npc,
*npc = ctx->ops->npc_read(ctx);
spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED);
+ ctx->policy = SCHED_IDLE;
spu_release(ctx);
if (signal_pending(current))
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 5915343e259..5d5f680cd0b 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -246,7 +246,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
spu_switch_notify(spu, ctx);
ctx->state = SPU_STATE_RUNNABLE;
- spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED);
+ spuctx_switch_state(ctx, SPU_UTIL_USER);
}
/*
@@ -856,21 +856,18 @@ static noinline void spusched_tick(struct spu_context *ctx)
{
struct spu_context *new = NULL;
struct spu *spu = NULL;
- u32 status;
if (spu_acquire(ctx))
BUG(); /* a kernel thread never has signals pending */
if (ctx->state != SPU_STATE_RUNNABLE)
goto out;
- if (spu_stopped(ctx, &status))
- goto out;
if (ctx->flags & SPU_CREATE_NOSCHED)
goto out;
if (ctx->policy == SCHED_FIFO)
goto out;
- if (--ctx->time_slice)
+ if (--ctx->time_slice && ctx->policy != SCHED_IDLE)
goto out;
spu = ctx->spu;
@@ -880,7 +877,8 @@ static noinline void spusched_tick(struct spu_context *ctx)
new = grab_runnable_context(ctx->prio + 1, spu->node);
if (new) {
spu_unschedule(spu, ctx);
- spu_add_to_rq(ctx);
+ if (ctx->policy != SCHED_IDLE)
+ spu_add_to_rq(ctx);
} else {
spu_context_nospu_trace(spusched_tick__newslice, ctx);
ctx->time_slice++;
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c
index 01974f7776e..79aa773f3c9 100644
--- a/arch/powerpc/platforms/cell/spufs/sputrace.c
+++ b/arch/powerpc/platforms/cell/spufs/sputrace.c
@@ -58,12 +58,12 @@ static int sputrace_sprint(char *tbuf, int n)
ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));
return snprintf(tbuf, n,
- "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n",
+ "[%lu.%09lu] %d: %s (ctxthread = %d, spu = %d)\n",
(unsigned long) tv.tv_sec,
(unsigned long) tv.tv_nsec,
- t->owner_tid,
- t->name,
t->curr_tid,
+ t->name,
+ t->owner_tid,
t->number);
}
@@ -188,6 +188,7 @@ struct spu_probe spu_probes[] = {
{ "spufs_ps_nopfn__insert", "%p %p", spu_context_event },
{ "spu_acquire_saved__enter", "%p", spu_context_nospu_event },
{ "destroy_spu_context__enter", "%p", spu_context_nospu_event },
+ { "spufs_stop_callback__enter", "%p %p", spu_context_event },
};
static int __init sputrace_init(void)
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 6063c88c26d..e9dc7a55d1b 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -34,6 +34,7 @@
#include <linux/module.h>
#include <linux/errno.h>
+#include <linux/hardirq.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@@ -117,6 +118,8 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
* Write INT_MASK_class1 with value of 0.
* Save INT_Mask_class2 in CSA.
* Write INT_MASK_class2 with value of 0.
+ * Synchronize all three interrupts to be sure
+ * we no longer execute a handler on another CPU.
*/
spin_lock_irq(&spu->register_lock);
if (csa) {
@@ -129,6 +132,9 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
spu_int_mask_set(spu, 2, 0ul);
eieio();
spin_unlock_irq(&spu->register_lock);
+ synchronize_irq(spu->irqs[0]);
+ synchronize_irq(spu->irqs[1]);
+ synchronize_irq(spu->irqs[2]);
}
static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu)
@@ -720,8 +726,9 @@ static inline void set_switch_active(struct spu_state *csa, struct spu *spu)
* Restore, Step 23.
* Change the software context switch pending flag
* to context switch active.
+ *
+ * This implementation does not uses a switch active flag.
*/
- set_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags);
clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
mb();
}
@@ -1739,9 +1746,8 @@ static inline void reset_switch_active(struct spu_state *csa, struct spu *spu)
{
/* Restore, Step 74:
* Reset the "context switch active" flag.
+ * Not performed by this implementation.
*/
- clear_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags);
- mb();
}
static inline void reenable_interrupts(struct spu_state *csa, struct spu *spu)
diff --git a/arch/powerpc/platforms/celleb/beat.h b/arch/powerpc/platforms/celleb/beat.h
index b2e292df13c..ac82ac35b99 100644
--- a/arch/powerpc/platforms/celleb/beat.h
+++ b/arch/powerpc/platforms/celleb/beat.h
@@ -21,9 +21,6 @@
#ifndef _CELLEB_BEAT_H
#define _CELLEB_BEAT_H
-#define DABRX_KERNEL (1UL<<1)
-#define DABRX_USER (1UL<<0)
-
int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*);
int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t);
int64_t beat_repository_encode(int, const char *, uint64_t[4]);
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile
index 8f52d751579..ce6d789e074 100644
--- a/arch/powerpc/platforms/pasemi/Makefile
+++ b/arch/powerpc/platforms/pasemi/Makefile
@@ -1,3 +1,3 @@
-obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o
+obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o misc.o
obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o
obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
diff --git a/arch/powerpc/platforms/pasemi/misc.c b/arch/powerpc/platforms/pasemi/misc.c
new file mode 100644
index 00000000000..ded7d152d00
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/misc.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007 PA Semi, Inc
+ *
+ * Parts based on arch/powerpc/sysdev/fsl_soc.c:
+ *
+ * 2006 (c) MontaVista Software, 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.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/of.h>
+#include <linux/i2c.h>
+
+#ifdef CONFIG_I2C_BOARDINFO
+/* The below is from fsl_soc.c. It's copied because since there are no
+ * official bus bindings at this time it doesn't make sense to share across
+ * the platforms, even though they happen to be common.
+ */
+struct i2c_driver_device {
+ char *of_device;
+ char *i2c_driver;
+ char *i2c_type;
+};
+
+static struct i2c_driver_device i2c_devices[] __initdata = {
+ {"dallas,ds1338", "rtc-ds1307", "ds1338"},
+};
+
+static int __init find_i2c_driver(struct device_node *node,
+ struct i2c_board_info *info)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
+ if (!of_device_is_compatible(node, i2c_devices[i].of_device))
+ continue;
+ if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver,
+ KOBJ_NAME_LEN) >= KOBJ_NAME_LEN ||
+ strlcpy(info->type, i2c_devices[i].i2c_type,
+ I2C_NAME_SIZE) >= I2C_NAME_SIZE)
+ return -ENOMEM;
+ return 0;
+ }
+ return -ENODEV;
+}
+
+static int __init pasemi_register_i2c_devices(void)
+{
+ struct pci_dev *pdev;
+ struct device_node *adap_node;
+ struct device_node *node;
+
+ pdev = NULL;
+ while ((pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa003, pdev))) {
+ adap_node = pci_device_to_OF_node(pdev);
+
+ if (!adap_node)
+ continue;
+
+ node = NULL;
+ while ((node = of_get_next_child(adap_node, node))) {
+ struct i2c_board_info info = {};
+ const u32 *addr;
+ int len;
+
+ addr = of_get_property(node, "reg", &len);
+ if (!addr || len < sizeof(int) ||
+ *addr > (1 << 10) - 1) {
+ printk(KERN_WARNING
+ "pasemi_register_i2c_devices: "
+ "invalid i2c device entry\n");
+ continue;
+ }
+
+ info.irq = irq_of_parse_and_map(node, 0);
+ if (info.irq == NO_IRQ)
+ info.irq = -1;
+
+ if (find_i2c_driver(node, &info) < 0)
+ continue;
+
+ info.addr = *addr;
+
+ i2c_register_board_info(PCI_FUNC(pdev->devfn), &info,
+ 1);
+ }
+ }
+ return 0;
+}
+device_initcall(pasemi_register_i2c_devices);
+#endif
diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c
index e95fc1594c8..6d626623644 100644
--- a/arch/powerpc/platforms/pseries/power.c
+++ b/arch/powerpc/platforms/pseries/power.c
@@ -75,7 +75,7 @@ core_initcall(pm_init);
#else
static int __init apo_pm_init(void)
{
- return (sysfs_create_file(power_kobj, &auto_poweron_attr));
+ return (sysfs_create_file(power_kobj, &auto_poweron_attr.attr));
}
__initcall(apo_pm_init);
#endif
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
index d6bfda30ac8..33cbfb22ce3 100644
--- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -95,7 +95,6 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
unsigned int virq;
struct msi_desc *entry;
struct msi_msg msg;
- u64 addr;
pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n",
pdev, nvec, type);
@@ -132,8 +131,8 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
set_irq_chip(virq, &mpic_pasemi_msi_chip);
set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
- pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%lx\n",
- virq, hwirq, addr);
+ pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%x\n",
+ virq, hwirq, msg.address_lo);
/* Likewise, the device writes [0...511] into the target
* register to generate MSI [512...1023]
diff --git a/arch/ppc/platforms/4xx/ibm440ep.c b/arch/ppc/platforms/4xx/ibm440ep.c
index 1fed6638c81..0de91532aab 100644
--- a/arch/ppc/platforms/4xx/ibm440ep.c
+++ b/arch/ppc/platforms/4xx/ibm440ep.c
@@ -172,11 +172,11 @@ struct ocp_def core_ocp[] = {
/* Polarity and triggering settings for internal interrupt sources */
struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
{ .polarity = 0xffbffe03,
- .triggering = 0xfffffe00,
+ .triggering = 0x00000000,
.ext_irq_mask = 0x000001fc, /* IRQ0 - IRQ6 */
},
- { .polarity = 0xffffc6ef,
- .triggering = 0xffffc7ff,
+ { .polarity = 0xffffc6af,
+ .triggering = 0x06000140,
.ext_irq_mask = 0x00003800, /* IRQ7 - IRQ9 */
},
};
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 92a4f7b4323..1831833c430 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -61,6 +61,7 @@ config S390
def_bool y
select HAVE_OPROFILE
select HAVE_KPROBES
+ select HAVE_KRETPROBES
source "init/Kconfig"
@@ -100,7 +101,8 @@ config NR_CPUS
int "Maximum number of CPUs (2-64)"
range 2 64
depends on SMP
- default "32"
+ default "32" if !64BIT
+ default "64" if 64BIT
help
This allows you to specify the maximum number of CPUs which this
kernel will support. The maximum supported value is 64 and the
@@ -349,6 +351,10 @@ endchoice
source "fs/Kconfig.binfmt"
+config FORCE_MAX_ZONEORDER
+ int
+ default "9"
+
config PROCESS_DEBUG
bool "Show crashed user process info"
help
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 39921f3a968..62f6b5a606d 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24
-# Sat Feb 9 12:13:01 2008
+# Linux kernel version: 2.6.25-rc4
+# Wed Mar 5 11:22:59 2008
#
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
@@ -43,12 +43,15 @@ CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_NS=y
# CONFIG_CPUSETS is not set
+CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# 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
+CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
@@ -85,7 +88,9 @@ CONFIG_SLAB=y
# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -185,6 +190,7 @@ CONFIG_IPL=y
CONFIG_IPL_VM=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
+CONFIG_FORCE_MAX_ZONEORDER=9
# CONFIG_PROCESS_DEBUG is not set
CONFIG_PFAULT=y
# CONFIG_SHARED_KERNEL is not set
@@ -435,6 +441,7 @@ CONFIG_DASD_EER=y
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HAVE_IDE is not set
#
# SCSI device support
@@ -593,6 +600,7 @@ CONFIG_S390_VMUR=m
#
# Sonics Silicon Backplane
#
+# CONFIG_MEMSTICK is not set
#
# File systems
@@ -750,7 +758,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_FRAME_POINTER is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
@@ -759,6 +766,7 @@ CONFIG_FORCED_INLINING=y
# CONFIG_LATENCYTOP is not set
CONFIG_SAMPLES=y
# CONFIG_SAMPLE_KOBJECT is not set
+# CONFIG_SAMPLE_KPROBES is not set
# CONFIG_DEBUG_PAGEALLOC is not set
#
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index b3b650a93c7..4d3e38392cb 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -4,6 +4,11 @@
EXTRA_AFLAGS := -traditional
+#
+# Passing null pointers is ok for smp code, since we access the lowcore here.
+#
+CFLAGS_smp.o := -Wno-nonnull
+
obj-y := bitmap.o traps.o time.o process.o base.o early.o \
setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 9f7b73b180f..01832c44063 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -88,13 +88,17 @@ static noinline __init void create_kernel_nss(void)
__cpcmd(defsys_cmd, NULL, 0, &response);
- if (response != 0)
+ if (response != 0) {
+ kernel_nss_name[0] = '\0';
return;
+ }
__cpcmd(savesys_cmd, NULL, 0, &response);
- if (response != strlen(savesys_cmd))
+ if (response != strlen(savesys_cmd)) {
+ kernel_nss_name[0] = '\0';
return;
+ }
ipl_flags = IPL_NSS_VALID;
}
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 60acdc266db..375232c46c7 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -704,6 +704,7 @@ void reipl_run(struct shutdown_trigger *trigger)
default:
break;
}
+ disabled_wait((unsigned long) __builtin_return_address(0));
}
static void __init reipl_probe(void)
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index a6a4729e0e9..ce203154d8c 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -114,24 +114,27 @@ extern void s390_handle_mcck(void);
static void default_idle(void)
{
int cpu, rc;
+ int nr_calls = 0;
+ void *hcpu;
#ifdef CONFIG_SMP
struct s390_idle_data *idle;
#endif
/* CPU is going idle. */
cpu = smp_processor_id();
-
+ hcpu = (void *)(long)cpu;
local_irq_disable();
if (need_resched()) {
local_irq_enable();
return;
}
- rc = atomic_notifier_call_chain(&idle_chain,
- S390_CPU_IDLE, (void *)(long) cpu);
- if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
- BUG();
- if (rc != NOTIFY_OK) {
+ rc = __atomic_notifier_call_chain(&idle_chain, S390_CPU_IDLE, hcpu, -1,
+ &nr_calls);
+ if (rc == NOTIFY_BAD) {
+ nr_calls--;
+ __atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
+ hcpu, nr_calls, NULL);
local_irq_enable();
return;
}
@@ -149,6 +152,10 @@ static void default_idle(void)
local_mcck_disable();
if (test_thread_flag(TIF_MCCK_PENDING)) {
local_mcck_enable();
+ /* disable monitor call class 0 */
+ __ctl_clear_bit(8, 15);
+ atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
+ hcpu);
local_irq_enable();
s390_handle_mcck();
return;
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 85060659fb1..8f894d380a6 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -626,13 +626,11 @@ static int __cpuinit smp_alloc_lowcore(int cpu)
if (!lowcore)
return -ENOMEM;
async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
- if (!async_stack)
- goto out_async_stack;
panic_stack = __get_free_page(GFP_KERNEL);
- if (!panic_stack)
- goto out_panic_stack;
-
- *lowcore = S390_lowcore;
+ if (!panic_stack || !async_stack)
+ goto out;
+ memcpy(lowcore, &S390_lowcore, 512);
+ memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
lowcore->async_stack = async_stack + ASYNC_SIZE;
lowcore->panic_stack = panic_stack + PAGE_SIZE;
@@ -653,9 +651,8 @@ static int __cpuinit smp_alloc_lowcore(int cpu)
out_save_area:
free_page(panic_stack);
#endif
-out_panic_stack:
+out:
free_pages(async_stack, ASYNC_ORDER);
-out_async_stack:
free_pages((unsigned long) lowcore, lc_order);
return -ENOMEM;
}
@@ -719,8 +716,8 @@ int __cpuinit __cpu_up(unsigned int cpu)
cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
cpu_lowcore->current_task = (unsigned long) idle;
cpu_lowcore->cpu_data.cpu_nr = cpu;
- cpu_lowcore->softirq_pending = 0;
- cpu_lowcore->ext_call_fast = 0;
+ cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce;
+ cpu_lowcore->ipl_device = S390_lowcore.ipl_device;
eieio();
while (signal_processor(cpu, sigp_restart) == sigp_busy)
@@ -797,23 +794,43 @@ void cpu_die(void)
void __init smp_prepare_cpus(unsigned int max_cpus)
{
+#ifndef CONFIG_64BIT
+ unsigned long save_area = 0;
+#endif
+ unsigned long async_stack, panic_stack;
+ struct _lowcore *lowcore;
unsigned int cpu;
+ int lc_order;
smp_detect_cpus();
/* request the 0x1201 emergency signal external interrupt */
if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
panic("Couldn't request external interrupt 0x1201");
- memset(lowcore_ptr, 0, sizeof(lowcore_ptr));
print_cpu_info(&S390_lowcore.cpu_data);
- smp_alloc_lowcore(smp_processor_id());
+ /* Reallocate current lowcore, but keep its contents. */
+ lc_order = sizeof(long) == 8 ? 1 : 0;
+ lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order);
+ panic_stack = __get_free_page(GFP_KERNEL);
+ async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
#ifndef CONFIG_64BIT
if (MACHINE_HAS_IEEE)
- ctl_set_bit(14, 29); /* enable extended save area */
+ save_area = get_zeroed_page(GFP_KERNEL);
#endif
- set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]);
-
+ local_irq_disable();
+ local_mcck_disable();
+ lowcore_ptr[smp_processor_id()] = lowcore;
+ *lowcore = S390_lowcore;
+ lowcore->panic_stack = panic_stack + PAGE_SIZE;
+ lowcore->async_stack = async_stack + ASYNC_SIZE;
+#ifndef CONFIG_64BIT
+ if (MACHINE_HAS_IEEE)
+ lowcore->extended_save_area_addr = (u32) save_area;
+#endif
+ set_prefix((u32)(unsigned long) lowcore);
+ local_mcck_enable();
+ local_irq_enable();
for_each_possible_cpu(cpu)
if (cpu != smp_processor_id())
smp_create_idle(cpu);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 3bbac1293be..cb232c15536 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -209,8 +209,6 @@ static void stop_hz_timer(void)
*/
static void start_hz_timer(void)
{
- BUG_ON(!in_interrupt());
-
if (!cpu_isset(smp_processor_id(), nohz_cpu_mask))
return;
account_ticks(get_clock());
@@ -744,7 +742,6 @@ static void etr_adjust_time(unsigned long long clock, unsigned long long delay)
}
}
-#ifdef CONFIG_SMP
static void etr_sync_cpu_start(void *dummy)
{
int *in_sync = dummy;
@@ -777,7 +774,6 @@ static void etr_sync_cpu_start(void *dummy)
static void etr_sync_cpu_end(void *dummy)
{
}
-#endif /* CONFIG_SMP */
/*
* Sync the TOD clock using the port refered to by aibp. This port
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c
index 28c4500a58d..d2ffbadb51a 100644
--- a/arch/s390/lib/uaccess_std.c
+++ b/arch/s390/lib/uaccess_std.c
@@ -293,10 +293,10 @@ int futex_atomic_cmpxchg_std(int __user *uaddr, int oldval, int newval)
asm volatile(
" sacf 256\n"
- " cs %1,%4,0(%5)\n"
- "0: lr %0,%1\n"
- "1: sacf 0\n"
- EX_TABLE(0b,1b)
+ "0: cs %1,%4,0(%5)\n"
+ "1: lr %0,%1\n"
+ "2: sacf 0\n"
+ EX_TABLE(0b,2b) EX_TABLE(1b,2b)
: "=d" (ret), "+d" (oldval), "=m" (*uaddr)
: "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
: "cc", "memory" );
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index b3400b5ad5c..95b7534e9e3 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -330,6 +330,7 @@ config CPU_SUBTYPE_SH5_101
config CPU_SUBTYPE_SH5_103
bool "Support SH5-103 processor"
+ select CPU_SH5
endchoice
@@ -455,13 +456,6 @@ config SH_SECUREEDGE5410
This includes both the OEM SecureEdge products as well as the
SME product line.
-config SH_7710VOIPGW
- bool "SH7710-VOIP-GW"
- depends on CPU_SUBTYPE_SH7710
- help
- Select this option to build a kernel for the SH7710 based
- VOIP GW.
-
config SH_RTS7751R2D
bool "RTS7751R2D"
depends on CPU_SUBTYPE_SH7751R
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 81381e5773c..c510c225144 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -118,7 +118,6 @@ machdir-$(CONFIG_SH_EDOSK7705) += renesas/edosk7705
machdir-$(CONFIG_SH_HIGHLANDER) += renesas/r7780rp
machdir-$(CONFIG_SH_MIGOR) += renesas/migor
machdir-$(CONFIG_SH_SDK7780) += renesas/sdk7780
-machdir-$(CONFIG_SH_7710VOIPGW) += renesas/sh7710voipgw
machdir-$(CONFIG_SH_X3PROTO) += renesas/x3proto
machdir-$(CONFIG_SH_SH4202_MICRODEV) += superh/microdev
machdir-$(CONFIG_SH_LANDISK) += landisk
diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c
index 640ca2a74f1..177f4f028e0 100644
--- a/arch/sh/boards/hp6xx/hp6xx_apm.c
+++ b/arch/sh/boards/hp6xx/hp6xx_apm.c
@@ -2,6 +2,7 @@
* bios-less APM driver for hp680
*
* Copyright 2005 (c) Andriy Skulysh <askulysh@gmail.com>
+ * Copyright 2008 (c) Kristoffer Ericson <kristoffer.ericson@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License.
@@ -15,17 +16,19 @@
#include <asm/adc.h>
#include <asm/hp6xx.h>
-#define SH7709_PGDR 0xa400012c
-
+/* percentage values */
#define APM_CRITICAL 10
#define APM_LOW 30
+/* resonably sane values */
#define HP680_BATTERY_MAX 898
#define HP680_BATTERY_MIN 486
#define HP680_BATTERY_AC_ON 1023
#define MODNAME "hp6x0_apm"
+#define PGDR 0xa400012c
+
static void hp6x0_apm_get_power_status(struct apm_power_info *info)
{
int battery, backup, charging, percentage;
@@ -38,17 +41,26 @@ static void hp6x0_apm_get_power_status(struct apm_power_info *info)
percentage = 100 * (battery - HP680_BATTERY_MIN) /
(HP680_BATTERY_MAX - HP680_BATTERY_MIN);
+ /* % of full battery */
+ info->battery_life = percentage;
+
+ /* We want our estimates in minutes */
+ info->units = 0;
+
+ /* Extremely(!!) rough estimate, we will replace this with a datalist later on */
+ info->time = (2 * battery);
+
info->ac_line_status = (battery > HP680_BATTERY_AC_ON) ?
APM_AC_ONLINE : APM_AC_OFFLINE;
- pgdr = ctrl_inb(SH7709_PGDR);
+ pgdr = ctrl_inb(PGDR);
if (pgdr & PGDR_MAIN_BATTERY_OUT) {
info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT;
info->battery_flag = 0x80;
} else if (charging < 8) {
info->battery_status = APM_BATTERY_STATUS_CHARGING;
info->battery_flag = 0x08;
- info->ac_line_status = 0xff;
+ info->ac_line_status = 0x01;
} else if (percentage <= APM_CRITICAL) {
info->battery_status = APM_BATTERY_STATUS_CRITICAL;
info->battery_flag = 0x04;
@@ -59,8 +71,6 @@ static void hp6x0_apm_get_power_status(struct apm_power_info *info)
info->battery_status = APM_BATTERY_STATUS_HIGH;
info->battery_flag = 0x01;
}
-
- info->units = 0;
}
static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev)
diff --git a/arch/sh/boards/renesas/sh7710voipgw/Makefile b/arch/sh/boards/renesas/sh7710voipgw/Makefile
deleted file mode 100644
index 77037567633..00000000000
--- a/arch/sh/boards/renesas/sh7710voipgw/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-y := setup.o
diff --git a/arch/sh/boards/renesas/sh7710voipgw/setup.c b/arch/sh/boards/renesas/sh7710voipgw/setup.c
deleted file mode 100644
index 0d56fd83bcb..00000000000
--- a/arch/sh/boards/renesas/sh7710voipgw/setup.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Renesas Technology SH7710 VoIP Gateway
- *
- * Copyright (C) 2006 Ranjit Deshpande
- * Kenati Technologies Inc.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- */
-#include <linux/init.h>
-#include <asm/machvec.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-static struct ipr_data sh7710voipgw_ipr_map[] = {
- { TIMER2_IRQ, TIMER2_IPR_ADDR, TIMER2_IPR_POS, TIMER2_PRIORITY },
- { WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY },
-
- /* SCIF0 */
- { SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
- { SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
- { SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
- { SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
-
- /* DMAC-1 */
- { DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
- { DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
- { DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
- { DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
-
- /* DMAC-2 */
- { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
- { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
-
- /* IPSEC */
- { IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY },
-
- /* EDMAC */
- { EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS, EDMAC0_PRIORITY },
- { EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS, EDMAC1_PRIORITY },
- { EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS, EDMAC2_PRIORITY },
-
- /* SIOF0 */
- { SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
- { SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
- { SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
- { SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
-
- /* SIOF1 */
- { SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
- { SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
- { SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
- { SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
-
- /* SLIC IRQ's */
- { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY },
- { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY },
-};
-
-/*
- * Initialize IRQ setting
- */
-static void __init sh7710voipgw_init_irq(void)
-{
- /* Disable all interrupts in IPR registers */
- ctrl_outw(0x0, INTC_IPRA);
- ctrl_outw(0x0, INTC_IPRB);
- ctrl_outw(0x0, INTC_IPRC);
- ctrl_outw(0x0, INTC_IPRD);
- ctrl_outw(0x0, INTC_IPRE);
- ctrl_outw(0x0, INTC_IPRF);
- ctrl_outw(0x0, INTC_IPRG);
- ctrl_outw(0x0, INTC_IPRH);
- ctrl_outw(0x0, INTC_IPRI);
-
- /* Ack all interrupt sources in the IRR0 register */
- ctrl_outb(0x3f, INTC_IRR0);
-
- /* Use IRQ0 - IRQ3 as active low interrupt lines i.e. disable
- * IRL mode.
- */
- ctrl_outw(0x2aa, INTC_ICR1);
-
- make_ipr_irq(sh7710voipgw_ipr_map, ARRAY_SIZE(sh7710voipgw_ipr_map));
-}
-
-/*
- * The Machine Vector
- */
-static struct sh_machine_vector mv_sh7710voipgw __initmv = {
- .mv_name = "SH7710 VoIP Gateway",
- .mv_nr_irqs = 104,
- .mv_init_irq = sh7710voipgw_init_irq,
-};
diff --git a/arch/sh/boards/renesas/x3proto/ilsel.c b/arch/sh/boards/renesas/x3proto/ilsel.c
index 6d4454fef97..b5c673c3933 100644
--- a/arch/sh/boards/renesas/x3proto/ilsel.c
+++ b/arch/sh/boards/renesas/x3proto/ilsel.c
@@ -68,7 +68,7 @@ static void __ilsel_enable(ilsel_source_t set, unsigned int bit)
shift = mk_ilsel_shift(bit);
pr_debug("%s: bit#%d: addr - 0x%08lx (shift %d, set %d)\n",
- __FUNCTION__, bit, addr, shift, set);
+ __func__, bit, addr, shift, set);
tmp = ctrl_inw(addr);
tmp &= ~(0xf << shift);
diff --git a/arch/sh/boards/superh/microdev/io.c b/arch/sh/boards/superh/microdev/io.c
index b704e20d7e4..9f8a540f7e1 100644
--- a/arch/sh/boards/superh/microdev/io.c
+++ b/arch/sh/boards/superh/microdev/io.c
@@ -127,7 +127,7 @@ static unsigned long microdev_isa_port2addr(unsigned long offset)
* safe default.
*/
printk("Warning: unexpected port in %s( offset = 0x%lx )\n",
- __FUNCTION__, offset);
+ __func__, offset);
result = PVR;
}
diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig
index 2ad804ec920..1a072615ffd 100644
--- a/arch/sh/configs/r7780mp_defconfig
+++ b/arch/sh/configs/r7780mp_defconfig
@@ -1,9 +1,10 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc2
-# Tue Nov 13 20:32:39 2007
+# Linux kernel version: 2.6.25-rc4
+# Thu Mar 6 15:39:59 2008
#
CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
@@ -19,6 +20,8 @@ CONFIG_LOCKDEP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -37,17 +40,20 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_USER_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=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_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
@@ -61,17 +67,27 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_HAVE_KPROBES is not set
+# CONFIG_HAVE_KRETPROBES is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
@@ -98,6 +114,8 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
#
# System type
@@ -105,7 +123,9 @@ CONFIG_DEFAULT_IOSCHED="noop"
CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
@@ -114,6 +134,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7710 is not set
# CONFIG_CPU_SUBTYPE_SH7712 is not set
# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
# CONFIG_CPU_SUBTYPE_SH7750 is not set
# CONFIG_CPU_SUBTYPE_SH7091 is not set
# CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -122,12 +143,16 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7785 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -137,7 +162,8 @@ CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-# CONFIG_32BIT is not set
+CONFIG_29BIT=y
+# CONFIG_PMB is not set
CONFIG_VSYSCALL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -153,6 +179,7 @@ CONFIG_HUGETLB_PAGE_SIZE_64K=y
# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -190,6 +217,7 @@ CONFIG_CPU_HAS_FPU=y
# Board support
#
# CONFIG_SH_7780_SOLUTION_ENGINE is not set
+# CONFIG_SH_SDK7780 is not set
CONFIG_SH_HIGHLANDER=y
# CONFIG_SH_R7780RP is not set
CONFIG_SH_R7780MP=y
@@ -234,12 +262,13 @@ 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_KEXEC=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
+CONFIG_RCU_TRACE=y
CONFIG_GUSA=y
#
@@ -284,6 +313,7 @@ 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
@@ -344,6 +374,7 @@ CONFIG_LLC=m
#
# 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
@@ -386,7 +417,7 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
CONFIG_MISC_DEVICES=y
@@ -394,6 +425,8 @@ CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_93CX6=y
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -453,6 +486,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
@@ -506,6 +540,7 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_NS87415 is not set
# CONFIG_PATA_OPTI is not set
@@ -538,7 +573,6 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
@@ -551,7 +585,6 @@ CONFIG_AX88796_93CX6=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
-# CONFIG_SMC911X is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -576,6 +609,7 @@ CONFIG_8139TOO=m
# CONFIG_8139TOO_TUNE_TWISTER is not set
CONFIG_8139TOO_8129=y
# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
@@ -591,6 +625,9 @@ CONFIG_E1000=m
# CONFIG_E1000_NAPI is not set
# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED 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
@@ -616,6 +653,7 @@ CONFIG_NETDEV_10000=y
# CONFIG_NIU is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
# CONFIG_TR is not set
#
@@ -629,7 +667,6 @@ CONFIG_NETDEV_10000=y
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_FC 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
@@ -686,6 +723,7 @@ CONFIG_SERIO_LIBPS2=y
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -722,6 +760,7 @@ CONFIG_DEVPORT=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_IT87 is not set
@@ -736,6 +775,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_THERMAL=y
# CONFIG_WATCHDOG is not set
#
@@ -800,12 +840,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk 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_INFINIBAND is not set
CONFIG_RTC_LIB=y
@@ -830,9 +867,10 @@ CONFIG_RTC_INTF_DEV=y
#
# Platform RTC drivers
#
+# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_V3020 is not set
@@ -867,12 +905,10 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-CONFIG_MINIX_FS=y
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=m
@@ -920,8 +956,10 @@ CONFIG_CONFIGFS_FS=m
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=y
# 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
@@ -997,10 +1035,6 @@ CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
# CONFIG_DLM is not set
-CONFIG_INSTRUMENTATION=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-# CONFIG_MARKERS is not set
#
# Kernel hacking
@@ -1035,9 +1069,9 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_FRAME_POINTER is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SAMPLES is not set
CONFIG_SH_STANDARD_BIOS=y
@@ -1059,6 +1093,7 @@ CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
@@ -1077,6 +1112,9 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -1091,13 +1129,16 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
#
# Library routines
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig
index f68743dc393..30f5ee40c31 100644
--- a/arch/sh/configs/se7780_defconfig
+++ b/arch/sh/configs/se7780_defconfig
@@ -1,9 +1,10 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc3
-# Thu Mar 15 14:06:20 2007
+# Linux kernel version: 2.6.25-rc3
+# Thu Feb 28 10:18:04 2008
#
CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
@@ -11,38 +12,44 @@ CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-# CONFIG_GENERIC_TIME is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
# CONFIG_EXPERIMENTAL is not set
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_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=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
@@ -52,31 +59,36 @@ CONFIG_SYSCTL_SYSCALL=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 is not set
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_SLAB=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_KPROBES is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
-
-#
-# Block layer
-#
CONFIG_BLOCK=y
# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
#
@@ -91,68 +103,27 @@ CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
#
# System type
#
-CONFIG_SOLUTION_ENGINE=y
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-CONFIG_SH_7780_SOLUTION_ENGINE=y
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_7343_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_7710VOIPGW is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_HIGHLANDER is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-# CONFIG_SH_TITAN is not set
-# CONFIG_SH_SHMIN is not set
-# CONFIG_SH_7206_SOLUTION_ENGINE is not set
-# CONFIG_SH_7619_SOLUTION_ENGINE is not set
-# CONFIG_SH_UNKNOWN is not set
-
-#
-# Processor selection
-#
CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
# CONFIG_CPU_SUBTYPE_SH7619 is not set
-
-#
-# SH-2A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
# CONFIG_CPU_SUBTYPE_SH7206 is not set
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
# CONFIG_CPU_SUBTYPE_SH7710 is not set
-
-#
-# SH-4 Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
# CONFIG_CPU_SUBTYPE_SH7750 is not set
# CONFIG_CPU_SUBTYPE_SH7091 is not set
# CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -161,52 +132,58 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7785 is not set
-
-#
-# SH4AL-DSP Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
#
+CONFIG_QUICKLIST=y
CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_32BIT=y
+CONFIG_29BIT=y
+# CONFIG_PMB is not set
CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
#
# Cache configuration
#
# CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
#
# Processor features
@@ -214,20 +191,29 @@ CONFIG_ZONE_DMA_FLAG=0
CONFIG_CPU_LITTLE_ENDIAN=y
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_SH_FPU=y
-# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
CONFIG_CPU_HAS_INTEVT=y
-CONFIG_CPU_HAS_INTC2_IRQ=y
-CONFIG_CPU_HAS_INTC_IRQ=y
CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+CONFIG_SOLUTION_ENGINE=y
+CONFIG_SH_7780_SOLUTION_ENGINE=y
+# CONFIG_SH_SDK7780 is not set
+# CONFIG_SH_HIGHLANDER is not set
#
# Timer and clock configuration
#
CONFIG_SH_TMU=y
CONFIG_SH_TIMER_IRQ=28
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_SH_PCLK_FREQ=33333333
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
# CPU Frequency scaling
@@ -242,7 +228,6 @@ CONFIG_SH_PCLK_FREQ=33333333
#
# Companion Chips
#
-# CONFIG_HD6446X_SERIES is not set
#
# Additional SuperH Device Drivers
@@ -258,40 +243,36 @@ CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
-# CONFIG_SMP is not set
+# CONFIG_SCHED_HRTICK is not set
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
+CONFIG_GUSA=y
#
# Boot options
#
CONFIG_ZERO_PAGE_OFFSET=0x00001000
CONFIG_BOOT_LINK_OFFSET=0x00810000
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0.115200 root=/dev/sda1"
#
# Bus options
#
+# CONFIG_CF_ENABLER is not set
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-
-#
-# PCI Hotplug Support
-#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
# CONFIG_BINFMT_MISC is not set
#
@@ -302,7 +283,6 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -329,6 +309,7 @@ CONFIG_IP_PNP=y
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
@@ -349,16 +330,13 @@ CONFIG_IPV6=y
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
+# CONFIG_ATM is not set
# CONFIG_BRIDGE 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
-
-#
-# QoS and/or fair queueing
-#
# CONFIG_NET_SCHED is not set
#
@@ -366,9 +344,18 @@ CONFIG_IPV6=y
#
# 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
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
#
# Device Drivers
@@ -380,15 +367,7 @@ CONFIG_IPV6=y
CONFIG_STANDALONE=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
@@ -407,6 +386,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
@@ -437,13 +417,13 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
CONFIG_MTD_ROM=y
# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -461,31 +441,15 @@ CONFIG_MTD_ROM=y
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
# CONFIG_MTD_ONENAND is not set
#
-# Parallel port support
+# UBI - Unsorted block images
#
+# CONFIG_MTD_UBI is not set
# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
+CONFIG_BLK_DEV=y
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
@@ -497,15 +461,12 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -513,6 +474,7 @@ CONFIG_BLK_DEV_LOOP=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
@@ -533,6 +495,7 @@ CONFIG_CHR_DEV_SG=y
# 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
@@ -540,12 +503,9 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
@@ -555,7 +515,6 @@ CONFIG_CHR_DEV_SG=y
# 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_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
@@ -566,6 +525,7 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
@@ -577,10 +537,6 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
# CONFIG_SATA_AHCI is not set
@@ -597,62 +553,48 @@ CONFIG_SATA_SIL=y
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SERVERWORKS is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_SIL680 is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
# CONFIG_PATA_PLATFORM is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
# CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
#
-# CONFIG_IEEE1394 is not set
#
-# I2O device support
+# An alternative FireWire stack is available with EXPERIMENTAL=y
#
+# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
CONFIG_PHYLIB=y
#
@@ -666,85 +608,59 @@ CONFIG_PHYLIB=y
# CONFIG_VITESSE_PHY is not set
CONFIG_SMSC_PHY=y
# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
# CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
+# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_SMC91X=y
-
-#
-# Tulip family network device support
-#
# CONFIG_NET_TULIP 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_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_DGRS is not set
# CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139TOO is not set
+# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-# CONFIG_QLA3XXX is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
+# Wireless LAN
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
#
-# Wan interfaces
+# USB Network Adapters
#
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_PPP is not set
@@ -752,15 +668,7 @@ CONFIG_NET_PCI=y
# CONFIG_NET_FC is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
# CONFIG_PHONE is not set
#
@@ -768,6 +676,7 @@ CONFIG_NET_PCI=y
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -777,7 +686,6 @@ CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
@@ -787,6 +695,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE 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
@@ -821,31 +730,12 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
# CONFIG_I2C is not set
#
@@ -853,18 +743,27 @@ CONFIG_UNIX98_PTYS=y
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_THERMAL=y
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -875,23 +774,27 @@ CONFIG_HWMON=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-# CONFIG_USB_DABUSB is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
#
# Graphics support
#
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
# CONFIG_FB_DDC is not set
# CONFIG_FB_CFB_FILLRECT is not set
# CONFIG_FB_CFB_COPYAREA is not set
# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
@@ -899,14 +802,13 @@ CONFIG_FIRMWARE_EDID=y
# CONFIG_FB_TILEBLITTING is not set
#
-# Frambuffer hardware drivers
+# Frame buffer hardware drivers
#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_EPSON1355 is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
@@ -920,22 +822,27 @@ CONFIG_FIRMWARE_EDID=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
#
# Console display driver support
#
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
@@ -958,39 +865,38 @@ CONFIG_SOUND=y
# Open Sound System
#
CONFIG_SOUND_PRIME=y
-# CONFIG_OBSOLETE_OSS is not set
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_ICH is not set
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-
-#
-# HID Devices
-#
+CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
#
-# USB support
+# USB Input Devices
#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_USB_HIDDEV 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=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 is not set
#
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
@@ -998,6 +904,7 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
#
# USB Device Class drivers
@@ -1015,49 +922,20 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_LIBUSUAL is not set
#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_TOUCHSCREEN is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_GTCO is not set
-
-#
# USB Imaging devices
#
# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_USBNET_MII is not set
-# CONFIG_USB_USBNET is not set
CONFIG_USB_MON=y
#
# USB port drivers
#
-
-#
-# USB Serial Converter support
-#
# CONFIG_USB_SERIAL is not set
#
@@ -1078,67 +956,17 @@ CONFIG_USB_MON=y
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
# CONFIG_MMC is not set
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
+# Userspace I/O
#
+# CONFIG_UIO is not set
#
# File systems
@@ -1151,12 +979,11 @@ CONFIG_EXT2_FS=y
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_DNOTIFY 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
@@ -1181,14 +1008,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# Pseudo filesystems
#
CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
-# CONFIG_SYSFS is not set
+CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -1197,14 +1024,13 @@ CONFIG_RAMFS=y
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
@@ -1225,10 +1051,6 @@ CONFIG_SUNRPC=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
@@ -1275,13 +1097,15 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
# 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 is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_SAMPLES is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_SH_KGDB is not set
@@ -1290,11 +1114,48 @@ CONFIG_LOG_BUF_SHIFT=14
# Security options
#
# CONFIG_KEYS is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
+# CONFIG_SECURITY is not set
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_SEQIV is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
#
# Library routines
@@ -1302,9 +1163,12 @@ CONFIG_LOG_BUF_SHIFT=14
CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
index 9380c321169..37e49a58920 100644
--- a/arch/sh/configs/sh7710voipgw_defconfig
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -1,40 +1,55 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct 3 12:48:56 2006
+# Linux kernel version: 2.6.25-rc4
+# Thu Mar 6 16:02:29 2008
#
CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
# 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_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
@@ -46,33 +61,39 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
+CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
-CONFIG_SLAB=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_KPROBES is not set
+# CONFIG_HAVE_KRETPROBES is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_KMOD is not set
-
-#
-# Block layer
-#
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -86,59 +107,26 @@ CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
#
# System type
#
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_7343_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-CONFIG_SH_7710VOIPGW=y
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R7780RP is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-# CONFIG_SH_TITAN is not set
-# CONFIG_SH_SHMIN is not set
-# CONFIG_SH_UNKNOWN is not set
-
-#
-# Processor selection
-#
CONFIG_CPU_SH3=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
# CONFIG_CPU_SUBTYPE_SH7705 is not set
# CONFIG_CPU_SUBTYPE_SH7706 is not set
# CONFIG_CPU_SUBTYPE_SH7707 is not set
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
CONFIG_CPU_SUBTYPE_SH7710=y
-
-#
-# SH-4 Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
# CONFIG_CPU_SUBTYPE_SH7750 is not set
# CONFIG_CPU_SUBTYPE_SH7091 is not set
# CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -147,65 +135,84 @@ CONFIG_CPU_SUBTYPE_SH7710=y
# CONFIG_CPU_SUBTYPE_SH7751R is not set
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
-
-#
-# SH4AL-DSP Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
#
+CONFIG_QUICKLIST=y
CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x00800000
+CONFIG_29BIT=y
CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB 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_STATIC is not set
+CONFIG_SPARSEMEM_STATIC=y
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
#
# Cache configuration
#
# CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
#
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
# CONFIG_SH_FPU_EMU is not set
CONFIG_SH_DSP=y
# CONFIG_SH_ADC is not set
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_DSP=y
#
-# Timer support
+# Board support
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+
+#
+# Timer and clock configuration
#
CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=32768000
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
# CPU Frequency scaling
@@ -220,56 +227,51 @@ CONFIG_SH_PCLK_FREQ=32768000
#
# Companion Chips
#
-# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
#
# Kernel features
#
# CONFIG_HZ_100 is not set
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_KEXEC is not set
-# CONFIG_SMP is not set
+# CONFIG_CRASH_DUMP is not set
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_RCU_TRACE=y
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
#
# Boot options
#
CONFIG_ZERO_PAGE_OFFSET=0x00001000
CONFIG_BOOT_LINK_OFFSET=0x00800000
-# CONFIG_UBC_WAKEUP is not set
# CONFIG_CMDLINE_BOOL is not set
#
# Bus options
#
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
#
-# PCI Hotplug Support
-#
-
-#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
# CONFIG_BINFMT_MISC is not set
#
-# Power management options (EXPERIMENTAL)
-#
-# CONFIG_PM is not set
-
-#
# Networking
#
CONFIG_NET=y
@@ -277,13 +279,14 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
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 is not set
@@ -301,14 +304,13 @@ CONFIG_SYN_COOKIES=y
# 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 is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
-
-#
-# IP: Virtual Server Configuration
-#
+# CONFIG_TCP_MD5SIG is not set
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
@@ -316,44 +318,24 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
#
# Core Netfilter Configuration
#
-# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
# CONFIG_NETFILTER_XTABLES is not set
#
# IP: Netfilter Configuration
#
-CONFIG_IP_NF_CONNTRACK=y
-# CONFIG_IP_NF_CT_ACCT is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FTP=m
-# CONFIG_IP_NF_IRC is not set
-# CONFIG_IP_NF_NETBIOS_NS is not set
-# CONFIG_IP_NF_TFTP is not set
-# CONFIG_IP_NF_AMANDA is not set
-CONFIG_IP_NF_PPTP=m
-# CONFIG_IP_NF_H323 is not set
-# CONFIG_IP_NF_SIP is not set
# CONFIG_IP_NF_QUEUE is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -366,14 +348,7 @@ CONFIG_IP_NF_PPTP=m
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CLK_JIFFIES=y
-# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
-# CONFIG_NET_SCH_CLK_CPU is not set
#
# Queueing/Scheduling
@@ -382,6 +357,7 @@ CONFIG_NET_SCH_CBQ=y
# CONFIG_NET_SCH_HTB is not set
# CONFIG_NET_SCH_HFSC is not set
# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_RR is not set
# CONFIG_NET_SCH_RED is not set
# CONFIG_NET_SCH_SFQ is not set
# CONFIG_NET_SCH_TEQL is not set
@@ -389,7 +365,6 @@ CONFIG_NET_SCH_CBQ=y
# CONFIG_NET_SCH_GRED is not set
# CONFIG_NET_SCH_DSMARK is not set
# CONFIG_NET_SCH_NETEM is not set
-CONFIG_NET_SCH_INGRESS=y
#
# Classification
@@ -405,20 +380,31 @@ CONFIG_NET_CLS_U32=y
# CONFIG_CLS_U32_MARK is not set
# CONFIG_NET_CLS_RSVP is not set
# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
-CONFIG_NET_CLS_POLICE=y
# CONFIG_NET_CLS_IND is not set
-CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_SCH_FIFO=y
#
# 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
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -427,19 +413,12 @@ CONFIG_NET_ESTIMATOR=y
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
@@ -451,12 +430,14 @@ CONFIG_MTD_PARTITIONS=y
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
@@ -482,7 +463,6 @@ CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_RAM=y
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
@@ -505,40 +485,25 @@ CONFIG_MTD_RAM=y
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
# CONFIG_MTD_ONENAND is not set
#
-# Parallel port support
+# UBI - Unsorted block images
#
+# CONFIG_MTD_UBI is not set
# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -546,104 +511,59 @@ CONFIG_MTD_RAM=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
# CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
+# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X 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_B44 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_E1000E_ENABLED is not set
+CONFIG_NETDEV_10000=y
#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
# 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
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
CONFIG_PHONE=y
-# CONFIG_PHONE_IXJ 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 is not set
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
@@ -653,6 +573,7 @@ CONFIG_INPUT=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE 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
@@ -684,35 +605,11 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_UNIX98_PTYS is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
CONFIG_HW_RANDOM=y
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
# CONFIG_I2C is not set
#
@@ -720,119 +617,86 @@ CONFIG_HW_RANDOM=y
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+# CONFIG_WATCHDOG is not set
#
-# Dallas's 1-wire bus
-#
-
-#
-# Hardware Monitoring support
+# Sonics Silicon Backplane
#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
-# Misc devices
+# Multifunction device drivers
#
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
-# Sound
+# Display device support
#
-# CONFIG_SOUND is not set
+# CONFIG_DISPLAY_SUPPORT is not set
#
-# USB support
+# Sound
#
-# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
-
-#
-# USB Gadget Support
-#
# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
# CONFIG_MMC is not set
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
# CONFIG_RTC_CLASS is not set
#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
+# Userspace I/O
#
+# CONFIG_UIO is not set
#
# File systems
#
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_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_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# 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
@@ -861,7 +725,6 @@ CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
#
@@ -874,26 +737,26 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
# CONFIG_JFFS2_SUMMARY is not set
# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
# CONFIG_SMB_FS is not set
@@ -901,55 +764,97 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+# CONFIG_DLM is not set
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
# 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 is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_FS is not set
+# CONFIG_SAMPLES is not set
# CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_KGDB is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_SH_KGDB is not set
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_SEQIV is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index 5c3359756a9..71ff3d6f26e 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -90,7 +90,7 @@ static irqreturn_t dma_tei(int irq, void *dev_id)
static int sh_dmac_request_dma(struct dma_channel *chan)
{
- if (unlikely(!chan->flags & DMA_TEI_CAPABLE))
+ if (unlikely(!(chan->flags & DMA_TEI_CAPABLE)))
return 0;
return request_irq(get_dmte_irq(chan->chan), dma_tei,
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c
index b76a14f12ce..ab77b0e0fa0 100644
--- a/arch/sh/drivers/heartbeat.c
+++ b/arch/sh/drivers/heartbeat.c
@@ -93,7 +93,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
}
hd->base = ioremap_nocache(res->start, res->end - res->start + 1);
- if (!unlikely(hd->base)) {
+ if (unlikely(!hd->base)) {
dev_err(&pdev->dev, "ioremap failed\n");
if (!pdev->dev.platform_data)
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c
index 0dac87b1962..e1284fc6936 100644
--- a/arch/sh/drivers/pci/ops-dreamcast.c
+++ b/arch/sh/drivers/pci/ops-dreamcast.c
@@ -83,9 +83,9 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
- case 1: *val = ctrl_inb(GAPSPCI_BBA_CONFIG+where); break;
- case 2: *val = ctrl_inw(GAPSPCI_BBA_CONFIG+where); break;
- case 4: *val = ctrl_inl(GAPSPCI_BBA_CONFIG+where); break;
+ case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break;
+ case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break;
+ case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break;
}
return PCIBIOS_SUCCESSFUL;
@@ -97,9 +97,9 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
- case 1: ctrl_outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
- case 2: ctrl_outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
- case 4: ctrl_outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
+ case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
+ case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
+ case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
}
return PCIBIOS_SUCCESSFUL;
@@ -127,36 +127,36 @@ int __init gapspci_init(void)
*/
for (i=0; i<16; i++)
- idbuf[i] = ctrl_inb(GAPSPCI_REGS+i);
+ idbuf[i] = inb(GAPSPCI_REGS+i);
if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
return -ENODEV;
- ctrl_outl(0x5a14a501, GAPSPCI_REGS+0x18);
+ outl(0x5a14a501, GAPSPCI_REGS+0x18);
for (i=0; i<1000000; i++)
;
- if (ctrl_inl(GAPSPCI_REGS+0x18) != 1)
+ if (inl(GAPSPCI_REGS+0x18) != 1)
return -EINVAL;
- ctrl_outl(0x01000000, GAPSPCI_REGS+0x20);
- ctrl_outl(0x01000000, GAPSPCI_REGS+0x24);
+ outl(0x01000000, GAPSPCI_REGS+0x20);
+ outl(0x01000000, GAPSPCI_REGS+0x24);
- ctrl_outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
- ctrl_outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
+ outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
+ outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
- ctrl_outl(1, GAPSPCI_REGS+0x14);
- ctrl_outl(1, GAPSPCI_REGS+0x34);
+ outl(1, GAPSPCI_REGS+0x14);
+ outl(1, GAPSPCI_REGS+0x34);
/* Setting Broadband Adapter */
- ctrl_outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
- ctrl_outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
- ctrl_outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
- ctrl_outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
- ctrl_outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
- ctrl_outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
- ctrl_outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
+ outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
+ outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
+ outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
+ outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
+ outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
+ outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
+ outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
return 0;
}
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 80a31329ead..75fb03d3567 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -233,7 +233,7 @@ static void __init dsp_init(void)
* and cache configuration in detect_cpu_and_cache_system().
*/
-asmlinkage void __cpuinit sh_cpu_init(void)
+asmlinkage void __init sh_cpu_init(void)
{
current_thread_info()->cpu = hard_smp_processor_id();
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index b230eb278ce..cc530f4d84d 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
index 3feb95a4fcb..fb781329848 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
@@ -21,8 +21,8 @@
#include <asm/freq.h>
#include <asm/io.h>
-const static int pll1rate[]={8,12,16,0};
-const static int pfc_divisors[]={1,2,3,4,6,8,12};
+static const int pll1rate[]={8,12,16,0};
+static const int pfc_divisors[]={1,2,3,4,6,8,12};
#define ifc_divisors pfc_divisors
#if (CONFIG_SH_CLK_MD == 0)
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index db6ef5cecde..e98dc445035 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index a564425b905..e6d4ec445dd 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index fcc80bb7bee..10f2a760c5e 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -94,9 +94,9 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
boot_cpu_data.dcache.way_incr = (1 << 13);
boot_cpu_data.dcache.entry_mask = 0x1ff0;
boot_cpu_data.dcache.sets = 512;
- ctrl_outl(CCR_CACHE_32KB, CCR3);
+ ctrl_outl(CCR_CACHE_32KB, CCR3_REG);
#else
- ctrl_outl(CCR_CACHE_16KB, CCR3);
+ ctrl_outl(CCR_CACHE_16KB, CCR3_REG);
#endif
#endif
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index dd0a20a685f..f581534cb73 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
#include <asm/rtc.h>
enum {
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index 969804bb523..d3733b13ea5 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -16,7 +16,7 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
enum {
UNUSED = 0,
@@ -123,15 +123,15 @@ static struct resource rtc_resources[] = {
.flags = IORESOURCE_IO,
},
[1] = {
- .start = 20,
+ .start = 21,
.flags = IORESOURCE_IRQ,
},
[2] = {
- .start = 21,
+ .start = 22,
.flags = IORESOURCE_IRQ,
},
[3] = {
- .start = 22,
+ .start = 20,
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 0cc0e2bf135..7406c9ad925 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
#include <asm/rtc.h>
enum {
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 3855ea4c21c..8028082527c 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -16,7 +16,7 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/io.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
#include <asm/rtc.h>
#define INTC_ICR1 0xA4140010UL
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
index dab193293f2..7371abf64f8 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
@@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index ae3603aca61..ec884039b91 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/io.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
static struct resource rtc_resources[] = {
[0] = {
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 85f81579b97..254c5c55ab9 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index 8250e017bd4..9561b02ade0 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -216,7 +216,7 @@ void sq_unmap(unsigned long vaddr)
if (unlikely(!map)) {
printk("%s: bad store queue address 0x%08lx\n",
- __FUNCTION__, vaddr);
+ __func__, vaddr);
return;
}
@@ -233,7 +233,7 @@ void sq_unmap(unsigned long vaddr)
vma = remove_vm_area((void *)(map->sq_addr & PAGE_MASK));
if (!vma) {
printk(KERN_ERR "%s: bad address 0x%08lx\n",
- __FUNCTION__, map->sq_addr);
+ __func__, map->sq_addr);
return;
}
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index c0a3f079dfd..6d4f50cd4aa 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 967e8b69a2f..f26b5cdad0d 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -12,7 +12,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 73c778d40d1..b98b4bc93ec 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -10,9 +10,9 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
+#include <linux/serial_sci.h>
#include <linux/mm.h>
#include <asm/mmzone.h>
-#include <asm/sci.h>
static struct resource usbf_resources[] = {
[0] = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index eabd5386812..07c988dc9de 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/io.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
static struct resource rtc_resources[] = {
[0] = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
index 32f4f59a837..b9cec48b180 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
@@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index 293004b526f..18dbbe23fea 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -11,7 +11,7 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/io.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
static struct resource rtc_resources[] = {
[0] = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index 74b60e96cdf..621e7329ec6 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -10,10 +10,10 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
+#include <linux/serial_sci.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <asm/mmzone.h>
-#include <asm/sci.h>
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index 4dc958b6b31..bd35f32534b 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -10,9 +10,9 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
+#include <linux/serial_sci.h>
#include <linux/io.h>
#include <asm/mmzone.h>
-#include <asm/sci.h>
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/arch/sh/kernel/cpu/sh5/unwind.c b/arch/sh/kernel/cpu/sh5/unwind.c
index 119c20afd4e..b205b25eaf4 100644
--- a/arch/sh/kernel/cpu/sh5/unwind.c
+++ b/arch/sh/kernel/cpu/sh5/unwind.c
@@ -149,7 +149,7 @@ static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc,
if (dest >= 63) {
printk(KERN_NOTICE "%s: Invalid dest reg %d "
"specified in movi handler. Failed "
- "opcode was 0x%lx: ", __FUNCTION__,
+ "opcode was 0x%lx: ", __func__,
dest, op);
continue;
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 86a665d9220..39cd7f3aec7 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -32,7 +32,7 @@ EXPORT_SYMBOL_GPL(trapped_mem);
#endif
static DEFINE_SPINLOCK(trapped_lock);
-int __init register_trapped_io(struct trapped_io *tiop)
+int register_trapped_io(struct trapped_io *tiop)
{
struct resource *res;
unsigned long len = 0, flags = 0;
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index e1a6de9088b..d80de390327 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -111,9 +111,9 @@ DECLARE_EXPORT(__movmem_i4_even);
DECLARE_EXPORT(__movmem_i4_odd);
DECLARE_EXPORT(__movmemSI12_i4);
-#if (__GNUC_MINOR__ == 2 || defined(__GNUC_STM_RELEASE__))
+#if (__GNUC_MINOR__ >= 2 || defined(__GNUC_STM_RELEASE__))
/*
- * GCC 4.2 emits these for division, as do GCC 4.1.x versions of the ST
+ * GCC >= 4.2 emits these for division, as do GCC 4.1.x versions of the ST
* compiler which include backported patches.
*/
DECLARE_EXPORT(__sdivsi3_i4i);
@@ -146,5 +146,6 @@ EXPORT_SYMBOL(csum_partial_copy_generic);
EXPORT_SYMBOL(csum_ipv6_magic);
#endif
EXPORT_SYMBOL(clear_page);
+EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(__clear_user);
EXPORT_SYMBOL(_ebss);
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index 8004c38d3d3..dd38a683de6 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -42,6 +42,7 @@ EXPORT_SYMBOL(__down_trylock);
EXPORT_SYMBOL(__up);
EXPORT_SYMBOL(__put_user_asm_l);
EXPORT_SYMBOL(__get_user_asm_l);
+EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(__copy_user);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(__udelay);
diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c
index 71312324b5d..d20c8c37588 100644
--- a/arch/sh/kernel/timers/timer-cmt.c
+++ b/arch/sh/kernel/timers/timer-cmt.c
@@ -77,7 +77,7 @@ static unsigned long cmt_timer_get_offset(void)
count -= LATCH;
} else {
printk("%s (): hardware timer problem?\n",
- __FUNCTION__);
+ __func__);
}
}
} else
diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c
index ade9d6eb29f..fe453c01f9c 100644
--- a/arch/sh/kernel/timers/timer-mtu2.c
+++ b/arch/sh/kernel/timers/timer-mtu2.c
@@ -76,7 +76,7 @@ static unsigned long mtu2_timer_get_offset(void)
count -= LATCH;
} else {
printk("%s (): hardware timer problem?\n",
- __FUNCTION__);
+ __func__);
}
}
} else
diff --git a/arch/sh/kernel/topology.c b/arch/sh/kernel/topology.c
index 9b5844a1bda..0838942b708 100644
--- a/arch/sh/kernel/topology.c
+++ b/arch/sh/kernel/topology.c
@@ -29,7 +29,7 @@ static int __init topology_init(void)
ret = register_cpu(&per_cpu(cpu_devices, i), i);
if (unlikely(ret))
printk(KERN_WARNING "%s: register_cpu %d failed (%d)\n",
- __FUNCTION__, i, ret);
+ __func__, i, ret);
}
#if defined(CONFIG_NUMA) && !defined(CONFIG_SMP)
diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c
index a55ac81d795..1b58a749908 100644
--- a/arch/sh/kernel/traps_64.c
+++ b/arch/sh/kernel/traps_64.c
@@ -238,7 +238,7 @@ DO_ERROR(12, SIGILL, "reserved instruction", reserved_inst, current)
/* Called with interrupts disabled */
asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs)
{
- show_excp_regs(__FUNCTION__, -1, -1, regs);
+ show_excp_regs(__func__, -1, -1, regs);
die_if_kernel("exception", regs, ex);
}
diff --git a/arch/sh/lib64/c-checksum.c b/arch/sh/lib64/c-checksum.c
index 5dfbd8b5e55..5c284e0cff9 100644
--- a/arch/sh/lib64/c-checksum.c
+++ b/arch/sh/lib64/c-checksum.c
@@ -207,7 +207,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
result = (result & 0xffffffff) + (result >> 32);
pr_debug("%s saddr %x daddr %x len %x proto %x sum %x result %08Lx\n",
- __FUNCTION__, saddr, daddr, len, proto, sum, result);
+ __func__, saddr, daddr, len, proto, sum, result);
return (__wsum)result;
}
diff --git a/arch/sh/lib64/udelay.c b/arch/sh/lib64/udelay.c
index 23c7d17fb9f..d76bd801194 100644
--- a/arch/sh/lib64/udelay.c
+++ b/arch/sh/lib64/udelay.c
@@ -21,7 +21,7 @@
* a 1GHz box, that's about 2 seconds.
*/
-void __delay(int loops)
+void __delay(unsigned long loops)
{
long long dummy;
__asm__ __volatile__("gettr tr0, %1\n\t"
@@ -33,24 +33,17 @@ void __delay(int loops)
:"0"(loops));
}
-void __udelay(unsigned long long usecs, unsigned long lpj)
+inline void __const_udelay(unsigned long xloops)
{
- usecs *= (((unsigned long long) HZ << 32) / 1000000) * lpj;
- __delay((long long) usecs >> 32);
+ __delay(xloops * (HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy));
}
-void __ndelay(unsigned long long nsecs, unsigned long lpj)
+void __udelay(unsigned long usecs)
{
- nsecs *= (((unsigned long long) HZ << 32) / 1000000000) * lpj;
- __delay((long long) nsecs >> 32);
+ __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */
}
-void udelay(unsigned long usecs)
+void __ndelay(unsigned long nsecs)
{
- __udelay(usecs, cpu_data[raw_smp_processor_id()].loops_per_jiffy);
-}
-
-void ndelay(unsigned long nsecs)
-{
- __ndelay(nsecs, cpu_data[raw_smp_processor_id()].loops_per_jiffy);
+ __const_udelay(nsecs * 0x00000005);
}
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index f549b8cd250..5fd218430b1 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -59,7 +59,7 @@ config 32BIT
config PMB
bool "Support 32-bit physical addressing through PMB"
- depends on MMU && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
+ depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
select 32BIT
default y
help
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index e2ed6dd252b..53dde060736 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -328,7 +328,7 @@ int arch_add_memory(int nid, u64 start, u64 size)
/* We only have ZONE_NORMAL, so this is easy.. */
ret = __add_pages(pgdat->node_zones + ZONE_NORMAL, start_pfn, nr_pages);
if (unlikely(ret))
- printk("%s: Failed, __add_pages() == %d\n", __FUNCTION__, ret);
+ printk("%s: Failed, __add_pages() == %d\n", __func__, ret);
return ret;
}
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c
index 0c7b7e33abd..882a32ebc6b 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap_32.c
@@ -141,7 +141,7 @@ void __iounmap(void __iomem *addr)
p = remove_vm_area((void *)(vaddr & PAGE_MASK));
if (!p) {
- printk(KERN_ERR "%s: bad address %p\n", __FUNCTION__, addr);
+ printk(KERN_ERR "%s: bad address %p\n", __func__, addr);
return;
}
diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c
index e27d1651923..cea224c3e49 100644
--- a/arch/sh/mm/ioremap_64.c
+++ b/arch/sh/mm/ioremap_64.c
@@ -178,7 +178,7 @@ static unsigned long shmedia_alloc_io(unsigned long phys, unsigned long size,
} else {
if (!printed_full) {
printk("%s: done with statics, switching to kmalloc\n",
- __FUNCTION__);
+ __func__);
printed_full = 1;
}
tlen = strlen(name);
@@ -352,7 +352,7 @@ void onchip_unmap(unsigned long vaddr)
res = shmedia_find_resource(&shmedia_iomap, vaddr);
if (!res) {
printk(KERN_ERR "%s: Failed to free 0x%08lx\n",
- __FUNCTION__, vaddr);
+ __func__, vaddr);
return;
}
diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c
index a4b015f95a3..7f885b7f8af 100644
--- a/arch/sh/mm/pg-sh7705.c
+++ b/arch/sh/mm/pg-sh7705.c
@@ -14,6 +14,7 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/threads.h>
+#include <linux/fs.h>
#include <asm/addrspace.h>
#include <asm/page.h>
#include <asm/pgtable.h>
diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c
index 2a98c9ec88f..7876997ba19 100644
--- a/arch/sh/mm/tlbflush_64.c
+++ b/arch/sh/mm/tlbflush_64.c
@@ -131,7 +131,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
#ifdef DEBUG_FAULT
print_task(tsk);
printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n",
- __FUNCTION__,__LINE__,
+ __func__, __LINE__,
address,regs->pc,textaccess,writeaccess);
show_regs(regs);
#endif
@@ -145,7 +145,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
#ifdef DEBUG_FAULT
print_task(tsk);
printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n",
- __FUNCTION__,__LINE__,
+ __func__, __LINE__,
address,regs->pc,textaccess,writeaccess);
show_regs(regs);
@@ -157,7 +157,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
#ifdef DEBUG_FAULT
print_task(tsk);
printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n",
- __FUNCTION__,__LINE__,
+ __func__, __LINE__,
address,regs->pc,textaccess,writeaccess);
show_regs(regs);
#endif
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index 67997af25c0..d63b93da952 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -38,7 +38,6 @@ R7780MP SH_R7780MP
R7785RP SH_R7785RP
TITAN SH_TITAN
SHMIN SH_SHMIN
-7710VOIPGW SH_7710VOIPGW
LBOXRE2 SH_LBOX_RE2
X3PROTO SH_X3PROTO
MAGICPANELR2 SH_MAGIC_PANEL_R2
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index e795f282dec..bf1b15d3f6f 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.62 2000/12/15 00:41:17 davem Exp $
+#
# Makefile for the linux kernel.
#
@@ -12,7 +12,8 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \
sys_sparc.o sunos_asm.o systbls.o \
time.o windows.o cpu.o devices.o sclow.o \
tadpole.o tick14.o ptrace.o sys_solaris.o \
- unaligned.o muldiv.o semaphore.o prom.o of_device.o devres.o
+ unaligned.o una_asm.o muldiv.o semaphore.o \
+ prom.o of_device.o devres.o
devres-y = ../../../kernel/irq/devres.o
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 259a559d4ce..e7a0edfc1a3 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -32,7 +32,7 @@ struct cpu_fp_info {
/* In order to get the fpu type correct, you need to take the IDPROM's
* machine type value into consideration too. I will fix this.
*/
-struct cpu_fp_info linux_sparc_fpu[] = {
+static struct cpu_fp_info linux_sparc_fpu[] = {
{ 0, 0, "Fujitsu MB86910 or Weitek WTL1164/5"},
{ 0, 1, "Fujitsu MB86911 or Weitek WTL1164/5 or LSI L64831"},
{ 0, 2, "LSI Logic L64802 or Texas Instruments ACT8847"},
@@ -76,7 +76,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
-struct cpu_iu_info linux_sparc_chips[] = {
+static struct cpu_iu_info linux_sparc_chips[] = {
/* Sun4/100, 4/200, SLC */
{ 0, 0, "Fujitsu MB86900/1A or LSI L64831 SparcKIT-40"},
/* borned STP1012PGA */
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
index d850785b208..96344ff2bbe 100644
--- a/arch/sparc/kernel/ebus.c
+++ b/arch/sparc/kernel/ebus.c
@@ -101,7 +101,7 @@ void __init fill_ebus_child(struct device_node *dp,
prom_printf("UGH: property for %s was %d, need < %d\n",
dev->prom_node->name, len,
dev->parent->num_addrs);
- panic(__FUNCTION__);
+ panic(__func__);
}
/* XXX resource */
@@ -162,7 +162,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d
prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
dev->prom_node->name, len,
(int)sizeof(struct linux_prom_registers));
- panic(__FUNCTION__);
+ panic(__func__);
}
dev->num_addrs = len / sizeof(struct linux_prom_registers);
@@ -324,7 +324,7 @@ void __init ebus_init(void)
regs = of_get_property(dp, "reg", &len);
if (!regs) {
prom_printf("%s: can't find reg property\n",
- __FUNCTION__);
+ __func__);
prom_halt();
}
nreg = len / sizeof(struct linux_prom_pci_registers);
diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c
index 313d1620ae8..59e9344e7a0 100644
--- a/arch/sparc/kernel/led.c
+++ b/arch/sparc/kernel/led.c
@@ -3,6 +3,9 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/uaccess.h>
#include <asm/auxio.h>
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 19186ce8850..70c0dd22491 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -139,18 +139,12 @@ void cpu_idle(void)
#endif
-extern char reboot_command [];
-
-extern void (*prom_palette)(int);
-
/* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
void machine_halt(void)
{
local_irq_enable();
mdelay(8);
local_irq_disable();
- if (prom_palette)
- prom_palette (1);
prom_halt();
panic("Halt failed!");
}
@@ -165,8 +159,6 @@ void machine_restart(char * cmd)
p = strchr (reboot_command, '\n');
if (p) *p = 0;
- if (prom_palette)
- prom_palette (1);
if (cmd)
prom_reboot(cmd);
if (*reboot_command)
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 3cf78f16084..3c13137685d 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -65,7 +65,6 @@ struct screen_info screen_info = {
*/
extern unsigned long trapbase;
-void (*prom_palette)(int);
/* Pretty sick eh? */
void prom_sync_me(void)
@@ -80,8 +79,6 @@ void prom_sync_me(void)
"nop\n\t"
"nop\n\t" : : "r" (&trapbase));
- if (prom_palette)
- prom_palette(1);
prom_printf("PROM SYNC COMMAND...\n");
show_free_areas();
if(current->pid != 0) {
@@ -191,7 +188,6 @@ extern int prom_probe_memory(void);
extern void sun4c_probe_vac(void);
extern char cputypval;
extern unsigned long start, end;
-extern void panic_setup(char *, int *);
extern unsigned short root_flags;
extern unsigned short root_dev;
diff --git a/arch/sparc/kernel/una_asm.S b/arch/sparc/kernel/una_asm.S
new file mode 100644
index 00000000000..8cc03458eb7
--- /dev/null
+++ b/arch/sparc/kernel/una_asm.S
@@ -0,0 +1,153 @@
+/* una_asm.S: Kernel unaligned trap assembler helpers.
+ *
+ * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/errno.h>
+
+ .text
+
+retl_efault:
+ retl
+ mov -EFAULT, %o0
+
+ /* int __do_int_store(unsigned long *dst_addr, int size,
+ * unsigned long *src_val)
+ *
+ * %o0 = dest_addr
+ * %o1 = size
+ * %o2 = src_val
+ *
+ * Return '0' on success, -EFAULT on failure.
+ */
+ .globl __do_int_store
+__do_int_store:
+ ld [%o2], %g1
+ cmp %1, 2
+ be 2f
+ cmp %1, 4
+ be 1f
+ srl %g1, 24, %g2
+ srl %g1, 16, %g7
+4: stb %g2, [%o0]
+ srl %g1, 8, %g2
+5: stb %g7, [%o0 + 1]
+ ld [%o2 + 4], %g7
+6: stb %g2, [%o0 + 2]
+ srl %g7, 24, %g2
+7: stb %g1, [%o0 + 3]
+ srl %g7, 16, %g1
+8: stb %g2, [%o0 + 4]
+ srl %g7, 8, %g2
+9: stb %g1, [%o0 + 5]
+10: stb %g2, [%o0 + 6]
+ b 0f
+11: stb %g7, [%o0 + 7]
+1: srl %g1, 16, %g7
+12: stb %g2, [%o0]
+ srl %g1, 8, %g2
+13: stb %g7, [%o0 + 1]
+14: stb %g2, [%o0 + 2]
+ b 0f
+15: stb %g1, [%o0 + 3]
+2: srl %g1, 8, %g2
+16: stb %g2, [%o0]
+17: stb %g1, [%o0 + 1]
+0: retl
+ mov 0, %o0
+
+ .section __ex_table,#alloc
+ .word 4b, retl_efault
+ .word 5b, retl_efault
+ .word 6b, retl_efault
+ .word 7b, retl_efault
+ .word 8b, retl_efault
+ .word 9b, retl_efault
+ .word 10b, retl_efault
+ .word 11b, retl_efault
+ .word 12b, retl_efault
+ .word 13b, retl_efault
+ .word 14b, retl_efault
+ .word 15b, retl_efault
+ .word 16b, retl_efault
+ .word 17b, retl_efault
+ .previous
+
+ /* int do_int_load(unsigned long *dest_reg, int size,
+ * unsigned long *saddr, int is_signed)
+ *
+ * %o0 = dest_reg
+ * %o1 = size
+ * %o2 = saddr
+ * %o3 = is_signed
+ *
+ * Return '0' on success, -EFAULT on failure.
+ */
+ .globl do_int_load
+do_int_load:
+ cmp %o1, 8
+ be 9f
+ cmp %o1, 4
+ be 6f
+4: ldub [%o2], %g1
+5: ldub [%o2 + 1], %g2
+ sll %g1, 8, %g1
+ tst %o3
+ be 3f
+ or %g1, %g2, %g1
+ sll %g1, 16, %g1
+ sra %g1, 16, %g1
+3: b 0f
+ st %g1, [%o0]
+6: ldub [%o2 + 1], %g2
+ sll %g1, 24, %g1
+7: ldub [%o2 + 2], %g7
+ sll %g2, 16, %g2
+8: ldub [%o2 + 3], %g3
+ sll %g7, 8, %g7
+ or %g3, %g2, %g3
+ or %g7, %g3, %g7
+ or %g1, %g7, %g1
+ b 0f
+ st %g1, [%o0]
+9: ldub [%o2], %g1
+10: ldub [%o2 + 1], %g2
+ sll %g1, 24, %g1
+11: ldub [%o2 + 2], %g7
+ sll %g2, 16, %g2
+12: ldub [%o2 + 3], %g3
+ sll %g7, 8, %g7
+ or %g1, %g2, %g1
+ or %g7, %g3, %g7
+ or %g1, %g7, %g7
+13: ldub [%o2 + 4], %g1
+ st %g7, [%o0]
+14: ldub [%o2 + 5], %g2
+ sll %g1, 24, %g1
+15: ldub [%o2 + 6], %g7
+ sll %g2, 16, %g2
+16: ldub [%o2 + 7], %g3
+ sll %g7, 8, %g7
+ or %g1, %g2, %g1
+ or %g7, %g3, %g7
+ or %g1, %g7, %g7
+ st %g7, [%o0 + 4]
+0: retl
+ mov 0, %o0
+
+ .section __ex_table,#alloc
+ .word 4b, retl_efault
+ .word 5b, retl_efault
+ .word 6b, retl_efault
+ .word 7b, retl_efault
+ .word 8b, retl_efault
+ .word 9b, retl_efault
+ .word 10b, retl_efault
+ .word 11b, retl_efault
+ .word 12b, retl_efault
+ .word 13b, retl_efault
+ .word 14b, retl_efault
+ .word 15b, retl_efault
+ .word 16b, retl_efault
+ .previous
diff --git a/arch/sparc/kernel/unaligned.c b/arch/sparc/kernel/unaligned.c
index a6330fbc9dd..33857be1666 100644
--- a/arch/sparc/kernel/unaligned.c
+++ b/arch/sparc/kernel/unaligned.c
@@ -175,157 +175,31 @@ static void unaligned_panic(char *str)
panic(str);
}
-#define do_integer_load(dest_reg, size, saddr, is_signed, errh) ({ \
-__asm__ __volatile__ ( \
- "cmp %1, 8\n\t" \
- "be 9f\n\t" \
- " cmp %1, 4\n\t" \
- "be 6f\n" \
-"4:\t" " ldub [%2], %%l1\n" \
-"5:\t" "ldub [%2 + 1], %%l2\n\t" \
- "sll %%l1, 8, %%l1\n\t" \
- "tst %3\n\t" \
- "be 3f\n\t" \
- " add %%l1, %%l2, %%l1\n\t" \
- "sll %%l1, 16, %%l1\n\t" \
- "sra %%l1, 16, %%l1\n" \
-"3:\t" "b 0f\n\t" \
- " st %%l1, [%0]\n" \
-"6:\t" "ldub [%2 + 1], %%l2\n\t" \
- "sll %%l1, 24, %%l1\n" \
-"7:\t" "ldub [%2 + 2], %%g7\n\t" \
- "sll %%l2, 16, %%l2\n" \
-"8:\t" "ldub [%2 + 3], %%g1\n\t" \
- "sll %%g7, 8, %%g7\n\t" \
- "or %%l1, %%l2, %%l1\n\t" \
- "or %%g7, %%g1, %%g7\n\t" \
- "or %%l1, %%g7, %%l1\n\t" \
- "b 0f\n\t" \
- " st %%l1, [%0]\n" \
-"9:\t" "ldub [%2], %%l1\n" \
-"10:\t" "ldub [%2 + 1], %%l2\n\t" \
- "sll %%l1, 24, %%l1\n" \
-"11:\t" "ldub [%2 + 2], %%g7\n\t" \
- "sll %%l2, 16, %%l2\n" \
-"12:\t" "ldub [%2 + 3], %%g1\n\t" \
- "sll %%g7, 8, %%g7\n\t" \
- "or %%l1, %%l2, %%l1\n\t" \
- "or %%g7, %%g1, %%g7\n\t" \
- "or %%l1, %%g7, %%g7\n" \
-"13:\t" "ldub [%2 + 4], %%l1\n\t" \
- "st %%g7, [%0]\n" \
-"14:\t" "ldub [%2 + 5], %%l2\n\t" \
- "sll %%l1, 24, %%l1\n" \
-"15:\t" "ldub [%2 + 6], %%g7\n\t" \
- "sll %%l2, 16, %%l2\n" \
-"16:\t" "ldub [%2 + 7], %%g1\n\t" \
- "sll %%g7, 8, %%g7\n\t" \
- "or %%l1, %%l2, %%l1\n\t" \
- "or %%g7, %%g1, %%g7\n\t" \
- "or %%l1, %%g7, %%g7\n\t" \
- "st %%g7, [%0 + 4]\n" \
-"0:\n\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".word 4b, " #errh "\n\t" \
- ".word 5b, " #errh "\n\t" \
- ".word 6b, " #errh "\n\t" \
- ".word 7b, " #errh "\n\t" \
- ".word 8b, " #errh "\n\t" \
- ".word 9b, " #errh "\n\t" \
- ".word 10b, " #errh "\n\t" \
- ".word 11b, " #errh "\n\t" \
- ".word 12b, " #errh "\n\t" \
- ".word 13b, " #errh "\n\t" \
- ".word 14b, " #errh "\n\t" \
- ".word 15b, " #errh "\n\t" \
- ".word 16b, " #errh "\n\n\t" \
- ".previous\n\t" \
- : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed) \
- : "l1", "l2", "g7", "g1", "cc"); \
-})
-
-#define store_common(dst_addr, size, src_val, errh) ({ \
-__asm__ __volatile__ ( \
- "ld [%2], %%l1\n" \
- "cmp %1, 2\n\t" \
- "be 2f\n\t" \
- " cmp %1, 4\n\t" \
- "be 1f\n\t" \
- " srl %%l1, 24, %%l2\n\t" \
- "srl %%l1, 16, %%g7\n" \
-"4:\t" "stb %%l2, [%0]\n\t" \
- "srl %%l1, 8, %%l2\n" \
-"5:\t" "stb %%g7, [%0 + 1]\n\t" \
- "ld [%2 + 4], %%g7\n" \
-"6:\t" "stb %%l2, [%0 + 2]\n\t" \
- "srl %%g7, 24, %%l2\n" \
-"7:\t" "stb %%l1, [%0 + 3]\n\t" \
- "srl %%g7, 16, %%l1\n" \
-"8:\t" "stb %%l2, [%0 + 4]\n\t" \
- "srl %%g7, 8, %%l2\n" \
-"9:\t" "stb %%l1, [%0 + 5]\n" \
-"10:\t" "stb %%l2, [%0 + 6]\n\t" \
- "b 0f\n" \
-"11:\t" " stb %%g7, [%0 + 7]\n" \
-"1:\t" "srl %%l1, 16, %%g7\n" \
-"12:\t" "stb %%l2, [%0]\n\t" \
- "srl %%l1, 8, %%l2\n" \
-"13:\t" "stb %%g7, [%0 + 1]\n" \
-"14:\t" "stb %%l2, [%0 + 2]\n\t" \
- "b 0f\n" \
-"15:\t" " stb %%l1, [%0 + 3]\n" \
-"2:\t" "srl %%l1, 8, %%l2\n" \
-"16:\t" "stb %%l2, [%0]\n" \
-"17:\t" "stb %%l1, [%0 + 1]\n" \
-"0:\n\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".word 4b, " #errh "\n\t" \
- ".word 5b, " #errh "\n\t" \
- ".word 6b, " #errh "\n\t" \
- ".word 7b, " #errh "\n\t" \
- ".word 8b, " #errh "\n\t" \
- ".word 9b, " #errh "\n\t" \
- ".word 10b, " #errh "\n\t" \
- ".word 11b, " #errh "\n\t" \
- ".word 12b, " #errh "\n\t" \
- ".word 13b, " #errh "\n\t" \
- ".word 14b, " #errh "\n\t" \
- ".word 15b, " #errh "\n\t" \
- ".word 16b, " #errh "\n\t" \
- ".word 17b, " #errh "\n\n\t" \
- ".previous\n\t" \
- : : "r" (dst_addr), "r" (size), "r" (src_val) \
- : "l1", "l2", "g7", "g1", "cc"); \
-})
-
-#define do_integer_store(reg_num, size, dst_addr, regs, errh) ({ \
- unsigned long *src_val; \
- static unsigned long zero[2] = { 0, }; \
- \
- if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \
- else { \
- src_val = &zero[0]; \
- if (size == 8) \
- zero[1] = fetch_reg(1, regs); \
- } \
- store_common(dst_addr, size, src_val, errh); \
-})
+/* una_asm.S */
+extern int do_int_load(unsigned long *dest_reg, int size,
+ unsigned long *saddr, int is_signed);
+extern int __do_int_store(unsigned long *dst_addr, int size,
+ unsigned long *src_val);
+
+static int do_int_store(int reg_num, int size, unsigned long *dst_addr,
+ struct pt_regs *regs)
+{
+ unsigned long zero[2] = { 0, 0 };
+ unsigned long *src_val;
+
+ if (reg_num)
+ src_val = fetch_reg_addr(reg_num, regs);
+ else {
+ src_val = &zero[0];
+ if (size == 8)
+ zero[1] = fetch_reg(1, regs);
+ }
+ return __do_int_store(dst_addr, size, src_val);
+}
extern void smp_capture(void);
extern void smp_release(void);
-#define do_atomic(srcdest_reg, mem, errh) ({ \
- unsigned long flags, tmp; \
- \
- smp_capture(); \
- local_irq_save(flags); \
- tmp = *srcdest_reg; \
- do_integer_load(srcdest_reg, 4, mem, 0, errh); \
- store_common(mem, 4, &tmp, errh); \
- local_irq_restore(flags); \
- smp_release(); \
-})
-
static inline void advance(struct pt_regs *regs)
{
regs->pc = regs->npc;
@@ -342,9 +216,7 @@ static inline int ok_for_kernel(unsigned int insn)
return !floating_point_load_or_store_p(insn);
}
-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault");
-
-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
{
unsigned long g2 = regs->u_regs [UREG_G2];
unsigned long fixup = search_extables_range(regs->pc, &g2);
@@ -379,48 +251,34 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n",
regs->pc);
unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store.");
-
- __asm__ __volatile__ ("\n"
-"kernel_unaligned_trap_fault:\n\t"
- "mov %0, %%o0\n\t"
- "call kernel_mna_trap_fault\n\t"
- " mov %1, %%o1\n\t"
- :
- : "r" (regs), "r" (insn)
- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
- "g1", "g2", "g3", "g4", "g5", "g7", "cc");
} else {
unsigned long addr = compute_effective_address(regs, insn);
+ int err;
#ifdef DEBUG_MNA
printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n",
regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
#endif
- switch(dir) {
+ switch (dir) {
case load:
- do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
- size, (unsigned long *) addr,
- decode_signedness(insn),
- kernel_unaligned_trap_fault);
+ err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
+ regs),
+ size, (unsigned long *) addr,
+ decode_signedness(insn));
break;
case store:
- do_integer_store(((insn>>25)&0x1f), size,
- (unsigned long *) addr, regs,
- kernel_unaligned_trap_fault);
+ err = do_int_store(((insn>>25)&0x1f), size,
+ (unsigned long *) addr, regs);
break;
-#if 0 /* unsupported */
- case both:
- do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
- (unsigned long *) addr,
- kernel_unaligned_trap_fault);
- break;
-#endif
default:
panic("Impossible kernel unaligned trap.");
/* Not reached... */
}
- advance(regs);
+ if (err)
+ kernel_mna_trap_fault(regs, insn);
+ else
+ advance(regs);
}
}
@@ -459,9 +317,7 @@ static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
return 0;
}
-void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("user_mna_trap_fault");
-
-void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
{
siginfo_t info;
@@ -485,7 +341,7 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
if(!ok_for_user(regs, insn, dir)) {
goto kill_user;
} else {
- int size = decode_access_size(insn);
+ int err, size = decode_access_size(insn);
unsigned long addr;
if(floating_point_load_or_store_p(insn)) {
@@ -496,48 +352,34 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
addr = compute_effective_address(regs, insn);
switch(dir) {
case load:
- do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
- size, (unsigned long *) addr,
- decode_signedness(insn),
- user_unaligned_trap_fault);
+ err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
+ regs),
+ size, (unsigned long *) addr,
+ decode_signedness(insn));
break;
case store:
- do_integer_store(((insn>>25)&0x1f), size,
- (unsigned long *) addr, regs,
- user_unaligned_trap_fault);
+ err = do_int_store(((insn>>25)&0x1f), size,
+ (unsigned long *) addr, regs);
break;
case both:
-#if 0 /* unsupported */
- do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
- (unsigned long *) addr,
- user_unaligned_trap_fault);
-#else
/*
* This was supported in 2.4. However, we question
* the value of SWAP instruction across word boundaries.
*/
printk("Unaligned SWAP unsupported.\n");
- goto kill_user;
-#endif
+ err = -EFAULT;
break;
default:
unaligned_panic("Impossible user unaligned trap.");
-
- __asm__ __volatile__ ("\n"
-"user_unaligned_trap_fault:\n\t"
- "mov %0, %%o0\n\t"
- "call user_mna_trap_fault\n\t"
- " mov %1, %%o1\n\t"
- :
- : "r" (regs), "r" (insn)
- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
- "g1", "g2", "g3", "g4", "g5", "g7", "cc");
goto out;
}
- advance(regs);
+ if (err)
+ goto kill_user;
+ else
+ advance(regs);
goto out;
}
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index c0442e8c4b1..2375fe9dc31 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1941,9 +1941,7 @@ static pte_t *sun4c_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long add
if ((pte = sun4c_pte_alloc_one_fast(mm, address)) != NULL)
return pte;
- pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
- if (pte)
- memset(pte, 0, PAGE_SIZE);
+ pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
return pte;
}
diff --git a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c
index 37cff5f5470..d9fb3af41c1 100644
--- a/arch/sparc/prom/misc.c
+++ b/arch/sparc/prom/misc.c
@@ -45,9 +45,6 @@ prom_feval(char *fstring)
spin_unlock_irqrestore(&prom_lock, flags);
}
-/* We want to do this more nicely some day. */
-extern void (*prom_palette)(int);
-
/* Drop into the prom, with the chance to continue with the 'go'
* prom command.
*/
@@ -58,8 +55,6 @@ prom_cmdline(void)
extern void install_linux_ticker(void);
unsigned long flags;
- if (prom_palette)
- prom_palette (1);
spin_lock_irqsave(&prom_lock, flags);
install_obp_ticker();
(*(romvec->pv_abort))();
@@ -69,8 +64,6 @@ prom_cmdline(void)
#ifdef CONFIG_SUN_AUXIO
set_auxio(AUXIO_LED, 0);
#endif
- if (prom_palette)
- prom_palette (0);
}
/* Drop into the prom, but completely terminate the program.
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 3af378ddb6a..463d1be32c9 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -10,6 +10,7 @@ config SPARC
default y
select HAVE_OPROFILE
select HAVE_KPROBES
+ select HAVE_KRETPROBES
config SPARC64
bool
diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug
index a5faa3683bd..6a4d28a4076 100644
--- a/arch/sparc64/Kconfig.debug
+++ b/arch/sparc64/Kconfig.debug
@@ -23,10 +23,6 @@ config STACK_DEBUG
depends on DEBUG_KERNEL
bool "Stack Overflow Detection Support"
-config DEBUG_BOOTMEM
- depends on DEBUG_KERNEL
- bool "Debug BOOTMEM initialization"
-
config DEBUG_PAGEALLOC
bool "Debug page memory allocations"
depends on DEBUG_KERNEL && !HIBERNATION
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index 01159cb5f16..f0c22f82698 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -12,39 +12,13 @@ CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -m64
CPPFLAGS_vmlinux.lds += -Usparc
-CC := $(shell if $(CC) -m64 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo $(CC); else echo sparc64-linux-gcc; fi )
-
-NEW_GCC := $(call cc-option-yn, -m64 -mcmodel=medlow)
-NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
-UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; )
-
-ifneq ($(NEW_GAS),y)
-AS = sparc64-linux-as
-LD = sparc64-linux-ld
-NM = sparc64-linux-nm
-AR = sparc64-linux-ar
-RANLIB = sparc64-linux-ranlib
-else
-AS := $(AS) -64
LDFLAGS := -m elf64_sparc
-endif
-ifneq ($(UNDECLARED_REGS),y)
-CC_UNDECL =
-else
-CC_UNDECL = -Wa,--undeclared-regs
-AS := $(AS) --undeclared-regs
-endif
-
-ifneq ($(NEW_GCC),y)
- KBUILD_CFLAGS += -pipe -mno-fpu -mtune=ultrasparc -mmedlow \
- -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare
-else
- KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \
- -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \
- $(CC_UNDECL)
- KBUILD_AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL)
-endif
+KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \
+ -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \
+ -Wa,--undeclared-regs
+KBUILD_CFLAGS += $(call cc-option,-mtune=ultrasparc3)
+KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs
ifeq ($(CONFIG_MCOUNT),y)
KBUILD_CFLAGS += -pg
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 833d74b2b19..250958d1e3c 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24
-# Tue Feb 5 17:28:19 2008
+# Linux kernel version: 2.6.25-rc1
+# Sun Feb 17 22:44:12 2008
#
CONFIG_SPARC=y
CONFIG_SPARC64=y
@@ -10,6 +10,7 @@ CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_64BIT=y
CONFIG_MMU=y
+CONFIG_IOMMU_HELPER=y
CONFIG_QUICKLIST=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -21,6 +22,7 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_ARCH_NO_VIRT_TO_BUS=y
CONFIG_OF=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_SPARC64_PAGE_SIZE_8KB=y
# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
# CONFIG_SPARC64_PAGE_SIZE_512KB is not set
@@ -49,8 +51,6 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# 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 is not set
CONFIG_LOG_BUF_SHIFT=18
@@ -60,6 +60,11 @@ CONFIG_FAIR_USER_SCHED=y
# CONFIG_FAIR_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
+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
@@ -74,6 +79,7 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
+# CONFIG_COMPAT_BRK is not set
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
@@ -176,13 +182,13 @@ CONFIG_PCI_MSI=y
CONFIG_SUN_OPENPROMFS=m
CONFIG_SPARC32_COMPAT=y
CONFIG_COMPAT=y
-CONFIG_BINFMT_ELF32=y
# CONFIG_BINFMT_AOUT32 is not set
#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
+CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
CONFIG_SOLARIS_EMUL=y
CONFIG_SCHED_SMT=y
@@ -354,6 +360,8 @@ CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
@@ -376,6 +384,7 @@ CONFIG_IDE_PROC_FS=y
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
#
# PCI IDE chipsets support
@@ -775,7 +784,6 @@ CONFIG_I2C_ALGOBIT=y
# 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_TPS65010 is not set
# CONFIG_SENSORS_MAX6875 is not set
@@ -831,6 +839,7 @@ 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_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
@@ -840,9 +849,11 @@ 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_WATCHDOG is not set
#
@@ -1201,6 +1212,7 @@ CONFIG_USB_STORAGE=m
# CONFIG_USB_TEST is not set
# CONFIG_USB_GADGET is not set
# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
@@ -1242,12 +1254,10 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -1291,8 +1301,10 @@ CONFIG_HUGETLB_PAGE=y
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_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
@@ -1370,6 +1382,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS 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
@@ -1385,7 +1398,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_KPROBES_SANITY_TEST is not set
@@ -1396,7 +1408,6 @@ CONFIG_FORCED_INLINING=y
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_DCFLUSH is not set
# CONFIG_STACK_DEBUG is not set
-# CONFIG_DEBUG_BOOTMEM is not set
# CONFIG_DEBUG_PAGEALLOC is not set
#
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c
index e43db73f2b9..dd5d28e3d79 100644
--- a/arch/sparc64/kernel/cpu.c
+++ b/arch/sparc64/kernel/cpu.c
@@ -30,7 +30,7 @@ struct cpu_fp_info {
char* fp_name;
};
-struct cpu_fp_info linux_sparc_fpu[] = {
+static struct cpu_fp_info linux_sparc_fpu[] = {
{ 0x17, 0x10, 0, "UltraSparc I integrated FPU"},
{ 0x22, 0x10, 0, "UltraSparc I integrated FPU"},
{ 0x17, 0x11, 0, "UltraSparc II integrated FPU"},
@@ -46,7 +46,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
-struct cpu_iu_info linux_sparc_chips[] = {
+static struct cpu_iu_info linux_sparc_chips[] = {
{ 0x17, 0x10, "TI UltraSparc I (SpitFire)"},
{ 0x22, 0x10, "TI UltraSparc I (SpitFire)"},
{ 0x17, 0x11, "TI UltraSparc II (BlackBird)"},
diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c
index eeb5a2fc788..bd76482077b 100644
--- a/arch/sparc64/kernel/ds.c
+++ b/arch/sparc64/kernel/ds.c
@@ -525,10 +525,10 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus,
}
}
-static int dr_cpu_configure(struct ds_info *dp,
- struct ds_cap_state *cp,
- u64 req_num,
- cpumask_t *mask)
+static int __cpuinit dr_cpu_configure(struct ds_info *dp,
+ struct ds_cap_state *cp,
+ u64 req_num,
+ cpumask_t *mask)
{
struct ds_data *resp;
int resp_len, ncpus, cpu;
@@ -623,9 +623,9 @@ static int dr_cpu_unconfigure(struct ds_info *dp,
return 0;
}
-static void dr_cpu_data(struct ds_info *dp,
- struct ds_cap_state *cp,
- void *buf, int len)
+static void __cpuinit dr_cpu_data(struct ds_info *dp,
+ struct ds_cap_state *cp,
+ void *buf, int len)
{
struct ds_data *data = buf;
struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1);
diff --git a/arch/sparc64/kernel/hvtramp.S b/arch/sparc64/kernel/hvtramp.S
index b692e044a46..0236c43772f 100644
--- a/arch/sparc64/kernel/hvtramp.S
+++ b/arch/sparc64/kernel/hvtramp.S
@@ -3,6 +3,8 @@
* Copyright (C) 2007 David S. Miller <davem@davemloft.net>
*/
+#include <linux/init.h>
+
#include <asm/thread_info.h>
#include <asm/hypervisor.h>
#include <asm/scratchpad.h>
@@ -13,7 +15,7 @@
#include <asm/head.h>
#include <asm/asi.h>
- .text
+ __CPUINIT
.align 8
.globl hv_cpu_startup, hv_cpu_startup_end
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index d3276ebcfb4..fbaab3497bf 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -134,7 +134,8 @@ unsigned long iommu_range_alloc(struct device *dev,
else
boundary_size = ALIGN(1UL << 32, 1 << IO_PAGE_SHIFT);
- n = iommu_area_alloc(arena->map, limit, start, npages, 0,
+ n = iommu_area_alloc(arena->map, limit, start, npages,
+ iommu->page_table_map_base >> IO_PAGE_SHIFT,
boundary_size >> IO_PAGE_SHIFT, 0);
if (n == -1) {
if (likely(pass < 1)) {
@@ -200,12 +201,11 @@ int iommu_table_init(struct iommu *iommu, int tsbsize,
/* Allocate and initialize the dummy page which we
* set inactive IO PTEs to point to.
*/
- iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
+ iommu->dummy_page = get_zeroed_page(GFP_KERNEL);
if (!iommu->dummy_page) {
printk(KERN_ERR "IOMMU: Error, gfp(dummy_page) failed.\n");
goto out_free_map;
}
- memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
/* Now allocate and setup the IOMMU page table itself. */
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index 34fc3ddd500..f43b5d75535 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -465,8 +465,6 @@ void __kprobes jprobe_return(void)
extern void jprobe_return_trap_instruction(void);
-extern void __show_regs(struct pt_regs * regs);
-
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
u32 *addr = (u32 *) regs->tpc;
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c
index 856659bb131..91008358956 100644
--- a/arch/sparc64/kernel/mdesc.c
+++ b/arch/sparc64/kernel/mdesc.c
@@ -758,7 +758,7 @@ static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp,
get_one_mondo_bits(val, &tb->nonresum_qmask, 2);
}
-void __devinit mdesc_fill_in_cpu_data(cpumask_t mask)
+void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask)
{
struct mdesc_handle *hp = mdesc_grab();
u64 mp;
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index a61c38fe75e..545356b00e2 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -225,20 +225,6 @@ static int __init pci_controller_init(const char *model_name, int namelen, struc
return 0;
}
-static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp)
-{
- int i;
-
- for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) {
- if (!strncmp(model_name,
- pci_controller_table[i].model_name,
- namelen)) {
- return 1;
- }
- }
- return 0;
-}
-
static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *))
{
struct device_node *dp;
@@ -273,13 +259,6 @@ static int __init pci_controller_scan(int (*handler)(const char *, int, struct d
return count;
}
-
-/* Is there some PCI controller in the system? */
-int __init pcic_present(void)
-{
- return pci_controller_scan(pci_is_controller);
-}
-
/* Find each controller in the system, attach and initialize
* software state structure for each and link into the
* pci_pbm_root. Setup the controller enough such
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 850cdffdd69..eae8ca2a6ba 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -20,6 +20,7 @@
#include <asm/of_device.h>
#include <asm/io.h>
#include <asm/sstate.h>
+#include <asm/reboot.h>
#include <linux/unistd.h>
@@ -39,8 +40,6 @@ static irqreturn_t power_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-extern void machine_halt(void);
-extern void machine_alt_power_off(void);
static void (*poweroff_method)(void) = machine_alt_power_off;
void machine_power_off(void)
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 1b237917498..e116e38b160 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -30,6 +30,7 @@
#include <linux/tick.h>
#include <linux/init.h>
#include <linux/cpu.h>
+#include <linux/elfcore.h>
#include <asm/oplib.h>
#include <asm/uaccess.h>
@@ -47,6 +48,8 @@
#include <asm/unistd.h>
#include <asm/hypervisor.h>
#include <asm/sstate.h>
+#include <asm/reboot.h>
+#include <asm/syscalls.h>
/* #define VERBOSE_SHOWREGS */
@@ -111,18 +114,9 @@ void cpu_idle(void)
}
}
-extern char reboot_command [];
-
-extern void (*prom_palette)(int);
-extern void (*prom_keyboard)(void);
-
void machine_halt(void)
{
sstate_halt();
- if (prom_palette)
- prom_palette (1);
- if (prom_keyboard)
- prom_keyboard();
prom_halt();
panic("Halt failed!");
}
@@ -130,10 +124,6 @@ void machine_halt(void)
void machine_alt_power_off(void)
{
sstate_poweroff();
- if (prom_palette)
- prom_palette(1);
- if (prom_keyboard)
- prom_keyboard();
prom_halt_power_off();
panic("Power-off failed!");
}
@@ -145,10 +135,6 @@ void machine_restart(char * cmd)
sstate_reboot();
p = strchr (reboot_command, '\n');
if (p) *p = 0;
- if (prom_palette)
- prom_palette (1);
- if (prom_keyboard)
- prom_keyboard();
if (cmd)
prom_reboot(cmd);
if (*reboot_command)
@@ -226,62 +212,6 @@ static void show_regwindow(struct pt_regs *regs)
print_symbol("I7: <%s>\n", rwk->ins[7]);
}
-void show_stackframe(struct sparc_stackf *sf)
-{
- unsigned long size;
- unsigned long *stk;
- int i;
-
- printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n"
- "l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n",
- sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3],
- sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
- printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n"
- "i4: %016lx i5: %016lx fp: %016lx ret_pc: %016lx\n",
- sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3],
- sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc);
- printk("sp: %016lx x0: %016lx x1: %016lx x2: %016lx\n"
- "x3: %016lx x4: %016lx x5: %016lx xx: %016lx\n",
- (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1],
- sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
- sf->xxargs[0]);
- size = ((unsigned long)sf->fp) - ((unsigned long)sf);
- size -= STACKFRAME_SZ;
- stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ);
- i = 0;
- do {
- printk("s%d: %016lx\n", i++, *stk++);
- } while ((size -= sizeof(unsigned long)));
-}
-
-void show_stackframe32(struct sparc_stackf32 *sf)
-{
- unsigned long size;
- unsigned *stk;
- int i;
-
- printk("l0: %08x l1: %08x l2: %08x l3: %08x\n",
- sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3]);
- printk("l4: %08x l5: %08x l6: %08x l7: %08x\n",
- sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
- printk("i0: %08x i1: %08x i2: %08x i3: %08x\n",
- sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3]);
- printk("i4: %08x i5: %08x fp: %08x ret_pc: %08x\n",
- sf->ins[4], sf->ins[5], sf->fp, sf->callers_pc);
- printk("sp: %08x x0: %08x x1: %08x x2: %08x\n"
- "x3: %08x x4: %08x x5: %08x xx: %08x\n",
- sf->structptr, sf->xargs[0], sf->xargs[1],
- sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
- sf->xxargs[0]);
- size = ((unsigned long)sf->fp) - ((unsigned long)sf);
- size -= STACKFRAME32_SZ;
- stk = (unsigned *)((unsigned long)sf + STACKFRAME32_SZ);
- i = 0;
- do {
- printk("s%d: %08x\n", i++, *stk++);
- } while ((size -= sizeof(unsigned)));
-}
-
#ifdef CONFIG_SMP
static DEFINE_SPINLOCK(regdump_lock);
#endif
@@ -369,24 +299,6 @@ void show_regs(struct pt_regs *regs)
#endif
}
-void show_regs32(struct pt_regs32 *regs)
-{
- printk("PSR: %08x PC: %08x NPC: %08x Y: %08x %s\n", regs->psr,
- regs->pc, regs->npc, regs->y, print_tainted());
- printk("g0: %08x g1: %08x g2: %08x g3: %08x ",
- regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
- regs->u_regs[3]);
- printk("g4: %08x g5: %08x g6: %08x g7: %08x\n",
- regs->u_regs[4], regs->u_regs[5], regs->u_regs[6],
- regs->u_regs[7]);
- printk("o0: %08x o1: %08x o2: %08x o3: %08x ",
- regs->u_regs[8], regs->u_regs[9], regs->u_regs[10],
- regs->u_regs[11]);
- printk("o4: %08x o5: %08x sp: %08x ret_pc: %08x\n",
- regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
- regs->u_regs[15]);
-}
-
unsigned long thread_saved_pc(struct task_struct *tsk)
{
struct thread_info *ti = task_thread_info(tsk);
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index a246e962e5a..68964ddcde1 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -1716,7 +1716,6 @@ static void __init of_console_init(void)
of_console_device = dp;
- prom_printf(msg, of_console_path);
printk(msg, of_console_path);
}
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 5964d8653ad..d036dbe7286 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -68,33 +68,22 @@ struct screen_info screen_info = {
16 /* orig-video-points */
};
-void (*prom_palette)(int);
-void (*prom_keyboard)(void);
-
static void
prom_console_write(struct console *con, const char *s, unsigned n)
{
prom_write(s, n);
}
-unsigned int boot_flags = 0;
-#define BOOTME_DEBUG 0x1
-
/* Exported for mm/init.c:paging_init. */
unsigned long cmdline_memory_size = 0;
-static struct console prom_debug_console = {
- .name = "debug",
+static struct console prom_early_console = {
+ .name = "earlyprom",
.write = prom_console_write,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1,
};
-/* XXX Implement this at some point... */
-void kernel_enter_debugger(void)
-{
-}
-
/*
* Process kernel command line switches that are specific to the
* SPARC or that require special low-level processing.
@@ -103,8 +92,6 @@ static void __init process_switch(char c)
{
switch (c) {
case 'd':
- boot_flags |= BOOTME_DEBUG;
- break;
case 's':
break;
case 'h':
@@ -112,8 +99,7 @@ static void __init process_switch(char c)
prom_halt();
break;
case 'p':
- /* Use PROM debug console. */
- register_console(&prom_debug_console);
+ /* Just ignore, this behavior is now the default. */
break;
case 'P':
/* Force UltraSPARC-III P-Cache on. */
@@ -168,8 +154,6 @@ static void __init boot_flags_init(char *commands)
}
}
-extern void panic_setup(char *, int *);
-
extern unsigned short root_flags;
extern unsigned short root_dev;
extern unsigned short ram_flags;
@@ -296,6 +280,9 @@ void __init setup_arch(char **cmdline_p)
*cmdline_p = prom_getbootargs();
strcpy(boot_command_line, *cmdline_p);
+ boot_flags_init(*cmdline_p);
+ register_console(&prom_early_console);
+
if (tlb_type == hypervisor)
printk("ARCH: SUN4V\n");
else
@@ -307,8 +294,6 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &prom_con;
#endif
- boot_flags_init(*cmdline_p);
-
idprom_init();
if (!root_flags)
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index a8052b76df4..cc454731d87 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -86,7 +86,7 @@ extern void setup_sparc64_timer(void);
static volatile unsigned long callin_flag = 0;
-void __devinit smp_callin(void)
+void __cpuinit smp_callin(void)
{
int cpuid = hard_smp_processor_id();
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 68db0893039..51fa773f38c 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -85,7 +85,6 @@ extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
extern long sparc32_open(const char __user * filename, int flags, int mode);
extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
unsigned long pfn, unsigned long size, pgprot_t prot);
-extern void (*prom_palette)(int);
extern int __ashrdi3(int, int);
@@ -355,5 +354,3 @@ EXPORT_SYMBOL(xor_niagara_2);
EXPORT_SYMBOL(xor_niagara_3);
EXPORT_SYMBOL(xor_niagara_4);
EXPORT_SYMBOL(xor_niagara_5);
-
-EXPORT_SYMBOL(prom_palette);
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
index 04e81dda13d..4ae2e525d68 100644
--- a/arch/sparc64/kernel/trampoline.S
+++ b/arch/sparc64/kernel/trampoline.S
@@ -4,6 +4,8 @@
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*/
+#include <linux/init.h>
+
#include <asm/head.h>
#include <asm/asi.h>
#include <asm/lsu.h>
@@ -36,7 +38,7 @@ dtlb_load:
tramp_stack:
.skip TRAMP_STACK_SIZE
- .text
+ __CPUINIT
.align 8
.globl sparc64_cpu_startup, sparc64_cpu_startup_end
sparc64_cpu_startup:
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 2b6abf63334..007f5317c0d 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1791,8 +1791,6 @@ static const char *sun4v_err_type_to_str(u32 type)
};
}
-extern void __show_regs(struct pt_regs * regs);
-
static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt)
{
int cnt;
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index dc7bf1b6321..1a511e9f0d3 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -7,6 +7,7 @@
*/
+#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -283,7 +284,7 @@ static void log_unaligned(struct pt_regs *regs)
{
static unsigned long count, last_time;
- if (jiffies - last_time > 5 * HZ)
+ if (time_after(jiffies, last_time + 5 * HZ))
count = 0;
if (count < 5) {
last_time = jiffies;
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index e2027f27c0f..2650d0d33ac 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -244,16 +244,8 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
if (regs->tstate & TSTATE_PRIV) {
const struct exception_table_entry *entry;
- if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
- if (insn & 0x2000)
- asi = (regs->tstate >> 24);
- else
- asi = (insn >> 5);
- }
-
- /* Look in asi.h: All _S asis have LS bit set */
- if ((asi & 0x1) &&
- (entry = search_exception_tables(regs->tpc))) {
+ entry = search_exception_tables(regs->tpc);
+ if (entry) {
regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
return;
@@ -294,7 +286,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
unsigned long tpc = regs->tpc;
/* Sanity check the PC. */
- if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
+ if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) ||
(tpc >= MODULES_VADDR && tpc < MODULES_END)) {
/* Valid, no problems... */
} else {
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index e726c45645f..b5c30416fda 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -618,9 +618,9 @@ static void __init inherit_prom_mappings(void)
read_obp_translations();
/* Now fixup OBP's idea about where we really are mapped. */
- prom_printf("Remapping the kernel... ");
+ printk("Remapping the kernel... ");
remap_kernel();
- prom_printf("done.\n");
+ printk("done.\n");
}
void prom_world(int enter)
@@ -739,11 +739,6 @@ static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn,
avoid_end = PAGE_ALIGN(initrd_end);
#endif
-#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("choose_bootmap_pfn: kern[%lx:%lx] avoid[%lx:%lx]\n",
- kern_base, PAGE_ALIGN(kern_base + kern_size),
- avoid_start, avoid_end);
-#endif
for (i = 0; i < pavail_ents; i++) {
unsigned long start, end;
@@ -777,10 +772,6 @@ static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn,
}
/* OK, it doesn't overlap anything, use it. */
-#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("choose_bootmap_pfn: Using %lx [%lx]\n",
- start >> PAGE_SHIFT, start);
-#endif
return start >> PAGE_SHIFT;
}
}
@@ -920,10 +911,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
unsigned long bootmap_pfn, bytes_avail, size;
int i;
-#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("bootmem_init: Scan pavail, ");
-#endif
-
bytes_avail = 0UL;
for (i = 0; i < pavail_ents; i++) {
end_of_phys_memory = pavail[i].phys_addr +
@@ -970,33 +957,20 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
bootmap_pfn = choose_bootmap_pfn(min_low_pfn, end_pfn);
-#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("init_bootmem(min[%lx], bootmap[%lx], max[%lx])\n",
- min_low_pfn, bootmap_pfn, max_low_pfn);
-#endif
bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn,
min_low_pfn, end_pfn);
/* Now register the available physical memory with the
* allocator.
*/
- for (i = 0; i < pavail_ents; i++) {
-#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("free_bootmem(pavail:%d): base[%lx] size[%lx]\n",
- i, pavail[i].phys_addr, pavail[i].reg_size);
-#endif
+ for (i = 0; i < pavail_ents; i++)
free_bootmem(pavail[i].phys_addr, pavail[i].reg_size);
- }
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start) {
size = initrd_end - initrd_start;
/* Reserve the initrd image area. */
-#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("reserve_bootmem(initrd): base[%llx] size[%lx]\n",
- initrd_start, initrd_end);
-#endif
reserve_bootmem(initrd_start, size, BOOTMEM_DEFAULT);
initrd_start += PAGE_OFFSET;
@@ -1004,9 +978,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
}
#endif
/* Reserve the kernel text/data/bss. */
-#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("reserve_bootmem(kernel): base[%lx] size[%lx]\n", kern_base, kern_size);
-#endif
reserve_bootmem(kern_base, kern_size, BOOTMEM_DEFAULT);
*pages_avail -= PAGE_ALIGN(kern_size) >> PAGE_SHIFT;
@@ -1020,10 +991,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
* in free_all_bootmem.
*/
size = bootmap_size;
-#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("reserve_bootmem(bootmap): base[%lx] size[%lx]\n",
- (bootmap_pfn << PAGE_SHIFT), size);
-#endif
reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size, BOOTMEM_DEFAULT);
for (i = 0; i < pavail_ents; i++) {
@@ -1031,10 +998,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
start_pfn = pavail[i].phys_addr >> PAGE_SHIFT;
end_pfn = (start_pfn + (pavail[i].reg_size >> PAGE_SHIFT));
-#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("memory_present(0, %lx, %lx)\n",
- start_pfn, end_pfn);
-#endif
memory_present(0, start_pfn, end_pfn);
}
@@ -1047,7 +1010,8 @@ static struct linux_prom64_registers pall[MAX_BANKS] __initdata;
static int pall_ents __initdata;
#ifdef CONFIG_DEBUG_PAGEALLOC
-static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot)
+static unsigned long __ref kernel_map_range(unsigned long pstart,
+ unsigned long pend, pgprot_t prot)
{
unsigned long vstart = PAGE_OFFSET + pstart;
unsigned long vend = PAGE_OFFSET + pend;
@@ -1451,7 +1415,7 @@ void __init paging_init(void)
zholes_size);
}
- prom_printf("Booting Linux...\n");
+ printk("Booting Linux...\n");
central_probe();
cpu_probe();
@@ -1549,10 +1513,6 @@ void __init mem_init(void)
high_memory = __va(last_valid_pfn << PAGE_SHIFT);
-#ifdef CONFIG_DEBUG_BOOTMEM
- prom_printf("mem_init: Calling free_all_bootmem().\n");
-#endif
-
/* We subtract one to account for the mem_map_zero page
* allocated below.
*/
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
index bbec7522826..47a877a15ab 100644
--- a/arch/sparc64/prom/misc.c
+++ b/arch/sparc64/prom/misc.c
@@ -55,9 +55,6 @@ void prom_feval(const char *fstring)
P1275_INOUT(1, 1), fstring);
}
-/* We want to do this more nicely some day. */
-extern void (*prom_palette)(int);
-
#ifdef CONFIG_SMP
extern void smp_capture(void);
extern void smp_release(void);
@@ -72,9 +69,6 @@ void prom_cmdline(void)
local_irq_save(flags);
- if (prom_palette)
- prom_palette(1);
-
#ifdef CONFIG_SMP
smp_capture();
#endif
@@ -85,9 +79,6 @@ void prom_cmdline(void)
smp_release();
#endif
- if (prom_palette)
- prom_palette(0);
-
local_irq_restore(flags);
}
diff --git a/arch/sparc64/solaris/conv.h b/arch/sparc64/solaris/conv.h
index 5faf59a9de3..50e58232cf2 100644
--- a/arch/sparc64/solaris/conv.h
+++ b/arch/sparc64/solaris/conv.h
@@ -28,7 +28,7 @@ extern unsigned sunos_sys_table[];
#define SUNOS(x) ((long)sunos_sys_table[x])
#ifdef DEBUG_SOLARIS
-#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__FUNCTION__,(s))
+#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__func__,(s))
#define SOLDD(s) printk("solaris: "); printk s
#else
#define SOLD(s)
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
index f53123c02c2..15234fcd191 100644
--- a/arch/sparc64/solaris/timod.c
+++ b/arch/sparc64/solaris/timod.c
@@ -81,7 +81,7 @@ void mykfree(void *p)
#define MKCTL_MAGIC 0xDEADBABEBADC0DEDL
#define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0)
#define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\
- __FILE__,__LINE__,__FUNCTION__,(m),(a));}while(0)
+ __FILE__,__LINE__,__func__,(m),(a));}while(0)
#define BUF_OFFSET sizeof(u64)
#define MKCTL_TRAILER sizeof(u64)
diff --git a/arch/um/defconfig b/arch/um/defconfig
index 59215bc264e..6bd456f96f9 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -1,13 +1,22 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17-rc3
-# Fri Apr 28 09:31:20 2006
+# Linux kernel version: 2.6.24
+# Thu Feb 7 11:48:55 2008
#
+CONFIG_DEFCONFIG_LIST="arch/$ARCH/defconfig"
CONFIG_GENERIC_HARDIRQS=y
CONFIG_UML=y
CONFIG_MMU=y
+CONFIG_NO_IOMEM=y
+# CONFIG_TRACE_IRQFLAGS_SUPPORT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_STACKTRACE_SUPPORT is not set
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_IRQ_RELEASE_METHOD=y
+CONFIG_HZ=100
#
# UML-specific options
@@ -40,11 +49,13 @@ CONFIG_M686=y
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
+# CONFIG_MPSC is not set
+# CONFIG_MCORE2 is not set
+# CONFIG_GENERIC_CPU is not set
# CONFIG_X86_GENERIC is not set
CONFIG_X86_CMPXCHG=y
-CONFIG_X86_XADD=y
CONFIG_X86_L1_CACHE_SHIFT=5
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_X86_XADD=y
CONFIG_X86_PPRO_FENCE=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
@@ -53,7 +64,12 @@ CONFIG_X86_POPAD_OK=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_TSC=y
+CONFIG_X86_CMOV=y
+CONFIG_X86_MINIMUM_CPU_FAMILY=4
+CONFIG_X86_DEBUGCTLMSR=y
CONFIG_UML_X86=y
+CONFIG_X86_32=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
# CONFIG_64BIT is not set
CONFIG_SEMAPHORE_SLEEPERS=y
# CONFIG_3_LEVEL_PGTABLES is not set
@@ -67,13 +83,18 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=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_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_LD_SCRIPT_DYN=y
-CONFIG_NET=y
CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
CONFIG_BINFMT_MISC=m
CONFIG_HOSTFS=y
# CONFIG_HPPFS is not set
@@ -83,31 +104,38 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_KERNEL_STACK_ORDER=0
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
+CONFIG_INIT_ENV_ARG_LIMIT=128
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# 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_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
+# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
CONFIG_KALLSYMS_EXTRA_PASS=y
@@ -117,29 +145,36 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=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_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 is not set
+# CONFIG_HAVE_KPROBES is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
-
-#
-# Block layer
-#
+CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -153,19 +188,16 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Block devices
-#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_UBD=y
# CONFIG_BLK_DEV_UBD_SYNC is not set
CONFIG_BLK_DEV_COW_COMMON=y
-# CONFIG_MMAPPER is not set
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_ATA_OVER_ETH is not set
#
@@ -185,32 +217,43 @@ CONFIG_CON_CHAN="xterm"
CONFIG_SSL_CHAN="pts"
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
+# CONFIG_RAW_DRIVER is not set
CONFIG_LEGACY_PTY_COUNT=32
# CONFIG_WATCHDOG is not set
CONFIG_UML_SOUND=m
CONFIG_SOUND=m
CONFIG_HOSTAUDIO=m
+# CONFIG_HW_RANDOM is not set
CONFIG_UML_RANDOM=y
+# CONFIG_MMAPPER is not set
#
# Generic Driver Options
#
+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
#
# Networking
#
+CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
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 is not set
@@ -226,28 +269,23 @@ CONFIG_IP_FIB_HASH=y
# 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_BIC=y
+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_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -258,13 +296,8 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
# CONFIG_NET_SCHED is not set
#
@@ -272,9 +305,20 @@ CONFIG_TCP_CONG_BIC=y
#
# 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
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# UML Network Devices
@@ -284,31 +328,24 @@ CONFIG_UML_NET_ETHERTAP=y
CONFIG_UML_NET_TUNTAP=y
CONFIG_UML_NET_SLIP=y
CONFIG_UML_NET_DAEMON=y
+# CONFIG_UML_NET_VDE is not set
CONFIG_UML_NET_MCAST=y
# CONFIG_UML_NET_PCAP is not set
CONFIG_UML_NET_SLIRP=y
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
+# CONFIG_VETH is not set
#
-# PHY device support
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
# CONFIG_WAN is not set
CONFIG_PPP=m
# CONFIG_PPP_MULTILINK is not set
@@ -319,18 +356,15 @@ CONFIG_PPP=m
# CONFIG_PPP_BSDCOMP is not set
# CONFIG_PPP_MPPE is not set
# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
CONFIG_SLIP=m
# CONFIG_SLIP_COMPRESSED is not set
+CONFIG_SLHC=m
# CONFIG_SLIP_SMART is not set
# CONFIG_SLIP_MODE_SLIP6 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
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
# CONFIG_CONNECTOR is not set
#
@@ -341,8 +375,8 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
CONFIG_REISERFS_FS=y
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
@@ -350,11 +384,15 @@ CONFIG_REISERFS_FS=y
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
# CONFIG_QFMT_V1 is not set
# CONFIG_QFMT_V2 is not set
CONFIG_QUOTACTL=y
@@ -383,10 +421,11 @@ CONFIG_JOLIET=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
#
@@ -405,10 +444,7 @@ CONFIG_RAMFS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
# CONFIG_SMB_FS is not set
@@ -416,17 +452,12 @@ CONFIG_RAMFS=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
@@ -467,33 +498,83 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_SEQIV is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_TWOFISH_586 is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_AES_586 is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SALSA20_586 is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
#
# Library routines
#
+CONFIG_BITREVERSE=m
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=m
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_DMA=y
#
-# Multi-device support (RAID and LVM)
+# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
# CONFIG_MD is not set
# CONFIG_INPUT is not set
@@ -501,23 +582,36 @@ CONFIG_CRC32=m
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SLAB_LEAK is not set
-# CONFIG_DEBUG_MUTEXES 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_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
# CONFIG_GPROF is not set
# CONFIG_GCOV is not set
# CONFIG_DEBUG_STACK_USAGE is not set
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index 448ba59207a..b56f8e0196a 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -79,14 +79,14 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
n = read(in_fds[0], &c, sizeof(c));
if (n == 0) {
printk("harddog_open - EOF on watchdog pipe\n");
- helper_wait(pid, 1, NULL);
+ helper_wait(pid);
err = -EIO;
goto out_close_out;
}
else if (n < 0) {
printk("harddog_open - read of watchdog pipe failed, "
"err = %d\n", errno);
- helper_wait(pid, 1, NULL);
+ helper_wait(pid);
err = n;
goto out_close_out;
}
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index 9ea1ae3c8f4..b0b4589e0eb 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -18,5 +18,7 @@ extern int restore_registers(int pid, struct uml_pt_regs *regs);
extern int init_registers(int pid);
extern void get_safe_registers(unsigned long *regs);
extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
+extern int get_fp_registers(int pid, unsigned long *regs);
+extern int put_fp_registers(int pid, unsigned long *regs);
#endif
diff --git a/arch/um/include/sysdep-i386/ptrace_user.h b/arch/um/include/sysdep-i386/ptrace_user.h
index 899aa4b2a78..75650723c38 100644
--- a/arch/um/include/sysdep-i386/ptrace_user.h
+++ b/arch/um/include/sysdep-i386/ptrace_user.h
@@ -9,6 +9,7 @@
#include <sys/ptrace.h>
#include <linux/ptrace.h>
#include <asm/ptrace.h>
+#include "user_constants.h"
#define PT_OFFSET(r) ((r) * sizeof(long))
@@ -40,6 +41,8 @@
#define PT_SP_OFFSET PT_OFFSET(UESP)
#define PT_SP(regs) ((regs)[UESP])
+#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE)
+
#ifndef FRAME_SIZE
#define FRAME_SIZE (17)
#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h
index 4cd61a852fa..45c0bd881cb 100644
--- a/arch/um/include/sysdep-x86_64/ptrace_user.h
+++ b/arch/um/include/sysdep-x86_64/ptrace_user.h
@@ -12,6 +12,7 @@
#include <linux/ptrace.h>
#include <asm/ptrace.h>
#undef __FRAME_OFFSETS
+#include "user_constants.h"
#define PT_INDEX(off) ((off) / sizeof(unsigned long))
@@ -69,6 +70,8 @@
#define REGS_IP_INDEX PT_INDEX(RIP)
#define REGS_SP_INDEX PT_INDEX(RSP)
+#define FP_SIZE (HOST_FP_SIZE)
+
#endif
/*
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c
index fa015565001..d386c75c88e 100644
--- a/arch/um/kernel/initrd.c
+++ b/arch/um/kernel/initrd.c
@@ -32,7 +32,7 @@ static int __init read_initrd(void)
* ask for no memory.
*/
if (size == 0) {
- printk(KERN_ERR "\"%\" is a zero-size initrd\n");
+ printk(KERN_ERR "\"%s\" is a zero-size initrd\n", initrd);
return 0;
}
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 2627ce82e91..2eea1ff235e 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -299,7 +299,7 @@ void show_mem(void)
{
int pfn, total = 0, reserved = 0;
int shared = 0, cached = 0;
- int highmem = 0;
+ int high_mem = 0;
struct page *page;
printk(KERN_INFO "Mem-info:\n");
@@ -311,7 +311,7 @@ void show_mem(void)
page = pfn_to_page(pfn);
total++;
if (PageHighMem(page))
- highmem++;
+ high_mem++;
if (PageReserved(page))
reserved++;
else if (PageSwapCache(page))
@@ -320,7 +320,7 @@ void show_mem(void)
shared += page_count(page) - 1;
}
printk(KERN_INFO "%d pages of RAM\n", total);
- printk(KERN_INFO "%d pages of HIGHMEM\n", highmem);
+ printk(KERN_INFO "%d pages of HIGHMEM\n", high_mem);
printk(KERN_INFO "%d reserved pages\n", reserved);
printk(KERN_INFO "%d pages shared\n", shared);
printk(KERN_INFO "%d pages swap cached\n", cached);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index fc50d2f959d..e8cb9ff183e 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -128,8 +128,6 @@ void *get_current(void)
return current;
}
-extern void schedule_tail(struct task_struct *prev);
-
/*
* This is called magically, by its address being stuffed in a jmp_buf
* and being longjmp-d to.
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index b14829469fa..1e8cba6550a 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -115,6 +115,14 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
sizeof(struct ptrace_faultinfo));
}
else {
+ unsigned long fpregs[FP_SIZE];
+
+ err = get_fp_registers(pid, fpregs);
+ if (err < 0) {
+ printk(UM_KERN_ERR "save_fp_registers returned %d\n",
+ err);
+ fatal_sigsegv();
+ }
err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
if (err) {
printk(UM_KERN_ERR "Failed to continue stub, pid = %d, "
@@ -128,6 +136,13 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
* the stub stack page. We just have to copy it.
*/
memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
+
+ err = put_fp_registers(pid, fpregs);
+ if (err < 0) {
+ printk(UM_KERN_ERR "put_fp_registers returned %d\n",
+ err);
+ fatal_sigsegv();
+ }
}
}
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index f74d853a0ee..b613473b3ec 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -56,6 +56,22 @@ unsigned long get_thread_reg(int reg, jmp_buf *buf)
int have_fpx_regs = 1;
+int get_fp_registers(int pid, unsigned long *regs)
+{
+ if (have_fpx_regs)
+ return save_fpx_registers(pid, regs);
+ else
+ return save_fp_registers(pid, regs);
+}
+
+int put_fp_registers(int pid, unsigned long *regs)
+{
+ if (have_fpx_regs)
+ return restore_fpx_registers(pid, regs);
+ else
+ return restore_fp_registers(pid, regs);
+}
+
void arch_init_registers(int pid)
{
unsigned long fpx_regs[HOST_XFP_SIZE];
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index a375853337a..594d97ad02b 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -40,3 +40,13 @@ unsigned long get_thread_reg(int reg, jmp_buf *buf)
return 0;
}
}
+
+int get_fp_registers(int pid, unsigned long *regs)
+{
+ return save_fp_registers(pid, regs);
+}
+
+int put_fp_registers(int pid, unsigned long *regs)
+{
+ return restore_fp_registers(pid, regs);
+}
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 514241526a1..39bd32bf84f 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -17,36 +17,9 @@
void foo(void)
{
- OFFSET(HOST_SC_IP, sigcontext, eip);
- OFFSET(HOST_SC_SP, sigcontext, esp);
- OFFSET(HOST_SC_FS, sigcontext, fs);
- OFFSET(HOST_SC_GS, sigcontext, gs);
- OFFSET(HOST_SC_DS, sigcontext, ds);
- OFFSET(HOST_SC_ES, sigcontext, es);
- OFFSET(HOST_SC_SS, sigcontext, ss);
- OFFSET(HOST_SC_CS, sigcontext, cs);
- OFFSET(HOST_SC_EFLAGS, sigcontext, eflags);
- OFFSET(HOST_SC_EAX, sigcontext, eax);
- OFFSET(HOST_SC_EBX, sigcontext, ebx);
- OFFSET(HOST_SC_ECX, sigcontext, ecx);
- OFFSET(HOST_SC_EDX, sigcontext, edx);
- OFFSET(HOST_SC_EDI, sigcontext, edi);
- OFFSET(HOST_SC_ESI, sigcontext, esi);
- OFFSET(HOST_SC_EBP, sigcontext, ebp);
OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
OFFSET(HOST_SC_ERR, sigcontext, err);
OFFSET(HOST_SC_CR2, sigcontext, cr2);
- OFFSET(HOST_SC_FPSTATE, sigcontext, fpstate);
- OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask);
- OFFSET(HOST_SC_FP_CW, _fpstate, cw);
- OFFSET(HOST_SC_FP_SW, _fpstate, sw);
- OFFSET(HOST_SC_FP_TAG, _fpstate, tag);
- OFFSET(HOST_SC_FP_IPOFF, _fpstate, ipoff);
- OFFSET(HOST_SC_FP_CSSEL, _fpstate, cssel);
- OFFSET(HOST_SC_FP_DATAOFF, _fpstate, dataoff);
- OFFSET(HOST_SC_FP_DATASEL, _fpstate, datasel);
- OFFSET(HOST_SC_FP_ST, _fpstate, _st);
- OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env);
DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct));
DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fpxregs_struct));
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index f1ef2a8dfbc..2f3443c6e85 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -19,37 +19,9 @@
void foo(void)
{
- OFFSET(HOST_SC_RBX, sigcontext, rbx);
- OFFSET(HOST_SC_RCX, sigcontext, rcx);
- OFFSET(HOST_SC_RDX, sigcontext, rdx);
- OFFSET(HOST_SC_RSI, sigcontext, rsi);
- OFFSET(HOST_SC_RDI, sigcontext, rdi);
- OFFSET(HOST_SC_RBP, sigcontext, rbp);
- OFFSET(HOST_SC_RAX, sigcontext, rax);
- OFFSET(HOST_SC_R8, sigcontext, r8);
- OFFSET(HOST_SC_R9, sigcontext, r9);
- OFFSET(HOST_SC_R10, sigcontext, r10);
- OFFSET(HOST_SC_R11, sigcontext, r11);
- OFFSET(HOST_SC_R12, sigcontext, r12);
- OFFSET(HOST_SC_R13, sigcontext, r13);
- OFFSET(HOST_SC_R14, sigcontext, r14);
- OFFSET(HOST_SC_R15, sigcontext, r15);
- OFFSET(HOST_SC_IP, sigcontext, rip);
- OFFSET(HOST_SC_SP, sigcontext, rsp);
OFFSET(HOST_SC_CR2, sigcontext, cr2);
OFFSET(HOST_SC_ERR, sigcontext, err);
OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
- OFFSET(HOST_SC_CS, sigcontext, cs);
- OFFSET(HOST_SC_FS, sigcontext, fs);
- OFFSET(HOST_SC_GS, sigcontext, gs);
- OFFSET(HOST_SC_EFLAGS, sigcontext, eflags);
- OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask);
-#if 0
- OFFSET(HOST_SC_ORIG_RAX, sigcontext, orig_rax);
- OFFSET(HOST_SC_DS, sigcontext, ds);
- OFFSET(HOST_SC_ES, sigcontext, es);
- OFFSET(HOST_SC_SS, sigcontext, ss);
-#endif
DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
DEFINE(HOST_XFP_SIZE, 0);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 3be2305709b..f41c9538ca3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -21,7 +21,8 @@ config X86
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_KPROBES
- select HAVE_KVM
+ select HAVE_KRETPROBES
+ select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
config GENERIC_LOCKBREAK
@@ -1054,7 +1055,7 @@ config SECCOMP
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
- depends on X86_64 && EXPERIMENTAL
+ depends on X86_64 && EXPERIMENTAL && BROKEN
help
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of critical functions, a canary
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index e09a6b73a1a..9304bfba7d4 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -377,6 +377,19 @@ config X86_OOSTORE
def_bool y
depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
+#
+# P6_NOPs are a relatively minor optimization that require a family >=
+# 6 processor, except that it is broken on certain VIA chips.
+# Furthermore, AMD chips prefer a totally different sequence of NOPs
+# (which work on all CPUs). As a result, disallow these if we're
+# compiling X86_GENERIC but not X86_64 (these NOPs do work on all
+# x86-64 capable chips); the list of processors in the right-hand clause
+# are the cores that benefit from this optimization.
+#
+config X86_P6_NOP
+ def_bool y
+ depends on (X86_64 || !X86_GENERIC) && (M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4)
+
config X86_TSC
def_bool y
depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64
@@ -390,6 +403,7 @@ config X86_CMOV
config X86_MINIMUM_CPU_FAMILY
int
default "64" if X86_64
+ default "6" if X86_32 && X86_P6_NOP
default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK)
default "3"
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 864affc9a7b..702eb39901c 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -156,7 +156,7 @@ config IO_DELAY_TYPE_NONE
choice
prompt "IO delay type"
- default IO_DELAY_0XED
+ default IO_DELAY_0X80
config IO_DELAY_0X80
bool "port 0x80 based port-IO delay [recommended]"
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 204af43535c..f1e739a43d4 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -229,7 +229,7 @@ zdisk bzdisk: vmlinux
fdimage fdimage144 fdimage288 isoimage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
-install: vdso_install
+install:
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
PHONY += vdso_install
diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
index 378353956b5..e77d89f9e8a 100644
--- a/arch/x86/boot/memory.c
+++ b/arch/x86/boot/memory.c
@@ -37,6 +37,12 @@ static int detect_memory_e820(void)
"=m" (*desc)
: "D" (desc), "d" (SMAP), "a" (0xe820));
+ /* BIOSes which terminate the chain with CF = 1 as opposed
+ to %ebx = 0 don't always report the SMAP signature on
+ the final, failing, probe. */
+ if (err)
+ break;
+
/* Some BIOSes stop returning SMAP in the middle of
the search loop. We don't know exactly how the BIOS
screwed up the map at that point, we might have a
@@ -47,9 +53,6 @@ static int detect_memory_e820(void)
break;
}
- if (err)
- break;
-
count++;
desc++;
} while (next && count < E820MAX);
diff --git a/arch/x86/boot/vesa.h b/arch/x86/boot/vesa.h
index ff5b73cd406..468e444622c 100644
--- a/arch/x86/boot/vesa.h
+++ b/arch/x86/boot/vesa.h
@@ -26,17 +26,10 @@ struct vesa_general_info {
far_ptr video_mode_ptr; /* 14 */
u16 total_memory; /* 18 */
- u16 oem_software_rev; /* 20 */
- far_ptr oem_vendor_name_ptr; /* 22 */
- far_ptr oem_product_name_ptr; /* 26 */
- far_ptr oem_product_rev_ptr; /* 30 */
-
- u8 reserved[222]; /* 34 */
- u8 oem_data[256]; /* 256 */
+ u8 reserved[236]; /* 20 */
} __attribute__ ((packed));
#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
-#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
struct vesa_mode_info {
u16 mode_attr; /* 0 */
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
index 662dd2f1306..419b5c27337 100644
--- a/arch/x86/boot/video-vesa.c
+++ b/arch/x86/boot/video-vesa.c
@@ -37,8 +37,6 @@ static int vesa_probe(void)
video_vesa.modes = GET_HEAP(struct mode_info, 0);
- vginfo.signature = VBE2_MAGIC;
-
ax = 0x4f00;
di = (size_t)&vginfo;
asm(INT10
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 1c0503bdfb1..5e7771a3ba2 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -500,7 +500,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
regs->ss = __USER32_DS;
set_fs(USER_DS);
- regs->flags &= ~X86_EFLAGS_TF;
+ regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF);
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
@@ -600,7 +600,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->ss = __USER32_DS;
set_fs(USER_DS);
- regs->flags &= ~X86_EFLAGS_TF;
+ regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF);
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 76ec0f8f138..4eb5ce84110 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -6,7 +6,15 @@ extra-y := head_$(BITS).o init_task.o vmlinux.lds
extra-$(CONFIG_X86_64) += head64.o
CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
-CFLAGS_vsyscall_64.o := $(PROFILING) -g0
+
+#
+# vsyscalls (which work on the user stack) should have
+# no stack-protector checks:
+#
+nostackp := $(call cc-option, -fno-stack-protector)
+CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp)
+CFLAGS_hpet.o := $(nostackp)
+CFLAGS_tsc_64.o := $(nostackp)
obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
obj-y += traps_$(BITS).o irq_$(BITS).o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 680b7300a48..2cdc9de9371 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -72,7 +72,8 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return
#define PREFIX "ACPI: "
int acpi_noirq; /* skip ACPI IRQ initialization */
-int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */
+int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */
+EXPORT_SYMBOL(acpi_pci_disabled);
int acpi_ht __initdata = 1; /* enable HT */
int acpi_lapic;
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index afd84463b71..8ea040124f7 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -20,10 +20,8 @@
#include <xen/interface/xen.h>
-#ifdef CONFIG_LGUEST_GUEST
#include <linux/lguest.h>
#include "../../../drivers/lguest/lg.h"
-#endif
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -130,10 +128,12 @@ void foo(void)
OFFSET(XEN_vcpu_info_pending, vcpu_info, evtchn_upcall_pending);
#endif
-#ifdef CONFIG_LGUEST_GUEST
+#if defined(CONFIG_LGUEST) || defined(CONFIG_LGUEST_GUEST) || defined(CONFIG_LGUEST_MODULE)
BLANK();
OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
OFFSET(LGUEST_DATA_pgdir, lguest_data, pgdir);
+
+ BLANK();
OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc);
OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc);
OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3);
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 9b95edcfc6a..027e5c003b1 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -25,14 +25,6 @@ static int __init no_halt(char *s)
__setup("no-hlt", no_halt);
-static int __init mca_pentium(char *s)
-{
- mca_pentium_flag = 1;
- return 1;
-}
-
-__setup("mca-pentium", mca_pentium);
-
static int __init no_387(char *s)
{
boot_cpu_data.hard_math = 0;
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index f86a3c4a266..a38aafaefc2 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -504,7 +504,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
/* Clear all flags overriden by options */
for (i = 0; i < NCAPINTS; i++)
- c->x86_capability[i] ^= cleared_cpu_caps[i];
+ c->x86_capability[i] &= ~cleared_cpu_caps[i];
/* Init Machine Check Exception if available. */
mcheck_init(c);
diff --git a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
index 39f8cb18296..c2f930d8664 100644
--- a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
+++ b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
@@ -55,7 +55,6 @@ static int eps_set_state(struct eps_cpu_data *centaur,
{
struct cpufreq_freqs freqs;
u32 lo, hi;
- u8 current_multiplier, current_voltage;
int err = 0;
int i;
@@ -95,6 +94,10 @@ postchange:
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
freqs.new = centaur->fsb * ((lo >> 8) & 0xff);
+#ifdef DEBUG
+ {
+ u8 current_multiplier, current_voltage;
+
/* Print voltage and multiplier */
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
current_voltage = lo & 0xff;
@@ -103,7 +106,8 @@ postchange:
current_multiplier = (lo >> 8) & 0xff;
printk(KERN_INFO "eps: Current multiplier = %d\n",
current_multiplier);
-
+ }
+#endif
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return err;
}
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index b6e136f23d3..be83336fddb 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -43,6 +43,7 @@
#include <asm/uaccess.h>
#include <asm/processor.h>
#include <asm/msr.h>
+#include <asm/kvm_para.h>
#include "mtrr.h"
u32 num_var_ranges = 0;
@@ -649,6 +650,7 @@ static __init int amd_special_default_mtrr(void)
/**
* mtrr_trim_uncached_memory - trim RAM not covered by MTRRs
+ * @end_pfn: ending page frame number
*
* Some buggy BIOSes don't setup the MTRRs properly for systems with certain
* memory configurations. This routine checks that the highest MTRR matches
@@ -688,8 +690,11 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
/* kvm/qemu doesn't have mtrr set right, don't trim them all */
if (!highest_pfn) {
- printk(KERN_WARNING "WARNING: strange, CPU MTRRs all blank?\n");
- WARN_ON(1);
+ if (!kvm_para_available()) {
+ printk(KERN_WARNING
+ "WARNING: strange, CPU MTRRs all blank?\n");
+ WARN_ON(1);
+ }
return 0;
}
diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c
index 200fb3f9ebf..e8b422c1c51 100644
--- a/arch/x86/kernel/cpu/transmeta.c
+++ b/arch/x86/kernel/cpu/transmeta.c
@@ -76,13 +76,6 @@ static void __cpuinit init_transmeta(struct cpuinfo_x86 *c)
/* All Transmeta CPUs have a constant TSC */
set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
- /* If we can run i686 user-space code, call us an i686 */
-#define USER686 ((1 << X86_FEATURE_TSC)|\
- (1 << X86_FEATURE_CX8)|\
- (1 << X86_FEATURE_CMOV))
- if (c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686)
- c->x86 = 6;
-
#ifdef CONFIG_SYSCTL
/* randomize_va_space slows us down enormously;
it probably triggers retranslation of x86->native bytecode */
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c
index 0c0eeb163d9..759e02bec07 100644
--- a/arch/x86/kernel/efi.c
+++ b/arch/x86/kernel/efi.c
@@ -54,7 +54,7 @@ EXPORT_SYMBOL(efi);
struct efi_memory_map memmap;
-struct efi efi_phys __initdata;
+static struct efi efi_phys __initdata;
static efi_system_table_t efi_systab __initdata;
static int __init setup_noefi(char *arg)
diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c
index cb91f985b4a..5d23d85624d 100644
--- a/arch/x86/kernel/efi_32.c
+++ b/arch/x86/kernel/efi_32.c
@@ -28,6 +28,7 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
+#include <asm/efi.h>
/*
* To make EFI call EFI runtime service in physical addressing mode we need
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 824e21b80aa..4b87c32b639 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -409,7 +409,7 @@ restore_nocheck_notrace:
RESTORE_REGS
addl $4, %esp # skip orig_eax/error_code
CFI_ADJUST_CFA_OFFSET -4
-ENTRY(irq_return)
+irq_return:
INTERRUPT_RETURN
.section .fixup,"ax"
iret_exc:
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 6be39a387c5..c20c9e7e08d 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -453,6 +453,7 @@ ENTRY(stub_execve)
CFI_REGISTER rip, r11
SAVE_REST
FIXUP_TOP_OF_STACK %r11
+ movq %rsp, %rcx
call sys_execve
RESTORE_TOP_OF_STACK %r11
movq %rax,RAX(%rsp)
@@ -583,7 +584,7 @@ retint_restore_args: /* return to kernel space */
restore_args:
RESTORE_ARGS 0,8,0
-ENTRY(irq_return)
+irq_return:
INTERRUPT_RETURN
.section __ex_table, "a"
@@ -1036,15 +1037,16 @@ ENDPROC(child_rip)
* rdi: name, rsi: argv, rdx: envp
*
* We want to fallback into:
- * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
+ * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs)
*
* do_sys_execve asm fallback arguments:
- * rdi: name, rsi: argv, rdx: envp, fake frame on the stack
+ * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
*/
ENTRY(kernel_execve)
CFI_STARTPROC
FAKE_STACK_FRAME $0
SAVE_ALL
+ movq %rsp,%rcx
call sys_execve
movq %rax, RAX(%rsp)
RESTORE_REST
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 24dbf56928d..ad2440832de 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -88,6 +88,9 @@ void __init x86_64_start_kernel(char * real_mode_data)
/* Make NULL pointers segfault */
zap_identity_mappings();
+ /* Cleanup the over mapped high alias */
+ cleanup_highmap();
+
for (i = 0; i < IDT_ENTRIES; i++) {
#ifdef CONFIG_EARLY_PRINTK
set_intr_gate(i, &early_idt_handlers[i]);
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 74ef4a41f22..fd8ca53943a 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -606,13 +606,13 @@ ENTRY(_stext)
.section ".bss.page_aligned","wa"
.align PAGE_SIZE_asm
#ifdef CONFIG_X86_PAE
-ENTRY(swapper_pg_pmd)
+swapper_pg_pmd:
.fill 1024*KPMDS,4,0
#else
ENTRY(swapper_pg_dir)
.fill 1024,4,0
#endif
-ENTRY(swapper_pg_fixmap)
+swapper_pg_fixmap:
.fill 1024,4,0
ENTRY(empty_zero_page)
.fill 4096,1,0
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 09b38d539b0..a007454133a 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -107,8 +107,13 @@ startup_64:
movq %rdx, 0(%rbx, %rax, 8)
ident_complete:
- /* Fixup the kernel text+data virtual addresses
+ /*
+ * Fixup the kernel text+data virtual addresses. Note that
+ * we might write invalid pmds, when the kernel is relocated
+ * cleanup_highmap() fixes this up along with the mappings
+ * beyond _end.
*/
+
leaq level2_kernel_pgt(%rip), %rdi
leaq 4096(%rdi), %r8
/* See if it is a valid page table entry */
@@ -250,7 +255,7 @@ ENTRY(secondary_startup_64)
lretq
/* SMP bootup changes these two */
- __CPUINITDATA
+ __REFDATA
.align 8
ENTRY(initial_code)
.quad x86_64_start_kernel
@@ -374,18 +379,24 @@ NEXT_PAGE(level2_ident_pgt)
/* Since I easily can, map the first 1G.
* Don't set NX because code runs from these pages.
*/
- PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD)
+ PMDS(0, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD)
NEXT_PAGE(level2_kernel_pgt)
- /* 40MB kernel mapping. The kernel code cannot be bigger than that.
- When you change this change KERNEL_TEXT_SIZE in page.h too. */
- /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */
- PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_TEXT_SIZE/PMD_SIZE)
- /* Module mapping starts here */
- .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0
+ /*
+ * 128 MB kernel mapping. We spend a full page on this pagetable
+ * anyway.
+ *
+ * The kernel code+data+bss must not be bigger than that.
+ *
+ * (NOTE: at +128MB starts the module area, see MODULES_VADDR.
+ * If you want to increase this then increase MODULES_VADDR
+ * too.)
+ */
+ PMDS(0, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL,
+ KERNEL_IMAGE_SIZE/PMD_SIZE)
NEXT_PAGE(level2_spare_pgt)
- .fill 512,8,0
+ .fill 512, 8, 0
#undef PMDS
#undef NEXT_PAGE
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 429d084e014..235fd6c7750 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -368,8 +368,8 @@ static int hpet_clocksource_register(void)
return 0;
}
-/*
- * Try to setup the HPET timer
+/**
+ * hpet_enable - Try to setup the HPET timer. Returns 1 on success.
*/
int __init hpet_enable(void)
{
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index 26719bd2c77..d2e39e69aaf 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -39,7 +39,7 @@
#define HAVE_HWFP 1
#endif
-unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
+static unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
void mxcsr_feature_mask_init(void)
{
@@ -132,7 +132,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
if (!cpu_has_fxsr)
return -ENODEV;
- unlazy_fpu(target);
+ init_fpu(target);
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
&target->thread.i387.fxsave, 0, -1);
@@ -147,7 +147,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
if (!cpu_has_fxsr)
return -ENODEV;
- unlazy_fpu(target);
+ init_fpu(target);
set_stopped_child_used_math(target);
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
@@ -261,7 +261,7 @@ static void convert_from_fxsr(struct user_i387_ia32_struct *env,
}
#else
env->fip = fxsave->fip;
- env->fcs = fxsave->fcs;
+ env->fcs = (u16) fxsave->fcs | ((u32) fxsave->fop << 16);
env->foo = fxsave->foo;
env->fos = fxsave->fos;
#endif
@@ -307,7 +307,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset,
if (!HAVE_HWFP)
return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf);
- unlazy_fpu(target);
+ init_fpu(target);
if (!cpu_has_fxsr)
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
@@ -332,7 +332,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
if (!HAVE_HWFP)
return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf);
- unlazy_fpu(target);
+ init_fpu(target);
set_stopped_child_used_math(target);
if (!cpu_has_fxsr)
diff --git a/arch/x86/kernel/i8259_32.c b/arch/x86/kernel/i8259_32.c
index 2d25b77102f..fe631967d62 100644
--- a/arch/x86/kernel/i8259_32.c
+++ b/arch/x86/kernel/i8259_32.c
@@ -26,8 +26,6 @@
* present in the majority of PC/AT boxes.
* plus some generic x86 specific things if generic specifics makes
* any sense at all.
- * this file should become arch/i386/kernel/irq.c when the old irq.c
- * moves to arch independent land
*/
static int i8259A_auto_eoi;
@@ -362,23 +360,12 @@ void __init init_ISA_irqs (void)
#endif
init_8259A(0);
- for (i = 0; i < NR_IRQS; i++) {
- irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = NULL;
- irq_desc[i].depth = 1;
-
- if (i < 16) {
- /*
- * 16 old-style INTA-cycle interrupts:
- */
- set_irq_chip_and_handler_name(i, &i8259A_chip,
- handle_level_irq, "XT");
- } else {
- /*
- * 'high' PCI IRQs filled in on demand
- */
- irq_desc[i].chip = &no_irq_chip;
- }
+ /*
+ * 16 old-style INTA-cycle interrupts:
+ */
+ for (i = 0; i < 16; i++) {
+ set_irq_chip_and_handler_name(i, &i8259A_chip,
+ handle_level_irq, "XT");
}
}
diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c
index 5b3ce793436..3d01e47777d 100644
--- a/arch/x86/kernel/init_task.c
+++ b/arch/x86/kernel/init_task.c
@@ -15,6 +15,7 @@ static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_UNUSED_SYMBOL(init_mm); /* will be removed in 2.6.26 */
/*
* Initial thread structure.
diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
index bd49321034d..c706a306155 100644
--- a/arch/x86/kernel/io_delay.c
+++ b/arch/x86/kernel/io_delay.c
@@ -13,7 +13,6 @@
#include <asm/io.h>
int io_delay_type __read_mostly = CONFIG_DEFAULT_IO_DELAY_TYPE;
-EXPORT_SYMBOL_GPL(io_delay_type);
static int __initdata io_delay_override;
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index a99e764fd66..34a591283f5 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -581,7 +581,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
* When a retprobed function returns, this code saves registers and
* calls trampoline_handler() runs, which calls the kretprobe's handler.
*/
-void __kprobes kretprobe_trampoline_holder(void)
+static void __used __kprobes kretprobe_trampoline_holder(void)
{
asm volatile (
".global kretprobe_trampoline\n"
@@ -673,7 +673,7 @@ void __kprobes kretprobe_trampoline_holder(void)
/*
* Called from kretprobe_trampoline
*/
-void * __kprobes trampoline_handler(struct pt_regs *regs)
+static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
{
struct kretprobe_instance *ri = NULL;
struct hlist_head *head, empty_rp;
diff --git a/arch/x86/kernel/nmi_32.c b/arch/x86/kernel/nmi_32.c
index edd413650b3..6a0aa703868 100644
--- a/arch/x86/kernel/nmi_32.c
+++ b/arch/x86/kernel/nmi_32.c
@@ -46,9 +46,6 @@ static unsigned int nmi_hz = HZ;
static DEFINE_PER_CPU(short, wd_enabled);
-/* local prototypes */
-static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
-
static int endflag __initdata = 0;
#ifdef CONFIG_SMP
@@ -391,15 +388,6 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
return rc;
}
-int do_nmi_callback(struct pt_regs * regs, int cpu)
-{
-#ifdef CONFIG_SYSCTL
- if (unknown_nmi_panic)
- return unknown_nmi_panic_callback(regs, cpu);
-#endif
- return 0;
-}
-
#ifdef CONFIG_SYSCTL
static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
@@ -453,6 +441,15 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
#endif
+int do_nmi_callback(struct pt_regs *regs, int cpu)
+{
+#ifdef CONFIG_SYSCTL
+ if (unknown_nmi_panic)
+ return unknown_nmi_panic_callback(regs, cpu);
+#endif
+ return 0;
+}
+
void __trigger_all_cpu_backtrace(void)
{
int i;
diff --git a/arch/x86/kernel/nmi_64.c b/arch/x86/kernel/nmi_64.c
index fb99484d21c..9a4fde74bee 100644
--- a/arch/x86/kernel/nmi_64.c
+++ b/arch/x86/kernel/nmi_64.c
@@ -46,9 +46,6 @@ static unsigned int nmi_hz = HZ;
static DEFINE_PER_CPU(short, wd_enabled);
-/* local prototypes */
-static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
-
/* Run after command line and cpu_init init, but before all other checks */
void nmi_watchdog_default(void)
{
@@ -394,15 +391,6 @@ asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
nmi_exit();
}
-int do_nmi_callback(struct pt_regs * regs, int cpu)
-{
-#ifdef CONFIG_SYSCTL
- if (unknown_nmi_panic)
- return unknown_nmi_panic_callback(regs, cpu);
-#endif
- return 0;
-}
-
void stop_nmi(void)
{
acpi_nmi_disable();
@@ -464,6 +452,15 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
#endif
+int do_nmi_callback(struct pt_regs *regs, int cpu)
+{
+#ifdef CONFIG_SYSCTL
+ if (unknown_nmi_panic)
+ return unknown_nmi_panic_callback(regs, cpu);
+#endif
+ return 0;
+}
+
void __trigger_all_cpu_backtrace(void)
{
int i;
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index a7d50a547dc..be3c7a299f0 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -603,11 +603,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
}
#endif
+#ifdef X86_BTS
if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
+#endif
if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index b0cc8f0136d..3baf9b9f4c8 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -604,11 +604,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
}
+#ifdef X86_BTS
if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
+#endif
}
/*
@@ -730,16 +732,16 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
*/
asmlinkage
long sys_execve(char __user *name, char __user * __user *argv,
- char __user * __user *envp, struct pt_regs regs)
+ char __user * __user *envp, struct pt_regs *regs)
{
long error;
char * filename;
filename = getname(name);
error = PTR_ERR(filename);
- if (IS_ERR(filename))
+ if (IS_ERR(filename))
return error;
- error = do_execve(filename, argv, envp, &regs);
+ error = do_execve(filename, argv, envp, regs);
putname(filename);
return error;
}
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 702c33efea8..8f64abe699f 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -323,6 +323,16 @@ static int putreg(struct task_struct *child,
return set_flags(child, value);
#ifdef CONFIG_X86_64
+ /*
+ * Orig_ax is really just a flag with small positive and
+ * negative values, so make sure to always sign-extend it
+ * from 32 bits so that it works correctly regardless of
+ * whether we come from a 32-bit environment or not.
+ */
+ case offsetof(struct user_regs_struct, orig_ax):
+ value = (long) (s32) value;
+ break;
+
case offsetof(struct user_regs_struct,fs_base):
if (value >= TASK_SIZE_OF(child))
return -EIO;
@@ -544,6 +554,8 @@ static int ptrace_set_debugreg(struct task_struct *child,
return 0;
}
+#ifdef X86_BTS
+
static int ptrace_bts_get_size(struct task_struct *child)
{
if (!child->thread.ds_area_msr)
@@ -826,6 +838,7 @@ void ptrace_bts_take_timestamp(struct task_struct *tsk,
ptrace_bts_write_record(tsk, &rec);
}
+#endif /* X86_BTS */
/*
* Called by kernel/ptrace.c when detaching..
@@ -839,7 +852,9 @@ void ptrace_disable(struct task_struct *child)
clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
#endif
if (child->thread.ds_area_msr) {
+#ifdef X86_BTS
ptrace_bts_realloc(child, 0, 0);
+#endif
child->thread.debugctlmsr &= ~ds_debugctl_mask();
if (!child->thread.debugctlmsr)
clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
@@ -961,6 +976,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
#endif
+ /*
+ * These bits need more cooking - not enabled yet:
+ */
+#ifdef X86_BTS
case PTRACE_BTS_CONFIG:
ret = ptrace_bts_config
(child, data, (struct ptrace_bts_config __user *)addr);
@@ -988,6 +1007,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = ptrace_bts_drain
(child, data, (struct bts_struct __user *) addr);
break;
+#endif
default:
ret = ptrace_request(child, request, addr, data);
@@ -1160,7 +1180,7 @@ static int genregs32_set(struct task_struct *target,
if (kbuf) {
const compat_ulong_t *k = kbuf;
while (count > 0 && !ret) {
- ret = putreg(target, pos, *k++);
+ ret = putreg32(target, pos, *k++);
count -= sizeof(*k);
pos += sizeof(*k);
}
@@ -1171,7 +1191,7 @@ static int genregs32_set(struct task_struct *target,
ret = __get_user(word, u++);
if (ret)
break;
- ret = putreg(target, pos, word);
+ ret = putreg32(target, pos, word);
count -= sizeof(*u);
pos += sizeof(*u);
}
@@ -1226,12 +1246,14 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
case PTRACE_SETOPTIONS:
case PTRACE_SET_THREAD_AREA:
case PTRACE_GET_THREAD_AREA:
+#ifdef X86_BTS
case PTRACE_BTS_CONFIG:
case PTRACE_BTS_STATUS:
case PTRACE_BTS_SIZE:
case PTRACE_BTS_GET:
case PTRACE_BTS_CLEAR:
case PTRACE_BTS_DRAIN:
+#endif
return sys_ptrace(request, pid, addr, data);
default:
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 7fd6ac43e4a..55ceb8cdef7 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -326,6 +326,10 @@ static inline void kb_wait(void)
}
}
+void __attribute__((weak)) mach_reboot_fixups(void)
+{
+}
+
static void native_machine_emergency_restart(void)
{
int i;
@@ -337,6 +341,8 @@ static void native_machine_emergency_restart(void)
/* Could also try the reset bit in the Hammer NB */
switch (reboot_type) {
case BOOT_KBD:
+ mach_reboot_fixups(); /* for board specific fixups */
+
for (i = 0; i < 10; i++) {
kb_wait();
udelay(50);
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index 691ab4cb167..a1d7071a51c 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -164,7 +164,6 @@ unsigned long mmu_cr4_features = X86_CR4_PAE;
unsigned int machine_id;
unsigned int machine_submodel_id;
unsigned int BIOS_revision;
-unsigned int mca_pentium_flag;
/* Boot loader ID as an integer, for the benefit of proc_dointvec */
int bootloader_type;
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index c0d8208af12..7637dc91c79 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -518,7 +518,7 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
}
#ifdef CONFIG_NUMA
-static int nearby_node(int apicid)
+static int __cpuinit nearby_node(int apicid)
{
int i, node;
@@ -791,7 +791,7 @@ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
return 1;
}
-static void srat_detect_node(void)
+static void __cpuinit srat_detect_node(void)
{
#ifdef CONFIG_NUMA
unsigned node;
@@ -1021,7 +1021,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
/* Clear all flags overriden by options */
for (i = 0; i < NCAPINTS; i++)
- c->x86_capability[i] ^= cleared_cpu_caps[i];
+ c->x86_capability[i] &= ~cleared_cpu_caps[i];
#ifdef CONFIG_X86_MCE
mcheck_init(c);
@@ -1046,7 +1046,7 @@ __setup("noclflush", setup_noclflush);
void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
{
if (c->x86_model_id[0])
- printk(KERN_INFO "%s", c->x86_model_id);
+ printk(KERN_CONT "%s", c->x86_model_id);
if (c->x86_mask || c->cpuid_level >= 0)
printk(KERN_CONT " stepping %02x\n", c->x86_mask);
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index caee1f002fe..0157a6f0f41 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -407,7 +407,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
* The tracer may want to single-step inside the
* handler too.
*/
- regs->flags &= ~TF_MASK;
+ regs->flags &= ~(TF_MASK | X86_EFLAGS_DF);
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
@@ -500,7 +500,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* The tracer may want to single-step inside the
* handler too.
*/
- regs->flags &= ~TF_MASK;
+ regs->flags &= ~(TF_MASK | X86_EFLAGS_DF);
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 7347bb14e30..56b72fb67f9 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -295,7 +295,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
see include/asm-x86_64/uaccess.h for details. */
set_fs(USER_DS);
- regs->flags &= ~X86_EFLAGS_TF;
+ regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF);
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
#ifdef DEBUG_SIG
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
index d53bd6fcb42..0880f2c388a 100644
--- a/arch/x86/kernel/smpboot_64.c
+++ b/arch/x86/kernel/smpboot_64.c
@@ -554,10 +554,10 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
int timeout;
unsigned long start_rip;
struct create_idle c_idle = {
- .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle),
.cpu = cpu,
.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
};
+ INIT_WORK(&c_idle.work, do_fork_idle);
/* allocate memory for gdts of secondary cpus. Hotplug is considered */
if (!cpu_gdt_descr[cpu].address &&
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index 02f0f61f5b1..c28c342c162 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -25,6 +25,8 @@ static int save_stack_stack(void *data, char *name)
static void save_stack_address(void *data, unsigned long addr, int reliable)
{
struct stack_trace *trace = data;
+ if (!reliable)
+ return;
if (trace->skip > 0) {
trace->skip--;
return;
@@ -37,6 +39,8 @@ static void
save_stack_address_nosched(void *data, unsigned long addr, int reliable)
{
struct stack_trace *trace = (struct stack_trace *)data;
+ if (!reliable)
+ return;
if (in_sched_functions(addr))
return;
if (trace->skip > 0) {
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
index 2ef1a5f8d67..9d406cdc847 100644
--- a/arch/x86/kernel/step.c
+++ b/arch/x86/kernel/step.c
@@ -166,7 +166,7 @@ static void enable_step(struct task_struct *child, bool block)
child->thread.debugctlmsr | DEBUGCTLMSR_BTF);
} else {
write_debugctlmsr(child,
- child->thread.debugctlmsr & ~TIF_DEBUGCTLMSR);
+ child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
if (!child->thread.debugctlmsr)
clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
@@ -189,7 +189,7 @@ void user_disable_single_step(struct task_struct *child)
* Make sure block stepping (BTF) is disabled.
*/
write_debugctlmsr(child,
- child->thread.debugctlmsr & ~TIF_DEBUGCTLMSR);
+ child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
if (!child->thread.debugctlmsr)
clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
index 6dfd4e76661..022bcaa3b42 100644
--- a/arch/x86/kernel/tls.c
+++ b/arch/x86/kernel/tls.c
@@ -91,7 +91,9 @@ int do_set_thread_area(struct task_struct *p, int idx,
asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
{
- return do_set_thread_area(current, -1, u_info, 1);
+ int ret = do_set_thread_area(current, -1, u_info, 1);
+ prevent_tail_call(ret);
+ return ret;
}
@@ -139,7 +141,9 @@ int do_get_thread_area(struct task_struct *p, int idx,
asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
{
- return do_get_thread_area(current, -1, u_info);
+ int ret = do_get_thread_area(current, -1, u_info);
+ prevent_tail_call(ret);
+ return ret;
}
int regset_tls_active(struct task_struct *target,
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index a40051b71d9..0fcc95a354f 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -34,7 +34,7 @@
static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
#ifdef CONFIG_HOTPLUG_CPU
-int arch_register_cpu(int num)
+int __ref arch_register_cpu(int num)
{
/*
* CPU0 cannot be offlined due to several
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
index 43517e324be..f14cfd9d1f9 100644
--- a/arch/x86/kernel/tsc_32.c
+++ b/arch/x86/kernel/tsc_32.c
@@ -28,7 +28,8 @@ EXPORT_SYMBOL_GPL(tsc_khz);
static int __init tsc_setup(char *str)
{
printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, "
- "cannot disable TSC.\n");
+ "cannot disable TSC completely.\n");
+ mark_tsc_unstable("user disabled TSC");
return 1;
}
#else
diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
index f1148ac8abe..2ffa9656fe7 100644
--- a/arch/x86/kernel/vmlinux_32.lds.S
+++ b/arch/x86/kernel/vmlinux_32.lds.S
@@ -38,7 +38,7 @@ SECTIONS
/* read-only */
.text : AT(ADDR(.text) - LOAD_OFFSET) {
- . = ALIGN(4096); /* not really needed, already page aligned */
+ . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
*(.text.page_aligned)
TEXT_TEXT
SCHED_TEXT
@@ -70,21 +70,21 @@ SECTIONS
RODATA
/* writeable */
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
DATA_DATA
CONSTRUCTORS
} :data
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
__nosave_begin = .;
*(.data.nosave)
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
__nosave_end = .;
}
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
*(.data.page_aligned)
*(.data.idt)
@@ -108,7 +108,7 @@ SECTIONS
}
/* might get freed after init */
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
__smp_locks = .;
*(.smp_locks)
@@ -120,10 +120,10 @@ SECTIONS
* after boot. Always make sure that ALIGN() directive is present after
* the section which contains __smp_alt_end.
*/
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
/* will be freed after init */
- . = ALIGN(4096); /* Init code and data */
+ . = ALIGN(PAGE_SIZE); /* Init code and data */
.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
__init_begin = .;
_sinittext = .;
@@ -174,23 +174,23 @@ SECTIONS
EXIT_DATA
}
#if defined(CONFIG_BLK_DEV_INITRD)
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
__initramfs_start = .;
*(.init.ramfs)
__initramfs_end = .;
}
#endif
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
__per_cpu_start = .;
*(.data.percpu)
*(.data.percpu.shared_aligned)
__per_cpu_end = .;
}
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
/* freed after init ends here */
-
+
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
__init_end = .;
__bss_start = .; /* BSS */
@@ -200,7 +200,7 @@ SECTIONS
__bss_stop = .;
_end = . ;
/* This is where the kernel creates the early boot page tables */
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
pg0 = . ;
}
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index 0992b9946c6..fab13229973 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -37,7 +37,7 @@ SECTIONS
KPROBES_TEXT
*(.fixup)
*(.gnu.warning)
- _etext = .; /* End of text section */
+ _etext = .; /* End of text section */
} :text = 0x9090
. = ALIGN(16); /* Exception table */
@@ -60,7 +60,7 @@ SECTIONS
__tracedata_end = .;
}
- . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
+ . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
/* Data */
.data : AT(ADDR(.data) - LOAD_OFFSET) {
DATA_DATA
@@ -119,7 +119,7 @@ SECTIONS
.vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3))
{ *(.vsyscall_3) }
- . = VSYSCALL_VIRT_ADDR + 4096;
+ . = VSYSCALL_VIRT_ADDR + PAGE_SIZE;
#undef VSYSCALL_ADDR
#undef VSYSCALL_PHYS_ADDR
@@ -129,28 +129,28 @@ SECTIONS
#undef VVIRT_OFFSET
#undef VVIRT
- . = ALIGN(8192); /* init_task */
+ . = ALIGN(THREAD_SIZE); /* init_task */
.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
*(.data.init_task)
}:data.init
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
*(.data.page_aligned)
}
/* might get freed after init */
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
__smp_alt_begin = .;
__smp_locks = .;
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
*(.smp_locks)
}
__smp_locks_end = .;
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
__smp_alt_end = .;
- . = ALIGN(4096); /* Init code and data */
+ . = ALIGN(PAGE_SIZE); /* Init code and data */
__init_begin = .;
.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
_sinittext = .;
@@ -191,7 +191,7 @@ SECTIONS
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
*(.altinstructions)
}
- __alt_instructions_end = .;
+ __alt_instructions_end = .;
.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
*(.altinstr_replacement)
}
@@ -207,25 +207,25 @@ SECTIONS
/* vdso blob that is mapped into user space */
vdso_start = . ;
.vdso : AT(ADDR(.vdso) - LOAD_OFFSET) { *(.vdso) }
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
vdso_end = .;
#ifdef CONFIG_BLK_DEV_INITRD
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
__initramfs_start = .;
.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
__initramfs_end = .;
#endif
- PERCPU(4096)
+ PERCPU(PAGE_SIZE)
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
__init_end = .;
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
__nosave_begin = .;
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
__nosave_end = .;
__bss_start = .; /* BSS */
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 3f824277458..edff4c98548 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -44,11 +44,6 @@
#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
#define __syscall_clobber "r11","cx","memory"
-#define __pa_vsymbol(x) \
- ({unsigned long v; \
- extern char __vsyscall_0; \
- asm("" : "=r" (v) : "0" (x)); \
- ((v - VSYSCALL_START) + __pa_symbol(&__vsyscall_0)); })
/*
* vsyscall_gtod_data contains data that is :
@@ -102,7 +97,7 @@ static __always_inline void do_get_tz(struct timezone * tz)
static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
{
int ret;
- asm volatile("vsysc2: syscall"
+ asm volatile("syscall"
: "=a" (ret)
: "0" (__NR_gettimeofday),"D" (tv),"S" (tz)
: __syscall_clobber );
@@ -112,7 +107,7 @@ static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
static __always_inline long time_syscall(long *t)
{
long secs;
- asm volatile("vsysc1: syscall"
+ asm volatile("syscall"
: "=a" (secs)
: "0" (__NR_time),"D" (t) : __syscall_clobber);
return secs;
@@ -228,42 +223,11 @@ long __vsyscall(3) venosys_1(void)
#ifdef CONFIG_SYSCTL
-#define SYSCALL 0x050f
-#define NOP2 0x9090
-
-/*
- * NOP out syscall in vsyscall page when not needed.
- */
-static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+static int
+vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
- extern u16 vsysc1, vsysc2;
- u16 __iomem *map1;
- u16 __iomem *map2;
- int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
- if (!write)
- return ret;
- /* gcc has some trouble with __va(__pa()), so just do it this
- way. */
- map1 = ioremap(__pa_vsymbol(&vsysc1), 2);
- if (!map1)
- return -ENOMEM;
- map2 = ioremap(__pa_vsymbol(&vsysc2), 2);
- if (!map2) {
- ret = -ENOMEM;
- goto out;
- }
- if (!vsyscall_gtod_data.sysctl_enabled) {
- writew(SYSCALL, map1);
- writew(SYSCALL, map2);
- } else {
- writew(NOP2, map1);
- writew(NOP2, map2);
- }
- iounmap(map2);
-out:
- iounmap(map1);
- return ret;
+ return proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
}
static ctl_table kernel_table2[] = {
@@ -279,7 +243,6 @@ static ctl_table kernel_root_table2[] = {
.child = kernel_table2 },
{}
};
-
#endif
/* Assume __initcall executes before all user space. Hopefully kmod
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 2cbee9479ce..68a6b151193 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -647,6 +647,10 @@ static void start_apic_timer(struct kvm_lapic *apic)
apic->timer.period = apic_get_reg(apic, APIC_TMICT) *
APIC_BUS_CYCLE_NS * apic->timer.divide_count;
atomic_set(&apic->timer.pending, 0);
+
+ if (!apic->timer.period)
+ return;
+
hrtimer_start(&apic->timer.dev,
ktime_add_ns(now, apic->timer.period),
HRTIMER_MODE_ABS);
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 8efdcdbebb0..d8172aabc66 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -681,8 +681,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
unsigned level,
int metaphysical,
unsigned access,
- u64 *parent_pte,
- bool *new_page)
+ u64 *parent_pte)
{
union kvm_mmu_page_role role;
unsigned index;
@@ -722,8 +721,6 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
vcpu->arch.mmu.prefetch_page(vcpu, sp);
if (!metaphysical)
rmap_write_protect(vcpu->kvm, gfn);
- if (new_page)
- *new_page = 1;
return sp;
}
@@ -876,11 +873,18 @@ static void page_header_update_slot(struct kvm *kvm, void *pte, gfn_t gfn)
struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva)
{
+ struct page *page;
+
gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
if (gpa == UNMAPPED_GVA)
return NULL;
- return gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+
+ down_read(&current->mm->mmap_sem);
+ page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+ up_read(&current->mm->mmap_sem);
+
+ return page;
}
static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
@@ -999,8 +1003,7 @@ static int __nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write,
>> PAGE_SHIFT;
new_table = kvm_mmu_get_page(vcpu, pseudo_gfn,
v, level - 1,
- 1, ACC_ALL, &table[index],
- NULL);
+ 1, ACC_ALL, &table[index]);
if (!new_table) {
pgprintk("nonpaging_map: ENOMEM\n");
kvm_release_page_clean(page);
@@ -1020,15 +1023,18 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
struct page *page;
+ down_read(&vcpu->kvm->slots_lock);
+
down_read(&current->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, gfn);
+ up_read(&current->mm->mmap_sem);
spin_lock(&vcpu->kvm->mmu_lock);
kvm_mmu_free_some_pages(vcpu);
r = __nonpaging_map(vcpu, v, write, gfn, page);
spin_unlock(&vcpu->kvm->mmu_lock);
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return r;
}
@@ -1090,7 +1096,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
ASSERT(!VALID_PAGE(root));
sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
- PT64_ROOT_LEVEL, 0, ACC_ALL, NULL, NULL);
+ PT64_ROOT_LEVEL, 0, ACC_ALL, NULL);
root = __pa(sp->spt);
++sp->root_count;
vcpu->arch.mmu.root_hpa = root;
@@ -1111,7 +1117,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
root_gfn = 0;
sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
PT32_ROOT_LEVEL, !is_paging(vcpu),
- ACC_ALL, NULL, NULL);
+ ACC_ALL, NULL);
root = __pa(sp->spt);
++sp->root_count;
vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK;
@@ -1172,7 +1178,7 @@ void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu)
static void paging_new_cr3(struct kvm_vcpu *vcpu)
{
- pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->cr3);
+ pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->arch.cr3);
mmu_free_roots(vcpu);
}
@@ -1362,6 +1368,7 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
gfn_t gfn;
int r;
u64 gpte = 0;
+ struct page *page;
if (bytes != 4 && bytes != 8)
return;
@@ -1389,6 +1396,11 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
if (!is_present_pte(gpte))
return;
gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
+
+ down_read(&current->mm->mmap_sem);
+ page = gfn_to_page(vcpu->kvm, gfn);
+ up_read(&current->mm->mmap_sem);
+
vcpu->arch.update_pte.gfn = gfn;
vcpu->arch.update_pte.page = gfn_to_page(vcpu->kvm, gfn);
}
@@ -1496,9 +1508,9 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva)
gpa_t gpa;
int r;
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
spin_lock(&vcpu->kvm->mmu_lock);
r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT);
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 03ba8608fe0..ecc0856268c 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -91,7 +91,10 @@ static bool FNAME(cmpxchg_gpte)(struct kvm *kvm,
pt_element_t *table;
struct page *page;
+ down_read(&current->mm->mmap_sem);
page = gfn_to_page(kvm, table_gfn);
+ up_read(&current->mm->mmap_sem);
+
table = kmap_atomic(page, KM_USER0);
ret = CMPXCHG(&table[index], orig_pte, new_pte);
@@ -140,7 +143,7 @@ walk:
}
#endif
ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) ||
- (vcpu->cr3 & CR3_NONPAE_RESERVED_BITS) == 0);
+ (vcpu->arch.cr3 & CR3_NONPAE_RESERVED_BITS) == 0);
pt_access = ACC_ALL;
@@ -297,7 +300,6 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
u64 shadow_pte;
int metaphysical;
gfn_t table_gfn;
- bool new_page = 0;
shadow_ent = ((u64 *)__va(shadow_addr)) + index;
if (level == PT_PAGE_TABLE_LEVEL)
@@ -319,8 +321,8 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
}
shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1,
metaphysical, access,
- shadow_ent, &new_page);
- if (new_page && !metaphysical) {
+ shadow_ent);
+ if (!metaphysical) {
int r;
pt_element_t curr_pte;
r = kvm_read_guest_atomic(vcpu->kvm,
@@ -378,7 +380,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
if (r)
return r;
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
/*
* Look up the shadow pte for the faulting address.
*/
@@ -392,11 +394,13 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
pgprintk("%s: guest page fault\n", __FUNCTION__);
inject_page_fault(vcpu, addr, walker.error_code);
vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return 0;
}
+ down_read(&current->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, walker.gfn);
+ up_read(&current->mm->mmap_sem);
spin_lock(&vcpu->kvm->mmu_lock);
kvm_mmu_free_some_pages(vcpu);
@@ -413,14 +417,14 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
*/
if (shadow_pte && is_io_pte(*shadow_pte)) {
spin_unlock(&vcpu->kvm->mmu_lock);
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return 1;
}
++vcpu->stat.pf_fixed;
kvm_mmu_audit(vcpu, "post page fault (fixed)");
spin_unlock(&vcpu->kvm->mmu_lock);
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return write_pt;
}
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index de755cb1431..1a582f1090e 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -792,6 +792,10 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
vcpu->arch.cr0 = cr0;
cr0 |= X86_CR0_PG | X86_CR0_WP;
cr0 &= ~(X86_CR0_CD | X86_CR0_NW);
+ if (!vcpu->fpu_active) {
+ svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
+ cr0 |= X86_CR0_TS;
+ }
svm->vmcb->save.cr0 = cr0;
}
@@ -1096,6 +1100,24 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
case MSR_IA32_SYSENTER_ESP:
*data = svm->vmcb->save.sysenter_esp;
break;
+ /* Nobody will change the following 5 values in the VMCB so
+ we can safely return them on rdmsr. They will always be 0
+ until LBRV is implemented. */
+ case MSR_IA32_DEBUGCTLMSR:
+ *data = svm->vmcb->save.dbgctl;
+ break;
+ case MSR_IA32_LASTBRANCHFROMIP:
+ *data = svm->vmcb->save.br_from;
+ break;
+ case MSR_IA32_LASTBRANCHTOIP:
+ *data = svm->vmcb->save.br_to;
+ break;
+ case MSR_IA32_LASTINTFROMIP:
+ *data = svm->vmcb->save.last_excp_from;
+ break;
+ case MSR_IA32_LASTINTTOIP:
+ *data = svm->vmcb->save.last_excp_to;
+ break;
default:
return kvm_get_msr_common(vcpu, ecx, data);
}
@@ -1156,6 +1178,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
case MSR_IA32_SYSENTER_ESP:
svm->vmcb->save.sysenter_esp = data;
break;
+ case MSR_IA32_DEBUGCTLMSR:
+ pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTLMSR 0x%llx, nop\n",
+ __FUNCTION__, data);
+ break;
case MSR_K7_EVNTSEL0:
case MSR_K7_EVNTSEL1:
case MSR_K7_EVNTSEL2:
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ad36447e696..94ea724638f 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -638,6 +638,7 @@ static void setup_msrs(struct vcpu_vmx *vmx)
{
int save_nmsrs;
+ vmx_load_host_state(vmx);
save_nmsrs = 0;
#ifdef CONFIG_X86_64
if (is_long_mode(&vmx->vcpu)) {
@@ -1477,7 +1478,7 @@ static int alloc_apic_access_page(struct kvm *kvm)
struct kvm_userspace_memory_region kvm_userspace_mem;
int r = 0;
- down_write(&current->mm->mmap_sem);
+ down_write(&kvm->slots_lock);
if (kvm->arch.apic_access_page)
goto out;
kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
@@ -1487,9 +1488,12 @@ static int alloc_apic_access_page(struct kvm *kvm)
r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
if (r)
goto out;
+
+ down_read(&current->mm->mmap_sem);
kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00);
+ up_read(&current->mm->mmap_sem);
out:
- up_write(&current->mm->mmap_sem);
+ up_write(&kvm->slots_lock);
return r;
}
@@ -1602,9 +1606,6 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
- if (vm_need_virtualize_apic_accesses(vmx->vcpu.kvm))
- if (alloc_apic_access_page(vmx->vcpu.kvm) != 0)
- return -ENOMEM;
return 0;
}
@@ -2534,6 +2535,9 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
put_cpu();
if (err)
goto free_vmcs;
+ if (vm_need_virtualize_apic_accesses(kvm))
+ if (alloc_apic_access_page(kvm) != 0)
+ goto free_vmcs;
return &vmx->vcpu;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index cf530814868..6b01552bd1f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -46,6 +46,9 @@
#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
+static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
+ struct kvm_cpuid_entry2 __user *entries);
+
struct kvm_x86_ops *kvm_x86_ops;
struct kvm_stats_debugfs_item debugfs_entries[] = {
@@ -181,7 +184,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
int ret;
u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)];
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn, pdpte,
offset * sizeof(u64), sizeof(pdpte));
if (ret < 0) {
@@ -198,7 +201,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
out:
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return ret;
}
@@ -212,13 +215,13 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu)
if (is_long_mode(vcpu) || !is_pae(vcpu))
return false;
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte));
if (r < 0)
goto out;
changed = memcmp(pdpte, vcpu->arch.pdptrs, sizeof(pdpte)) != 0;
out:
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return changed;
}
@@ -356,7 +359,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
*/
}
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
/*
* Does the new cr3 value map to physical memory? (Note, we
* catch an invalid cr3 even in real-mode, because it would
@@ -372,7 +375,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
vcpu->arch.cr3 = cr3;
vcpu->arch.mmu.new_cr3(vcpu);
}
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
}
EXPORT_SYMBOL_GPL(set_cr3);
@@ -484,6 +487,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
pr_unimpl(vcpu, "%s: MSR_IA32_MCG_STATUS 0x%llx, nop\n",
__FUNCTION__, data);
break;
+ case MSR_IA32_MCG_CTL:
+ pr_unimpl(vcpu, "%s: MSR_IA32_MCG_CTL 0x%llx, nop\n",
+ __FUNCTION__, data);
+ break;
case MSR_IA32_UCODE_REV:
case MSR_IA32_UCODE_WRITE:
case 0x200 ... 0x2ff: /* MTRRs */
@@ -526,6 +533,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_IA32_MC0_CTL:
case MSR_IA32_MCG_STATUS:
case MSR_IA32_MCG_CAP:
+ case MSR_IA32_MCG_CTL:
case MSR_IA32_MC0_MISC:
case MSR_IA32_MC0_MISC+4:
case MSR_IA32_MC0_MISC+8:
@@ -727,6 +735,24 @@ long kvm_arch_dev_ioctl(struct file *filp,
r = 0;
break;
}
+ case KVM_GET_SUPPORTED_CPUID: {
+ struct kvm_cpuid2 __user *cpuid_arg = argp;
+ struct kvm_cpuid2 cpuid;
+
+ r = -EFAULT;
+ if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
+ goto out;
+ r = kvm_dev_ioctl_get_supported_cpuid(&cpuid,
+ cpuid_arg->entries);
+ if (r)
+ goto out;
+
+ r = -EFAULT;
+ if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid))
+ goto out;
+ r = 0;
+ break;
+ }
default:
r = -EINVAL;
}
@@ -974,8 +1000,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
put_cpu();
}
-static int kvm_vm_ioctl_get_supported_cpuid(struct kvm *kvm,
- struct kvm_cpuid2 *cpuid,
+static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *entries)
{
struct kvm_cpuid_entry2 *cpuid_entries;
@@ -1207,12 +1232,12 @@ static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES)
return -EINVAL;
- down_write(&current->mm->mmap_sem);
+ down_write(&kvm->slots_lock);
kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages;
- up_write(&current->mm->mmap_sem);
+ up_write(&kvm->slots_lock);
return 0;
}
@@ -1261,7 +1286,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
< alias->target_phys_addr)
goto out;
- down_write(&current->mm->mmap_sem);
+ down_write(&kvm->slots_lock);
p = &kvm->arch.aliases[alias->slot];
p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT;
@@ -1275,7 +1300,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
kvm_mmu_zap_all(kvm);
- up_write(&current->mm->mmap_sem);
+ up_write(&kvm->slots_lock);
return 0;
@@ -1351,7 +1376,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
struct kvm_memory_slot *memslot;
int is_dirty = 0;
- down_write(&current->mm->mmap_sem);
+ down_write(&kvm->slots_lock);
r = kvm_get_dirty_log(kvm, log, &is_dirty);
if (r)
@@ -1367,7 +1392,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
}
r = 0;
out:
- up_write(&current->mm->mmap_sem);
+ up_write(&kvm->slots_lock);
return r;
}
@@ -1487,24 +1512,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
r = 0;
break;
}
- case KVM_GET_SUPPORTED_CPUID: {
- struct kvm_cpuid2 __user *cpuid_arg = argp;
- struct kvm_cpuid2 cpuid;
-
- r = -EFAULT;
- if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
- goto out;
- r = kvm_vm_ioctl_get_supported_cpuid(kvm, &cpuid,
- cpuid_arg->entries);
- if (r)
- goto out;
-
- r = -EFAULT;
- if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid))
- goto out;
- r = 0;
- break;
- }
default:
;
}
@@ -1563,7 +1570,7 @@ int emulator_read_std(unsigned long addr,
void *data = val;
int r = X86EMUL_CONTINUE;
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
while (bytes) {
gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
unsigned offset = addr & (PAGE_SIZE-1);
@@ -1585,7 +1592,7 @@ int emulator_read_std(unsigned long addr,
addr += tocopy;
}
out:
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return r;
}
EXPORT_SYMBOL_GPL(emulator_read_std);
@@ -1604,9 +1611,9 @@ static int emulator_read_emulated(unsigned long addr,
return X86EMUL_CONTINUE;
}
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
/* For APIC access vmexit */
if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
@@ -1644,14 +1651,14 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
{
int ret;
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes);
if (ret < 0) {
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return 0;
}
kvm_mmu_pte_write(vcpu, gpa, val, bytes);
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return 1;
}
@@ -1663,9 +1670,9 @@ static int emulator_write_emulated_onepage(unsigned long addr,
struct kvm_io_device *mmio_dev;
gpa_t gpa;
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
if (gpa == UNMAPPED_GVA) {
kvm_inject_page_fault(vcpu, addr, 2);
@@ -1742,7 +1749,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
char *kaddr;
u64 val;
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
if (gpa == UNMAPPED_GVA ||
@@ -1753,13 +1760,17 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
goto emul_write;
val = *(u64 *)new;
+
+ down_read(&current->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+ up_read(&current->mm->mmap_sem);
+
kaddr = kmap_atomic(page, KM_USER0);
set_64bit((u64 *)(kaddr + offset_in_page(gpa)), val);
kunmap_atomic(kaddr, KM_USER0);
kvm_release_page_dirty(page);
emul_write:
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
}
#endif
@@ -2152,10 +2163,10 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
kvm_x86_ops->skip_emulated_instruction(vcpu);
for (i = 0; i < nr_pages; ++i) {
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
page = gva_to_page(vcpu, address + i * PAGE_SIZE);
vcpu->arch.pio.guest_pages[i] = page;
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
if (!page) {
kvm_inject_gp(vcpu, 0);
free_pio_guest_pages(vcpu);
@@ -2478,8 +2489,9 @@ static void vapic_enter(struct kvm_vcpu *vcpu)
down_read(&current->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
- vcpu->arch.apic->vapic_page = page;
up_read(&current->mm->mmap_sem);
+
+ vcpu->arch.apic->vapic_page = page;
}
static void vapic_exit(struct kvm_vcpu *vcpu)
@@ -2861,8 +2873,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
kvm_x86_ops->decache_cr4_guest_bits(vcpu);
mmu_reset_needed |= vcpu->arch.cr0 != sregs->cr0;
- vcpu->arch.cr0 = sregs->cr0;
kvm_x86_ops->set_cr0(vcpu, sregs->cr0);
+ vcpu->arch.cr0 = sregs->cr0;
mmu_reset_needed |= vcpu->arch.cr4 != sregs->cr4;
kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
@@ -2952,9 +2964,9 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
gpa_t gpa;
vcpu_load(vcpu);
- down_read(&current->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr);
- up_read(&current->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
tr->physical_address = gpa;
tr->valid = gpa != UNMAPPED_GVA;
tr->writeable = 1;
@@ -3227,11 +3239,13 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
*/
if (!user_alloc) {
if (npages && !old.rmap) {
+ down_write(&current->mm->mmap_sem);
memslot->userspace_addr = do_mmap(NULL, 0,
npages * PAGE_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS,
0);
+ up_write(&current->mm->mmap_sem);
if (IS_ERR((void *)memslot->userspace_addr))
return PTR_ERR((void *)memslot->userspace_addr);
@@ -3239,8 +3253,10 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
if (!old.user_alloc && old.rmap) {
int ret;
+ down_write(&current->mm->mmap_sem);
ret = do_munmap(current->mm, old.userspace_addr,
old.npages * PAGE_SIZE);
+ up_write(&current->mm->mmap_sem);
if (ret < 0)
printk(KERN_WARNING
"kvm_vm_ioctl_set_memory_region: "
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 5afdde4895d..cccb38a5965 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -57,6 +57,7 @@
#include <linux/lguest_launcher.h>
#include <linux/virtio_console.h>
#include <linux/pm.h>
+#include <asm/lguest.h>
#include <asm/paravirt.h>
#include <asm/param.h>
#include <asm/page.h>
@@ -75,15 +76,6 @@
* behaving in simplified but equivalent ways. In particular, the Guest is the
* same kernel as the Host (or at least, built from the same source code). :*/
-/* Declarations for definitions in lguest_guest.S */
-extern char lguest_noirq_start[], lguest_noirq_end[];
-extern const char lgstart_cli[], lgend_cli[];
-extern const char lgstart_sti[], lgend_sti[];
-extern const char lgstart_popf[], lgend_popf[];
-extern const char lgstart_pushf[], lgend_pushf[];
-extern const char lgstart_iret[], lgend_iret[];
-extern void lguest_iret(void);
-
struct lguest_data lguest_data = {
.hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF },
.noirq_start = (u32)lguest_noirq_start,
@@ -489,7 +481,7 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
{
*pmdp = pmdval;
lazy_hcall(LHCALL_SET_PMD, __pa(pmdp)&PAGE_MASK,
- (__pa(pmdp)&(PAGE_SIZE-1))/4, 0);
+ (__pa(pmdp)&(PAGE_SIZE-1)), 0);
}
/* There are a couple of legacy places where the kernel sets a PTE, but we
diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c
index fd42a4a095f..459b58a8a15 100644
--- a/arch/x86/lib/csum-wrappers_64.c
+++ b/arch/x86/lib/csum-wrappers_64.c
@@ -1,117 +1,129 @@
-/* Copyright 2002,2003 Andi Kleen, SuSE Labs.
+/*
+ * Copyright 2002, 2003 Andi Kleen, SuSE Labs.
* Subject to the GNU Public License v.2
- *
+ *
* Wrappers of assembly checksum functions for x86-64.
*/
-
#include <asm/checksum.h>
#include <linux/module.h>
-/**
- * csum_partial_copy_from_user - Copy and checksum from user space.
- * @src: source address (user space)
+/**
+ * csum_partial_copy_from_user - Copy and checksum from user space.
+ * @src: source address (user space)
* @dst: destination address
* @len: number of bytes to be copied.
* @isum: initial sum that is added into the result (32bit unfolded)
* @errp: set to -EFAULT for an bad source address.
- *
+ *
* Returns an 32bit unfolded checksum of the buffer.
- * src and dst are best aligned to 64bits.
- */
+ * src and dst are best aligned to 64bits.
+ */
__wsum
csum_partial_copy_from_user(const void __user *src, void *dst,
int len, __wsum isum, int *errp)
-{
+{
might_sleep();
*errp = 0;
- if (likely(access_ok(VERIFY_READ,src, len))) {
- /* Why 6, not 7? To handle odd addresses aligned we
- would need to do considerable complications to fix the
- checksum which is defined as an 16bit accumulator. The
- fix alignment code is primarily for performance
- compatibility with 32bit and that will handle odd
- addresses slowly too. */
- if (unlikely((unsigned long)src & 6)) {
- while (((unsigned long)src & 6) && len >= 2) {
- __u16 val16;
- *errp = __get_user(val16, (const __u16 __user *)src);
- if (*errp)
- return isum;
- *(__u16 *)dst = val16;
- isum = (__force __wsum)add32_with_carry(
- (__force unsigned)isum, val16);
- src += 2;
- dst += 2;
- len -= 2;
- }
+
+ if (!likely(access_ok(VERIFY_READ, src, len)))
+ goto out_err;
+
+ /*
+ * Why 6, not 7? To handle odd addresses aligned we
+ * would need to do considerable complications to fix the
+ * checksum which is defined as an 16bit accumulator. The
+ * fix alignment code is primarily for performance
+ * compatibility with 32bit and that will handle odd
+ * addresses slowly too.
+ */
+ if (unlikely((unsigned long)src & 6)) {
+ while (((unsigned long)src & 6) && len >= 2) {
+ __u16 val16;
+
+ *errp = __get_user(val16, (const __u16 __user *)src);
+ if (*errp)
+ return isum;
+
+ *(__u16 *)dst = val16;
+ isum = (__force __wsum)add32_with_carry(
+ (__force unsigned)isum, val16);
+ src += 2;
+ dst += 2;
+ len -= 2;
}
- isum = csum_partial_copy_generic((__force const void *)src,
- dst, len, isum, errp, NULL);
- if (likely(*errp == 0))
- return isum;
- }
+ }
+ isum = csum_partial_copy_generic((__force const void *)src,
+ dst, len, isum, errp, NULL);
+ if (unlikely(*errp))
+ goto out_err;
+
+ return isum;
+
+out_err:
*errp = -EFAULT;
- memset(dst,0,len);
- return isum;
-}
+ memset(dst, 0, len);
+ return isum;
+}
EXPORT_SYMBOL(csum_partial_copy_from_user);
-/**
- * csum_partial_copy_to_user - Copy and checksum to user space.
+/**
+ * csum_partial_copy_to_user - Copy and checksum to user space.
* @src: source address
* @dst: destination address (user space)
* @len: number of bytes to be copied.
* @isum: initial sum that is added into the result (32bit unfolded)
* @errp: set to -EFAULT for an bad destination address.
- *
+ *
* Returns an 32bit unfolded checksum of the buffer.
* src and dst are best aligned to 64bits.
- */
+ */
__wsum
csum_partial_copy_to_user(const void *src, void __user *dst,
int len, __wsum isum, int *errp)
-{
+{
might_sleep();
+
if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) {
*errp = -EFAULT;
- return 0;
+ return 0;
}
if (unlikely((unsigned long)dst & 6)) {
- while (((unsigned long)dst & 6) && len >= 2) {
+ while (((unsigned long)dst & 6) && len >= 2) {
__u16 val16 = *(__u16 *)src;
+
isum = (__force __wsum)add32_with_carry(
(__force unsigned)isum, val16);
*errp = __put_user(val16, (__u16 __user *)dst);
if (*errp)
return isum;
- src += 2;
- dst += 2;
+ src += 2;
+ dst += 2;
len -= 2;
}
}
*errp = 0;
- return csum_partial_copy_generic(src, (void __force *)dst,len,isum,NULL,errp);
-}
-
+ return csum_partial_copy_generic(src, (void __force *)dst,
+ len, isum, NULL, errp);
+}
EXPORT_SYMBOL(csum_partial_copy_to_user);
-/**
+/**
* csum_partial_copy_nocheck - Copy and checksum.
* @src: source address
* @dst: destination address
* @len: number of bytes to be copied.
* @isum: initial sum that is added into the result (32bit unfolded)
- *
+ *
* Returns an 32bit unfolded checksum of the buffer.
- */
+ */
__wsum
csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
-{
- return csum_partial_copy_generic(src,dst,len,sum,NULL,NULL);
-}
+{
+ return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL);
+}
EXPORT_SYMBOL(csum_partial_copy_nocheck);
__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
@@ -119,17 +131,20 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
__u32 len, unsigned short proto, __wsum sum)
{
__u64 rest, sum64;
-
+
rest = (__force __u64)htonl(len) + (__force __u64)htons(proto) +
(__force __u64)sum;
- asm(" addq (%[saddr]),%[sum]\n"
- " adcq 8(%[saddr]),%[sum]\n"
- " adcq (%[daddr]),%[sum]\n"
- " adcq 8(%[daddr]),%[sum]\n"
- " adcq $0,%[sum]\n"
- : [sum] "=r" (sum64)
- : "[sum]" (rest),[saddr] "r" (saddr), [daddr] "r" (daddr));
- return csum_fold((__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32));
-}
+ asm(" addq (%[saddr]),%[sum]\n"
+ " adcq 8(%[saddr]),%[sum]\n"
+ " adcq (%[daddr]),%[sum]\n"
+ " adcq 8(%[daddr]),%[sum]\n"
+ " adcq $0,%[sum]\n"
+
+ : [sum] "=r" (sum64)
+ : "[sum]" (rest), [saddr] "r" (saddr), [daddr] "r" (daddr));
+
+ return csum_fold(
+ (__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32));
+}
EXPORT_SYMBOL(csum_ipv6_magic);
diff --git a/arch/x86/lib/io_64.c b/arch/x86/lib/io_64.c
index 87b4a4e1803..3f1eb59b5f0 100644
--- a/arch/x86/lib/io_64.c
+++ b/arch/x86/lib/io_64.c
@@ -1,23 +1,25 @@
#include <linux/string.h>
-#include <asm/io.h>
#include <linux/module.h>
+#include <asm/io.h>
-void __memcpy_toio(unsigned long dst,const void*src,unsigned len)
+void __memcpy_toio(unsigned long dst, const void *src, unsigned len)
{
- __inline_memcpy((void *) dst,src,len);
+ __inline_memcpy((void *)dst, src, len);
}
EXPORT_SYMBOL(__memcpy_toio);
-void __memcpy_fromio(void *dst,unsigned long src,unsigned len)
+void __memcpy_fromio(void *dst, unsigned long src, unsigned len)
{
- __inline_memcpy(dst,(const void *) src,len);
+ __inline_memcpy(dst, (const void *)src, len);
}
EXPORT_SYMBOL(__memcpy_fromio);
void memset_io(volatile void __iomem *a, int b, size_t c)
{
- /* XXX: memset can mangle the IO patterns quite a bit.
- perhaps it would be better to use a dumb one */
- memset((void *)a,b,c);
+ /*
+ * TODO: memset can mangle the IO patterns quite a bit.
+ * perhaps it would be better to use a dumb one:
+ */
+ memset((void *)a, b, c);
}
EXPORT_SYMBOL(memset_io);
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index a4a9cccdd4f..a02a14f0f32 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -171,6 +171,34 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
__flush_tlb_one(vaddr);
}
+/*
+ * The head.S code sets up the kernel high mapping:
+ *
+ * from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text)
+ *
+ * phys_addr holds the negative offset to the kernel, which is added
+ * to the compile time generated pmds. This results in invalid pmds up
+ * to the point where we hit the physaddr 0 mapping.
+ *
+ * We limit the mappings to the region from _text to _end. _end is
+ * rounded up to the 2MB boundary. This catches the invalid pmds as
+ * well, as they are located before _text:
+ */
+void __init cleanup_highmap(void)
+{
+ unsigned long vaddr = __START_KERNEL_map;
+ unsigned long end = round_up((unsigned long)_end, PMD_SIZE) - 1;
+ pmd_t *pmd = level2_kernel_pgt;
+ pmd_t *last_pmd = pmd + PTRS_PER_PMD;
+
+ for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) {
+ if (!pmd_present(*pmd))
+ continue;
+ if (vaddr < (unsigned long) _text || vaddr > end)
+ set_pmd(pmd, __pmd(0));
+ }
+}
+
/* NOTE: this is meant to be run only at boot */
void __init
__set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
@@ -488,14 +516,6 @@ void __init mem_init(void)
/* clear_bss() already clear the empty_zero_page */
- /* temporary debugging - double check it's true: */
- {
- int i;
-
- for (i = 0; i < 1024; i++)
- WARN_ON_ONCE(empty_zero_page[i]);
- }
-
reservedpages = 0;
/* this will put all low memory onto the freelists */
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 9f42d7e9c15..ac3c959e271 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -42,6 +42,22 @@ int page_is_ram(unsigned long pagenr)
unsigned long addr, end;
int i;
+ /*
+ * A special case is the first 4Kb of memory;
+ * This is a BIOS owned area, not kernel ram, but generally
+ * not listed as such in the E820 table.
+ */
+ if (pagenr == 0)
+ return 0;
+
+ /*
+ * Second special case: Some BIOSen report the PC BIOS
+ * area (640->1Mb) as ram even though it is not.
+ */
+ if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
+ pagenr < (BIOS_END >> PAGE_SHIFT))
+ return 0;
+
for (i = 0; i < e820.nr_map; i++) {
/*
* Not usable memory:
@@ -51,14 +67,6 @@ int page_is_ram(unsigned long pagenr)
addr = (e820.map[i].addr + PAGE_SIZE-1) >> PAGE_SHIFT;
end = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT;
- /*
- * Sanity check: Some BIOSen report areas as RAM that
- * are not. Notably the 640->1Mb area, which is the
- * PCI BIOS area.
- */
- if (addr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
- end < (BIOS_END >> PAGE_SHIFT))
- continue;
if ((pagenr >= addr) && (pagenr < end))
return 1;
@@ -126,6 +134,8 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
return NULL;
}
+ WARN_ON_ONCE(page_is_ram(pfn));
+
switch (mode) {
case IOR_MODE_UNCACHED:
default:
@@ -152,7 +162,7 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
area->phys_addr = phys_addr;
vaddr = (unsigned long) area->addr;
if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
- remove_vm_area((void *)(vaddr & PAGE_MASK));
+ free_vm_area(area);
return NULL;
}
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 1aecc658cd7..8ccfee10f5b 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -494,11 +494,13 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
int i;
nodes_clear(node_possible_map);
+ nodes_clear(node_online_map);
#ifdef CONFIG_NUMA_EMU
if (cmdline && !numa_emulation(start_pfn, end_pfn))
return;
nodes_clear(node_possible_map);
+ nodes_clear(node_online_map);
#endif
#ifdef CONFIG_ACPI_NUMA
@@ -506,6 +508,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
end_pfn << PAGE_SHIFT))
return;
nodes_clear(node_possible_map);
+ nodes_clear(node_online_map);
#endif
#ifdef CONFIG_K8_NUMA
@@ -513,6 +516,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
end_pfn<<PAGE_SHIFT))
return;
nodes_clear(node_possible_map);
+ nodes_clear(node_online_map);
#endif
printk(KERN_INFO "%s\n",
numa_off ? "NUMA turned off" : "No NUMA configuration found");
@@ -524,7 +528,6 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
memnode_shift = 63;
memnodemap = memnode.embedded_map;
memnodemap[0] = 0;
- nodes_clear(node_online_map);
node_set_online(0);
node_set(0, node_possible_map);
for (i = 0; i < NR_CPUS; i++)
@@ -619,13 +622,17 @@ void __init init_cpu_to_node(void)
int i;
for (i = 0; i < NR_CPUS; i++) {
+ int node;
u16 apicid = x86_cpu_to_apicid_init[i];
if (apicid == BAD_APICID)
continue;
- if (apicid_to_node[apicid] == NUMA_NO_NODE)
+ node = apicid_to_node[apicid];
+ if (node == NUMA_NO_NODE)
+ continue;
+ if (!node_online(node))
continue;
- numa_set_node(i, apicid_to_node[apicid]);
+ numa_set_node(i, node);
}
}
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 4119379f80f..14e48b5a94b 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -16,6 +16,7 @@
#include <asm/sections.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
+#include <asm/proto.h>
/*
* The current flushing context - we pass it instead of 5 arguments:
@@ -26,8 +27,29 @@ struct cpa_data {
pgprot_t mask_clr;
int numpages;
int flushtlb;
+ unsigned long pfn;
};
+#ifdef CONFIG_X86_64
+
+static inline unsigned long highmap_start_pfn(void)
+{
+ return __pa(_text) >> PAGE_SHIFT;
+}
+
+static inline unsigned long highmap_end_pfn(void)
+{
+ return __pa(round_up((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
+}
+
+#endif
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+# define debug_pagealloc 1
+#else
+# define debug_pagealloc 0
+#endif
+
static inline int
within(unsigned long addr, unsigned long start, unsigned long end)
{
@@ -123,29 +145,14 @@ static void cpa_flush_range(unsigned long start, int numpages, int cache)
}
}
-#define HIGH_MAP_START __START_KERNEL_map
-#define HIGH_MAP_END (__START_KERNEL_map + KERNEL_TEXT_SIZE)
-
-
-/*
- * Converts a virtual address to a X86-64 highmap address
- */
-static unsigned long virt_to_highmap(void *address)
-{
-#ifdef CONFIG_X86_64
- return __pa((unsigned long)address) + HIGH_MAP_START - phys_base;
-#else
- return (unsigned long)address;
-#endif
-}
-
/*
* Certain areas of memory on x86 require very specific protection flags,
* for example the BIOS area or kernel text. Callers don't always get this
* right (again, ioremap() on BIOS memory is not uncommon) so this function
* checks and fixes these known static required protection bits.
*/
-static inline pgprot_t static_protections(pgprot_t prot, unsigned long address)
+static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
+ unsigned long pfn)
{
pgprot_t forbidden = __pgprot(0);
@@ -153,30 +160,23 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address)
* The BIOS area between 640k and 1Mb needs to be executable for
* PCI BIOS based config access (CONFIG_PCI_GOBIOS) support.
*/
- if (within(__pa(address), BIOS_BEGIN, BIOS_END))
+ if (within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END >> PAGE_SHIFT))
pgprot_val(forbidden) |= _PAGE_NX;
/*
* The kernel text needs to be executable for obvious reasons
- * Does not cover __inittext since that is gone later on
+ * Does not cover __inittext since that is gone later on. On
+ * 64bit we do not enforce !NX on the low mapping
*/
if (within(address, (unsigned long)_text, (unsigned long)_etext))
pgprot_val(forbidden) |= _PAGE_NX;
- /*
- * Do the same for the x86-64 high kernel mapping
- */
- if (within(address, virt_to_highmap(_text), virt_to_highmap(_etext)))
- pgprot_val(forbidden) |= _PAGE_NX;
- /* The .rodata section needs to be read-only */
- if (within(address, (unsigned long)__start_rodata,
- (unsigned long)__end_rodata))
- pgprot_val(forbidden) |= _PAGE_RW;
/*
- * Do the same for the x86-64 high kernel mapping
+ * The .rodata section needs to be read-only. Using the pfn
+ * catches all aliases.
*/
- if (within(address, virt_to_highmap(__start_rodata),
- virt_to_highmap(__end_rodata)))
+ if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT,
+ __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
pgprot_val(forbidden) |= _PAGE_RW;
prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
@@ -253,7 +253,7 @@ static int
try_preserve_large_page(pte_t *kpte, unsigned long address,
struct cpa_data *cpa)
{
- unsigned long nextpage_addr, numpages, pmask, psize, flags, addr;
+ unsigned long nextpage_addr, numpages, pmask, psize, flags, addr, pfn;
pte_t new_pte, old_pte, *tmp;
pgprot_t old_prot, new_prot;
int i, do_split = 1;
@@ -301,7 +301,15 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr);
pgprot_val(new_prot) |= pgprot_val(cpa->mask_set);
- new_prot = static_protections(new_prot, address);
+
+ /*
+ * old_pte points to the large page base address. So we need
+ * to add the offset of the virtual address:
+ */
+ pfn = pte_pfn(old_pte) + ((address & (psize - 1)) >> PAGE_SHIFT);
+ cpa->pfn = pfn;
+
+ new_prot = static_protections(new_prot, address, pfn);
/*
* We need to check the full range, whether
@@ -309,8 +317,9 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
* the pages in the range we try to preserve:
*/
addr = address + PAGE_SIZE;
- for (i = 1; i < cpa->numpages; i++, addr += PAGE_SIZE) {
- pgprot_t chk_prot = static_protections(new_prot, addr);
+ pfn++;
+ for (i = 1; i < cpa->numpages; i++, addr += PAGE_SIZE, pfn++) {
+ pgprot_t chk_prot = static_protections(new_prot, addr, pfn);
if (pgprot_val(chk_prot) != pgprot_val(new_prot))
goto out_unlock;
@@ -352,45 +361,48 @@ out_unlock:
static LIST_HEAD(page_pool);
static unsigned long pool_size, pool_pages, pool_low;
-static unsigned long pool_used, pool_failed, pool_refill;
+static unsigned long pool_used, pool_failed;
-static void cpa_fill_pool(void)
+static void cpa_fill_pool(struct page **ret)
{
- struct page *p;
gfp_t gfp = GFP_KERNEL;
+ unsigned long flags;
+ struct page *p;
- /* Do not allocate from interrupt context */
- if (in_irq() || irqs_disabled())
- return;
/*
- * Check unlocked. I does not matter when we have one more
- * page in the pool. The bit lock avoids recursive pool
- * allocations:
+ * Avoid recursion (on debug-pagealloc) and also signal
+ * our priority to get to these pagetables:
*/
- if (pool_pages >= pool_size || test_and_set_bit_lock(0, &pool_refill))
+ if (current->flags & PF_MEMALLOC)
return;
+ current->flags |= PF_MEMALLOC;
-#ifdef CONFIG_DEBUG_PAGEALLOC
/*
- * We could do:
- * gfp = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
- * but this fails on !PREEMPT kernels
+ * Allocate atomically from atomic contexts:
*/
- gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
-#endif
+ if (in_atomic() || irqs_disabled() || debug_pagealloc)
+ gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
- while (pool_pages < pool_size) {
+ while (pool_pages < pool_size || (ret && !*ret)) {
p = alloc_pages(gfp, 0);
if (!p) {
pool_failed++;
break;
}
- spin_lock_irq(&pgd_lock);
+ /*
+ * If the call site needs a page right now, provide it:
+ */
+ if (ret && !*ret) {
+ *ret = p;
+ continue;
+ }
+ spin_lock_irqsave(&pgd_lock, flags);
list_add(&p->lru, &page_pool);
pool_pages++;
- spin_unlock_irq(&pgd_lock);
+ spin_unlock_irqrestore(&pgd_lock, flags);
}
- clear_bit_unlock(0, &pool_refill);
+
+ current->flags &= ~PF_MEMALLOC;
}
#define SHIFT_MB (20 - PAGE_SHIFT)
@@ -411,11 +423,15 @@ void __init cpa_init(void)
* GiB. Shift MiB to Gib and multiply the result by
* POOL_PAGES_PER_GB:
*/
- gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB;
- pool_size = POOL_PAGES_PER_GB * gb;
+ if (debug_pagealloc) {
+ gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB;
+ pool_size = POOL_PAGES_PER_GB * gb;
+ } else {
+ pool_size = 1;
+ }
pool_low = pool_size;
- cpa_fill_pool();
+ cpa_fill_pool(NULL);
printk(KERN_DEBUG
"CPA: page pool initialized %lu of %lu pages preallocated\n",
pool_pages, pool_size);
@@ -437,16 +453,20 @@ static int split_large_page(pte_t *kpte, unsigned long address)
spin_lock_irqsave(&pgd_lock, flags);
if (list_empty(&page_pool)) {
spin_unlock_irqrestore(&pgd_lock, flags);
- return -ENOMEM;
+ base = NULL;
+ cpa_fill_pool(&base);
+ if (!base)
+ return -ENOMEM;
+ spin_lock_irqsave(&pgd_lock, flags);
+ } else {
+ base = list_first_entry(&page_pool, struct page, lru);
+ list_del(&base->lru);
+ pool_pages--;
+
+ if (pool_pages < pool_low)
+ pool_low = pool_pages;
}
- base = list_first_entry(&page_pool, struct page, lru);
- list_del(&base->lru);
- pool_pages--;
-
- if (pool_pages < pool_low)
- pool_low = pool_pages;
-
/*
* Check for races, another CPU might have split this page
* up for us already:
@@ -505,46 +525,46 @@ out_unlock:
return 0;
}
-static int __change_page_attr(unsigned long address, struct cpa_data *cpa)
+static int __change_page_attr(struct cpa_data *cpa, int primary)
{
+ unsigned long address = cpa->vaddr;
int do_split, err;
unsigned int level;
- struct page *kpte_page;
- pte_t *kpte;
+ pte_t *kpte, old_pte;
repeat:
kpte = lookup_address(address, &level);
if (!kpte)
- return -EINVAL;
+ return primary ? -EINVAL : 0;
- kpte_page = virt_to_page(kpte);
- BUG_ON(PageLRU(kpte_page));
- BUG_ON(PageCompound(kpte_page));
+ old_pte = *kpte;
+ if (!pte_val(old_pte)) {
+ if (!primary)
+ return 0;
+ printk(KERN_WARNING "CPA: called for zero pte. "
+ "vaddr = %lx cpa->vaddr = %lx\n", address,
+ cpa->vaddr);
+ WARN_ON(1);
+ return -EINVAL;
+ }
if (level == PG_LEVEL_4K) {
- pte_t new_pte, old_pte = *kpte;
+ pte_t new_pte;
pgprot_t new_prot = pte_pgprot(old_pte);
-
- if(!pte_val(old_pte)) {
- printk(KERN_WARNING "CPA: called for zero pte. "
- "vaddr = %lx cpa->vaddr = %lx\n", address,
- cpa->vaddr);
- WARN_ON(1);
- return -EINVAL;
- }
+ unsigned long pfn = pte_pfn(old_pte);
pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr);
pgprot_val(new_prot) |= pgprot_val(cpa->mask_set);
- new_prot = static_protections(new_prot, address);
+ new_prot = static_protections(new_prot, address, pfn);
/*
* We need to keep the pfn from the existing PTE,
* after all we're only going to change it's attributes
* not the memory it points to
*/
- new_pte = pfn_pte(pte_pfn(old_pte), canon_pgprot(new_prot));
-
+ new_pte = pfn_pte(pfn, canon_pgprot(new_prot));
+ cpa->pfn = pfn;
/*
* Do we really change anything ?
*/
@@ -581,67 +601,59 @@ repeat:
return err;
}
-/**
- * change_page_attr_addr - Change page table attributes in linear mapping
- * @address: Virtual address in linear mapping.
- * @prot: New page table attribute (PAGE_*)
- *
- * Change page attributes of a page in the direct mapping. This is a variant
- * of change_page_attr() that also works on memory holes that do not have
- * mem_map entry (pfn_valid() is false).
- *
- * See change_page_attr() documentation for more details.
- *
- * Modules and drivers should use the set_memory_* APIs instead.
- */
-static int change_page_attr_addr(struct cpa_data *cpa)
+static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias);
+
+static int cpa_process_alias(struct cpa_data *cpa)
{
- int err;
- unsigned long address = cpa->vaddr;
+ struct cpa_data alias_cpa;
+ int ret = 0;
-#ifdef CONFIG_X86_64
- unsigned long phys_addr = __pa(address);
+ if (cpa->pfn > max_pfn_mapped)
+ return 0;
/*
- * If we are inside the high mapped kernel range, then we
- * fixup the low mapping first. __va() returns the virtual
- * address in the linear mapping:
+ * No need to redo, when the primary call touched the direct
+ * mapping already:
*/
- if (within(address, HIGH_MAP_START, HIGH_MAP_END))
- address = (unsigned long) __va(phys_addr);
-#endif
+ if (!within(cpa->vaddr, PAGE_OFFSET,
+ PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) {
- err = __change_page_attr(address, cpa);
- if (err)
- return err;
+ alias_cpa = *cpa;
+ alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
+
+ ret = __change_page_attr_set_clr(&alias_cpa, 0);
+ }
#ifdef CONFIG_X86_64
+ if (ret)
+ return ret;
+ /*
+ * No need to redo, when the primary call touched the high
+ * mapping already:
+ */
+ if (within(cpa->vaddr, (unsigned long) _text, (unsigned long) _end))
+ return 0;
+
/*
* If the physical address is inside the kernel map, we need
* to touch the high mapped kernel as well:
*/
- if (within(phys_addr, 0, KERNEL_TEXT_SIZE)) {
- /*
- * Calc the high mapping address. See __phys_addr()
- * for the non obvious details.
- *
- * Note that NX and other required permissions are
- * checked in static_protections().
- */
- address = phys_addr + HIGH_MAP_START - phys_base;
+ if (!within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn()))
+ return 0;
- /*
- * Our high aliases are imprecise, because we check
- * everything between 0 and KERNEL_TEXT_SIZE, so do
- * not propagate lookup failures back to users:
- */
- __change_page_attr(address, cpa);
- }
+ alias_cpa = *cpa;
+ alias_cpa.vaddr =
+ (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base;
+
+ /*
+ * The high mapping range is imprecise, so ignore the return value.
+ */
+ __change_page_attr_set_clr(&alias_cpa, 0);
#endif
- return err;
+ return ret;
}
-static int __change_page_attr_set_clr(struct cpa_data *cpa)
+static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
{
int ret, numpages = cpa->numpages;
@@ -651,10 +663,17 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa)
* preservation check.
*/
cpa->numpages = numpages;
- ret = change_page_attr_addr(cpa);
+
+ ret = __change_page_attr(cpa, checkalias);
if (ret)
return ret;
+ if (checkalias) {
+ ret = cpa_process_alias(cpa);
+ if (ret)
+ return ret;
+ }
+
/*
* Adjust the number of pages with the result of the
* CPA operation. Either a large page has been
@@ -677,7 +696,7 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages,
pgprot_t mask_set, pgprot_t mask_clr)
{
struct cpa_data cpa;
- int ret, cache;
+ int ret, cache, checkalias;
/*
* Check, if we are requested to change a not supported
@@ -703,7 +722,10 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages,
cpa.mask_clr = mask_clr;
cpa.flushtlb = 0;
- ret = __change_page_attr_set_clr(&cpa);
+ /* No alias checking for _NX bit modifications */
+ checkalias = (pgprot_val(mask_set) | pgprot_val(mask_clr)) != _PAGE_NX;
+
+ ret = __change_page_attr_set_clr(&cpa, checkalias);
/*
* Check whether we really changed something:
@@ -729,7 +751,8 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages,
cpa_flush_all(cache);
out:
- cpa_fill_pool();
+ cpa_fill_pool(NULL);
+
return ret;
}
@@ -841,7 +864,7 @@ static int __set_pages_p(struct page *page, int numpages)
.mask_set = __pgprot(_PAGE_PRESENT | _PAGE_RW),
.mask_clr = __pgprot(0)};
- return __change_page_attr_set_clr(&cpa);
+ return __change_page_attr_set_clr(&cpa, 1);
}
static int __set_pages_np(struct page *page, int numpages)
@@ -851,7 +874,7 @@ static int __set_pages_np(struct page *page, int numpages)
.mask_set = __pgprot(0),
.mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW)};
- return __change_page_attr_set_clr(&cpa);
+ return __change_page_attr_set_clr(&cpa, 1);
}
void kernel_map_pages(struct page *page, int numpages, int enable)
@@ -892,9 +915,26 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
* Try to refill the page pool here. We can do this only after
* the tlb flush.
*/
- cpa_fill_pool();
+ cpa_fill_pool(NULL);
}
-#endif
+
+#ifdef CONFIG_HIBERNATION
+
+bool kernel_page_present(struct page *page)
+{
+ unsigned int level;
+ pte_t *pte;
+
+ if (PageHighMem(page))
+ return false;
+
+ pte = lookup_address((unsigned long)page_address(page), &level);
+ return (pte_val(*pte) & _PAGE_PRESENT);
+}
+
+#endif /* CONFIG_HIBERNATION */
+
+#endif /* CONFIG_DEBUG_PAGEALLOC */
/*
* The testcases use internal knowledge of the implementation that shouldn't
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index ecd91ea8a8a..845001c617c 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -166,7 +166,8 @@ static inline int save_add_info(void) {return 0;}
* Both SPARSE and RESERVE need nodes_add information.
* This code supports one contiguous hot add area per node.
*/
-static int reserve_hotadd(int node, unsigned long start, unsigned long end)
+static int __init
+reserve_hotadd(int node, unsigned long start, unsigned long end)
{
unsigned long s_pfn = start >> PAGE_SHIFT;
unsigned long e_pfn = end >> PAGE_SHIFT;
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index b7c67a187b6..7b6e3bb9b28 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -541,7 +541,7 @@ void pcibios_disable_device (struct pci_dev *dev)
pcibios_disable_irq(dev);
}
-struct pci_bus *pci_scan_bus_with_sysdata(int busno)
+struct pci_bus *__devinit pci_scan_bus_with_sysdata(int busno)
{
struct pci_bus *bus = NULL;
struct pci_sysdata *sd;
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index ed07ce6c171..a8715861877 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -583,6 +583,10 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
case PCI_DEVICE_ID_INTEL_ICH9_4:
case PCI_DEVICE_ID_INTEL_ICH9_5:
case PCI_DEVICE_ID_INTEL_TOLAPAI_0:
+ case PCI_DEVICE_ID_INTEL_ICH10_0:
+ case PCI_DEVICE_ID_INTEL_ICH10_1:
+ case PCI_DEVICE_ID_INTEL_ICH10_2:
+ case PCI_DEVICE_ID_INTEL_ICH10_3:
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
r->set = pirq_piix_set;
diff --git a/arch/x86/power/hibernate_asm_64.S b/arch/x86/power/hibernate_asm_64.S
index 1deb3244b99..000415947d9 100644
--- a/arch/x86/power/hibernate_asm_64.S
+++ b/arch/x86/power/hibernate_asm_64.S
@@ -20,6 +20,7 @@
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/asm-offsets.h>
+#include <asm/processor-flags.h>
ENTRY(swsusp_arch_suspend)
movq $saved_context, %rax
@@ -60,7 +61,7 @@ ENTRY(restore_image)
/* Flush TLB */
movq mmu_cr4_features(%rip), %rax
movq %rax, %rdx
- andq $~(1<<7), %rdx # PGE
+ andq $~(X86_CR4_PGE), %rdx
movq %rdx, %cr4; # turn off PGE
movq %cr3, %rcx; # flush TLB
movq %rcx, %cr3;
@@ -112,7 +113,7 @@ ENTRY(restore_registers)
/* Flush TLB, including "global" things (vmalloc) */
movq mmu_cr4_features(%rip), %rax
movq %rax, %rdx
- andq $~(1<<7), %rdx; # PGE
+ andq $~(X86_CR4_PGE), %rdx
movq %rdx, %cr4; # turn off PGE
movq %cr3, %rcx; # flush TLB
movq %rcx, %cr3
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index f385a4b4a48..0a8f4742ef5 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -50,7 +50,9 @@ obj-$(VDSO64-y) += vdso-syms.lds
sed-vdsosym := -e 's/^00*/0/' \
-e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p'
quiet_cmd_vdsosym = VDSOSYM $@
- cmd_vdsosym = $(NM) $< | sed -n $(sed-vdsosym) | LC_ALL=C sort > $@
+define cmd_vdsosym
+ $(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@
+endef
$(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE
$(call if_changed,vdsosym)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 49e5358f481..8b9ee27805f 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -153,6 +153,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
if (*ax == 1)
maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */
(1 << X86_FEATURE_ACPI) | /* disable ACPI */
+ (1 << X86_FEATURE_SEP) | /* disable SEP */
(1 << X86_FEATURE_ACC)); /* thermal monitoring */
asm(XEN_EMULATE_PREFIX "cpuid"
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 3bad4773a2f..2341492bf7a 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -38,7 +38,8 @@ char * __init xen_memory_setup(void)
unsigned long max_pfn = xen_start_info->nr_pages;
e820.nr_map = 0;
- add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM);
+ add_memory_region(0, LOWMEMSIZE(), E820_RAM);
+ add_memory_region(HIGH_MEMORY, PFN_PHYS(max_pfn)-HIGH_MEMORY, E820_RAM);
return "Xen";
}
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index 56685a88334..4bd1e14c6b9 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -59,7 +59,7 @@ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
head-y := arch/xtensa/kernel/head.o
core-y += arch/xtensa/kernel/ arch/xtensa/mm/
ifneq ($(PLATFORM),)
-core-y += arch/xtensa/platform-$(PLATFORM)/
+core-y += arch/xtensa/platforms/$(PLATFORM)/
endif
libs-y += arch/xtensa/lib/ $(LIBGCC)
diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile
index 734db7f7658..08e8814f8c7 100644
--- a/arch/xtensa/boot/boot-elf/Makefile
+++ b/arch/xtensa/boot/boot-elf/Makefile
@@ -14,25 +14,26 @@ OBJCOPY_ARGS := -O elf32-xtensa-le
endif
export OBJCOPY_ARGS
+export CPPFLAGS_boot.lds += -P -C
boot-y := bootstrap.o
OBJS := $(addprefix $(obj)/,$(boot-y))
-Image: vmlinux $(OBJS)
- $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
+Image: vmlinux $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds
+ $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
vmlinux vmlinux.tmp
$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
--add-section image=vmlinux.tmp \
--set-section-flags image=contents,alloc,load,load,data \
$(OBJS) $@.tmp
$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
- -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \
+ -T arch/$(ARCH)/boot/boot-elf/boot.lds \
-o arch/$(ARCH)/boot/$@.elf $@.tmp
rm -f $@.tmp vmlinux.tmp
Image.initrd: vmlinux $(OBJS)
- $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
+ $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
--add-section .initrd=arch/$(ARCH)/boot/ramdisk \
--set-section-flags .initrd=contents,alloc,load,load,data \
vmlinux vmlinux.tmp
diff --git a/arch/xtensa/boot/boot-elf/boot.ld b/arch/xtensa/boot/boot-elf/boot.lds.S
index 4ab06a0a7a6..849dfcafd51 100644
--- a/arch/xtensa/boot/boot-elf/boot.ld
+++ b/arch/xtensa/boot/boot-elf/boot.lds.S
@@ -1,4 +1,6 @@
+#include <asm/variant/core.h>
OUTPUT_ARCH(xtensa)
+ENTRY(_ResetVector)
SECTIONS
{
@@ -61,7 +63,7 @@ SECTIONS
_end = .;
_param_start = .;
- .ResetVector.text 0xfe000020 :
+ .ResetVector.text XCHAL_RESET_VECTOR_VADDR :
{
*(.ResetVector.text)
}
diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile
index 74d15d08077..872029b8443 100644
--- a/arch/xtensa/boot/boot-redboot/Makefile
+++ b/arch/xtensa/boot/boot-redboot/Makefile
@@ -22,7 +22,7 @@ LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
zImage: vmlinux $(OBJS) $(LIBS)
- $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
+ $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
vmlinux vmlinux.tmp
gzip -vf9 vmlinux.tmp
$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
diff --git a/arch/xtensa/boot/boot-redboot/boot.ld b/arch/xtensa/boot/boot-redboot/boot.ld
index 65b726410e8..774db20d11f 100644
--- a/arch/xtensa/boot/boot-redboot/boot.ld
+++ b/arch/xtensa/boot/boot-redboot/boot.ld
@@ -2,7 +2,7 @@ OUTPUT_ARCH(xtensa)
SECTIONS
{
- .start 0xD0200000 : { *(.start) }
+ .start 0xD1000000 : { *(.start) }
.text :
{
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
index d5ffe7b6443..ef63adadf7f 100644
--- a/arch/xtensa/kernel/asm-offsets.c
+++ b/arch/xtensa/kernel/asm-offsets.c
@@ -21,7 +21,6 @@
#include <linux/mm.h>
#include <asm/ptrace.h>
-#include <asm/processor.h>
#include <asm/uaccess.h>
#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -64,6 +63,8 @@ int main(void)
DEFINE(PT_SIZE, sizeof(struct pt_regs));
DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS]));
DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS]));
+ DEFINE(PT_XTREGS_OPT, offsetof(struct pt_regs, xtregs_opt));
+ DEFINE(XTREGS_OPT_SIZE, sizeof(xtregs_opt_t));
/* struct task_struct */
DEFINE(TASK_PTRACE, offsetof (struct task_struct, ptrace));
@@ -77,7 +78,19 @@ int main(void)
/* struct thread_info (offset from start_struct) */
DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
- DEFINE(THREAD_CP_SAVE, offsetof (struct task_struct, thread.cp_save));
+ DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable));
+#if XTENSA_HAVE_COPROCESSORS
+ DEFINE(THREAD_XTREGS_CP0, offsetof (struct thread_info, xtregs_cp));
+ DEFINE(THREAD_XTREGS_CP1, offsetof (struct thread_info, xtregs_cp));
+ DEFINE(THREAD_XTREGS_CP2, offsetof (struct thread_info, xtregs_cp));
+ DEFINE(THREAD_XTREGS_CP3, offsetof (struct thread_info, xtregs_cp));
+ DEFINE(THREAD_XTREGS_CP4, offsetof (struct thread_info, xtregs_cp));
+ DEFINE(THREAD_XTREGS_CP5, offsetof (struct thread_info, xtregs_cp));
+ DEFINE(THREAD_XTREGS_CP6, offsetof (struct thread_info, xtregs_cp));
+ DEFINE(THREAD_XTREGS_CP7, offsetof (struct thread_info, xtregs_cp));
+#endif
+ DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user));
+ DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t));
DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds));
/* struct mm_struct */
diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S
index 01bcb9fcfcb..2bc1e145c0a 100644
--- a/arch/xtensa/kernel/coprocessor.S
+++ b/arch/xtensa/kernel/coprocessor.S
@@ -8,193 +8,328 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2003 - 2005 Tensilica Inc.
- *
- * Marc Gauthier <marc@tensilica.com> <marc@alumni.uwaterloo.ca>
+ * Copyright (C) 2003 - 2007 Tensilica Inc.
*/
-/*
- * This module contains a table that describes the layout of the various
- * custom registers and states associated with each coprocessor, as well
- * as those not associated with any coprocessor ("extra state").
- * This table is included with core dumps and is available via the ptrace
- * interface, allowing the layout of such register/state information to
- * be modified in the kernel without affecting the debugger. Each
- * register or state is identified using a 32-bit "libdb target number"
- * assigned when the Xtensa processor is generated.
- */
#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
#include <asm/processor.h>
+#include <asm/coprocessor.h>
+#include <asm/thread_info.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/signal.h>
+#include <asm/tlbflush.h>
-#if XCHAL_HAVE_CP
+/*
+ * Entry condition:
+ *
+ * a0: trashed, original value saved on stack (PT_AREG0)
+ * a1: a1
+ * a2: new stack pointer, original in DEPC
+ * a3: dispatch table
+ * depc: a2, original value saved on stack (PT_DEPC)
+ * excsave_1: a3
+ *
+ * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+ * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+ */
-#define CP_LAST ((XCHAL_CP_MAX - 1) * COPROCESSOR_INFO_SIZE)
+/* IO protection is currently unsupported. */
-ENTRY(release_coprocessors)
+ENTRY(fast_io_protect)
+ wsr a0, EXCSAVE_1
+ movi a0, unrecoverable_exception
+ callx0 a0
- entry a1, 16
- # a2: task
- movi a3, 1 << XCHAL_CP_MAX # a3: coprocessor-bit
- movi a4, coprocessor_info+CP_LAST # a4: owner-table
- # a5: tmp
- movi a6, 0 # a6: 0
- rsil a7, LOCKLEVEL # a7: PS
+#if XTENSA_HAVE_COPROCESSORS
-1: /* Check if task is coprocessor owner of coprocessor[i]. */
+/*
+ * Macros for lazy context switch.
+ */
- l32i a5, a4, COPROCESSOR_INFO_OWNER
- srli a3, a3, 1
- beqz a3, 1f
- addi a4, a4, -8
- beq a2, a5, 1b
+#define SAVE_CP_REGS(x) \
+ .align 4; \
+ .Lsave_cp_regs_cp##x: \
+ .if XTENSA_HAVE_COPROCESSOR(x); \
+ xchal_cp##x##_store a2 a4 a5 a6 a7; \
+ .endif; \
+ jx a0
- /* Found an entry: Clear entry CPENABLE bit to disable CP. */
+#define SAVE_CP_REGS_TAB(x) \
+ .if XTENSA_HAVE_COPROCESSOR(x); \
+ .long .Lsave_cp_regs_cp##x - .Lsave_cp_regs_jump_table; \
+ .else; \
+ .long 0; \
+ .endif; \
+ .long THREAD_XTREGS_CP##x
- rsr a5, CPENABLE
- s32i a6, a4, COPROCESSOR_INFO_OWNER
- xor a5, a3, a5
- wsr a5, CPENABLE
- bnez a3, 1b
+#define LOAD_CP_REGS(x) \
+ .align 4; \
+ .Lload_cp_regs_cp##x: \
+ .if XTENSA_HAVE_COPROCESSOR(x); \
+ xchal_cp##x##_load a2 a4 a5 a6 a7; \
+ .endif; \
+ jx a0
-1: wsr a7, PS
- rsync
- retw
+#define LOAD_CP_REGS_TAB(x) \
+ .if XTENSA_HAVE_COPROCESSOR(x); \
+ .long .Lload_cp_regs_cp##x - .Lload_cp_regs_jump_table; \
+ .else; \
+ .long 0; \
+ .endif; \
+ .long THREAD_XTREGS_CP##x
+ SAVE_CP_REGS(0)
+ SAVE_CP_REGS(1)
+ SAVE_CP_REGS(2)
+ SAVE_CP_REGS(3)
+ SAVE_CP_REGS(4)
+ SAVE_CP_REGS(5)
+ SAVE_CP_REGS(6)
+ SAVE_CP_REGS(7)
-ENTRY(disable_coprocessor)
- entry sp, 16
- rsil a7, LOCKLEVEL
- rsr a3, CPENABLE
- movi a4, 1
- ssl a2
- sll a4, a4
- and a4, a3, a4
- xor a3, a3, a4
- wsr a3, CPENABLE
- wsr a7, PS
- rsync
- retw
+ LOAD_CP_REGS(0)
+ LOAD_CP_REGS(1)
+ LOAD_CP_REGS(2)
+ LOAD_CP_REGS(3)
+ LOAD_CP_REGS(4)
+ LOAD_CP_REGS(5)
+ LOAD_CP_REGS(6)
+ LOAD_CP_REGS(7)
-ENTRY(enable_coprocessor)
- entry sp, 16
- rsil a7, LOCKLEVEL
- rsr a3, CPENABLE
- movi a4, 1
- ssl a2
- sll a4, a4
- or a3, a3, a4
- wsr a3, CPENABLE
- wsr a7, PS
- rsync
- retw
+ .align 4
+.Lsave_cp_regs_jump_table:
+ SAVE_CP_REGS_TAB(0)
+ SAVE_CP_REGS_TAB(1)
+ SAVE_CP_REGS_TAB(2)
+ SAVE_CP_REGS_TAB(3)
+ SAVE_CP_REGS_TAB(4)
+ SAVE_CP_REGS_TAB(5)
+ SAVE_CP_REGS_TAB(6)
+ SAVE_CP_REGS_TAB(7)
+.Lload_cp_regs_jump_table:
+ LOAD_CP_REGS_TAB(0)
+ LOAD_CP_REGS_TAB(1)
+ LOAD_CP_REGS_TAB(2)
+ LOAD_CP_REGS_TAB(3)
+ LOAD_CP_REGS_TAB(4)
+ LOAD_CP_REGS_TAB(5)
+ LOAD_CP_REGS_TAB(6)
+ LOAD_CP_REGS_TAB(7)
-ENTRY(save_coprocessor_extra)
- entry sp, 16
- xchal_extra_store_funcbody
- retw
+/*
+ * coprocessor_save(buffer, index)
+ * a2 a3
+ * coprocessor_load(buffer, index)
+ * a2 a3
+ *
+ * Save or load coprocessor registers for coprocessor 'index'.
+ * The register values are saved to or loaded from them 'buffer' address.
+ *
+ * Note that these functions don't update the coprocessor_owner information!
+ *
+ */
-ENTRY(restore_coprocessor_extra)
- entry sp, 16
- xchal_extra_load_funcbody
+ENTRY(coprocessor_save)
+ entry a1, 32
+ s32i a0, a1, 0
+ movi a0, .Lsave_cp_regs_jump_table
+ addx8 a3, a3, a0
+ l32i a3, a3, 0
+ beqz a3, 1f
+ add a0, a0, a3
+ callx0 a0
+1: l32i a0, a1, 0
retw
-ENTRY(save_coprocessor_registers)
- entry sp, 16
- xchal_cpi_store_funcbody
+ENTRY(coprocessor_load)
+ entry a1, 32
+ s32i a0, a1, 0
+ movi a0, .Lload_cp_regs_jump_table
+ addx4 a3, a3, a0
+ l32i a3, a3, 0
+ beqz a3, 1f
+ add a0, a0, a3
+ callx0 a0
+1: l32i a0, a1, 0
retw
-ENTRY(restore_coprocessor_registers)
- entry sp, 16
- xchal_cpi_load_funcbody
+/*
+ * coprocessor_flush(struct task_info*, index)
+ * a2 a3
+ * coprocessor_restore(struct task_info*, index)
+ * a2 a3
+ *
+ * Save or load coprocessor registers for coprocessor 'index'.
+ * The register values are saved to or loaded from the coprocessor area
+ * inside the task_info structure.
+ *
+ * Note that these functions don't update the coprocessor_owner information!
+ *
+ */
+
+
+ENTRY(coprocessor_flush)
+ entry a1, 32
+ s32i a0, a1, 0
+ movi a0, .Lsave_cp_regs_jump_table
+ addx8 a3, a3, a0
+ l32i a4, a3, 4
+ l32i a3, a3, 0
+ add a2, a2, a4
+ beqz a3, 1f
+ add a0, a0, a3
+ callx0 a0
+1: l32i a0, a1, 0
retw
+ENTRY(coprocessor_restore)
+ entry a1, 32
+ s32i a0, a1, 0
+ movi a0, .Lload_cp_regs_jump_table
+ addx4 a3, a3, a0
+ l32i a4, a3, 4
+ l32i a3, a3, 0
+ add a2, a2, a4
+ beqz a3, 1f
+ add a0, a0, a3
+ callx0 a0
+1: l32i a0, a1, 0
+ retw
/*
- * The Xtensa compile-time HAL (core.h) XCHAL_*_SA_CONTENTS_LIBDB macros
- * describe the contents of coprocessor & extra save areas in terms of
- * undefined CONTENTS_LIBDB_{SREG,UREG,REGF} macros. We define these
- * latter macros here; they expand into a table of the format we want.
- * The general format is:
+ * Entry condition:
*
- * CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum,
- * bitmask, rsv2, rsv3)
- * CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum,
- * bitmask, rsv2, rsv3)
- * CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index,
- * numentries, contentsize, regname_base,
- * regfile_name, rsv2, rsv3)
+ * a0: trashed, original value saved on stack (PT_AREG0)
+ * a1: a1
+ * a2: new stack pointer, original in DEPC
+ * a3: dispatch table
+ * depc: a2, original value saved on stack (PT_DEPC)
+ * excsave_1: a3
*
- * For this table, we only care about the <libdbnum>, <offset> and <size>
- * fields.
+ * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+ * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
*/
-/* Map all XCHAL CONTENTS macros to the reg_entry asm macro defined below: */
-
-#define CONTENTS_LIBDB_SREG(libdbnum,offset,size,align,rsv1,name,sregnum, \
- bitmask, rsv2, rsv3) \
- reg_entry libdbnum, offset, size ;
-#define CONTENTS_LIBDB_UREG(libdbnum,offset,size,align,rsv1,name,uregnum, \
- bitmask, rsv2, rsv3) \
- reg_entry libdbnum, offset, size ;
-#define CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, \
- numentries, contentsize, regname_base, \
- regfile_name, rsv2, rsv3) \
- reg_entry libdbnum, offset, size ;
-
-/* A single table entry: */
- .macro reg_entry libdbnum, offset, size
- .ifne (__last_offset-(__last_group_offset+\offset))
- /* padding entry */
- .word (0xFC000000+__last_offset-(__last_group_offset+\offset))
- .endif
- .word \libdbnum /* actual entry */
- .set __last_offset, __last_group_offset+\offset+\size
- .endm /* reg_entry */
-
-
-/* Table entry that marks the beginning of a group (coprocessor or "extra"): */
- .macro reg_group cpnum, num_entries, align
- .set __last_group_offset, (__last_offset + \align- 1) & -\align
- .ifne \num_entries
- .word 0xFD000000+(\cpnum<<16)+\num_entries
- .endif
- .endm /* reg_group */
+ENTRY(fast_coprocessor_double)
+ wsr a0, EXCSAVE_1
+ movi a0, unrecoverable_exception
+ callx0 a0
-/*
- * Register info tables.
- */
- .section .rodata, "a"
- .globl _xtensa_reginfo_tables
- .globl _xtensa_reginfo_table_size
- .align 4
-_xtensa_reginfo_table_size:
- .word _xtensa_reginfo_table_end - _xtensa_reginfo_tables
-
-_xtensa_reginfo_tables:
- .set __last_offset, 0
- reg_group 0xFF, XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM, XCHAL_EXTRA_SA_ALIGN
- XCHAL_EXTRA_SA_CONTENTS_LIBDB
- reg_group 0, XCHAL_CP0_SA_CONTENTS_LIBDB_NUM, XCHAL_CP0_SA_ALIGN
- XCHAL_CP0_SA_CONTENTS_LIBDB
- reg_group 1, XCHAL_CP1_SA_CONTENTS_LIBDB_NUM, XCHAL_CP1_SA_ALIGN
- XCHAL_CP1_SA_CONTENTS_LIBDB
- reg_group 2, XCHAL_CP2_SA_CONTENTS_LIBDB_NUM, XCHAL_CP2_SA_ALIGN
- XCHAL_CP2_SA_CONTENTS_LIBDB
- reg_group 3, XCHAL_CP3_SA_CONTENTS_LIBDB_NUM, XCHAL_CP3_SA_ALIGN
- XCHAL_CP3_SA_CONTENTS_LIBDB
- reg_group 4, XCHAL_CP4_SA_CONTENTS_LIBDB_NUM, XCHAL_CP4_SA_ALIGN
- XCHAL_CP4_SA_CONTENTS_LIBDB
- reg_group 5, XCHAL_CP5_SA_CONTENTS_LIBDB_NUM, XCHAL_CP5_SA_ALIGN
- XCHAL_CP5_SA_CONTENTS_LIBDB
- reg_group 6, XCHAL_CP6_SA_CONTENTS_LIBDB_NUM, XCHAL_CP6_SA_ALIGN
- XCHAL_CP6_SA_CONTENTS_LIBDB
- reg_group 7, XCHAL_CP7_SA_CONTENTS_LIBDB_NUM, XCHAL_CP7_SA_ALIGN
- XCHAL_CP7_SA_CONTENTS_LIBDB
- .word 0xFC000000 /* invalid register number,marks end of table*/
-_xtensa_reginfo_table_end:
-#endif
+ENTRY(fast_coprocessor)
+
+ /* Save remaining registers a1-a3 and SAR */
+
+ xsr a3, EXCSAVE_1
+ s32i a3, a2, PT_AREG3
+ rsr a3, SAR
+ s32i a1, a2, PT_AREG1
+ s32i a3, a2, PT_SAR
+ mov a1, a2
+ rsr a2, DEPC
+ s32i a2, a1, PT_AREG2
+
+ /*
+ * The hal macros require up to 4 temporary registers. We use a3..a6.
+ */
+
+ s32i a4, a1, PT_AREG4
+ s32i a5, a1, PT_AREG5
+ s32i a6, a1, PT_AREG6
+
+ /* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */
+
+ rsr a3, EXCCAUSE
+ addi a3, a3, -EXCCAUSE_COPROCESSOR0_DISABLED
+
+ /* Set corresponding CPENABLE bit -> (sar:cp-index, a3: 1<<cp-index)*/
+
+ ssl a3 # SAR: 32 - coprocessor_number
+ movi a2, 1
+ rsr a0, CPENABLE
+ sll a2, a2
+ or a0, a0, a2
+ wsr a0, CPENABLE
+ rsync
+
+ /* Retrieve previous owner. (a3 still holds CP number) */
+
+ movi a0, coprocessor_owner # list of owners
+ addx4 a0, a3, a0 # entry for CP
+ l32i a4, a0, 0
+
+ beqz a4, 1f # skip 'save' if no previous owner
+
+ /* Disable coprocessor for previous owner. (a2 = 1 << CP number) */
+
+ l32i a5, a4, THREAD_CPENABLE
+ xor a5, a5, a2 # (1 << cp-id) still in a2
+ s32i a5, a4, THREAD_CPENABLE
+
+ /*
+ * Get context save area and 'call' save routine.
+ * (a4 still holds previous owner (thread_info), a3 CP number)
+ */
+
+ movi a5, .Lsave_cp_regs_jump_table
+ movi a0, 2f # a0: 'return' address
+ addx8 a3, a3, a5 # a3: coprocessor number
+ l32i a2, a3, 4 # a2: xtregs offset
+ l32i a3, a3, 0 # a3: jump offset
+ add a2, a2, a4
+ add a4, a3, a5 # a4: address of save routine
+ jx a4
+
+ /* Note that only a0 and a1 were preserved. */
+
+2: rsr a3, EXCCAUSE
+ addi a3, a3, -EXCCAUSE_COPROCESSOR0_DISABLED
+ movi a0, coprocessor_owner
+ addx4 a0, a3, a0
+
+ /* Set new 'owner' (a0 points to the CP owner, a3 contains the CP nr) */
+
+1: GET_THREAD_INFO (a4, a1)
+ s32i a4, a0, 0
+
+ /* Get context save area and 'call' load routine. */
+
+ movi a5, .Lload_cp_regs_jump_table
+ movi a0, 1f
+ addx8 a3, a3, a5
+ l32i a2, a3, 4 # a2: xtregs offset
+ l32i a3, a3, 0 # a3: jump offset
+ add a2, a2, a4
+ add a4, a3, a5
+ jx a4
+
+ /* Restore all registers and return from exception handler. */
+
+1: l32i a6, a1, PT_AREG6
+ l32i a5, a1, PT_AREG5
+ l32i a4, a1, PT_AREG4
+
+ l32i a0, a1, PT_SAR
+ l32i a3, a1, PT_AREG3
+ l32i a2, a1, PT_AREG2
+ wsr a0, SAR
+ l32i a0, a1, PT_AREG0
+ l32i a1, a1, PT_AREG1
+
+ rfe
+
+ .data
+ENTRY(coprocessor_owner)
+ .fill XCHAL_CP_MAX, 4, 0
+
+#endif /* XTENSA_HAVE_COPROCESSORS */
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 91a689eca43..dfd35dcc1cb 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -25,10 +25,10 @@
#include <asm/page.h>
#include <asm/signal.h>
#include <asm/tlbflush.h>
+#include <asm/variant/tie-asm.h>
/* Unimplemented features. */
-#undef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
#undef KERNEL_STACK_OVERFLOW_CHECK
#undef PREEMPTIBLE_KERNEL
#undef ALLOCA_EXCEPTION_IN_IRAM
@@ -214,19 +214,7 @@ _user_exception:
/* We are back to the original stack pointer (a1) */
-2:
-#if XCHAL_EXTRA_SA_SIZE
-
- /* For user exceptions, save the extra state into the user's TCB.
- * Note: We must assume that xchal_extra_store_funcbody destroys a2..a15
- */
-
- GET_CURRENT(a2,a1)
- addi a2, a2, THREAD_CP_SAVE
- xchal_extra_store_funcbody
-#endif
-
- /* Now, jump to the common exception handler. */
+2: /* Now, jump to the common exception handler. */
j common_exception
@@ -382,6 +370,10 @@ common_exception:
s32i a2, a1, PT_LBEG
s32i a3, a1, PT_LEND
+ /* Save optional registers. */
+
+ save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
+
/* Go to second-level dispatcher. Set up parameters to pass to the
* exception handler and call the exception handler.
*/
@@ -403,74 +395,49 @@ common_exception_return:
/* Jump if we are returning from kernel exceptions. */
1: l32i a3, a1, PT_PS
- _bbsi.l a3, PS_UM_BIT, 2f
- j kernel_exception_exit
+ _bbci.l a3, PS_UM_BIT, 4f
/* Specific to a user exception exit:
* We need to check some flags for signal handling and rescheduling,
* and have to restore WB and WS, extra states, and all registers
* in the register file that were in use in the user task.
- */
-
-2: wsr a3, PS /* disable interrupts */
-
- /* Check for signals (keep interrupts disabled while we read TI_FLAGS)
- * Note: PS.INTLEVEL = 0, PS.EXCM = 1
+ * Note that we don't disable interrupts here.
*/
GET_THREAD_INFO(a2,a1)
l32i a4, a2, TI_FLAGS
- /* Enable interrupts again.
- * Note: When we get here, we certainly have handled any interrupts.
- * (Hint: There is only one user exception frame on stack)
- */
-
- movi a3, 1 << PS_WOE_BIT
-
_bbsi.l a4, TIF_NEED_RESCHED, 3f
_bbci.l a4, TIF_SIGPENDING, 4f
-#ifndef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
l32i a4, a1, PT_DEPC
bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
-#endif
- /* Reenable interrupts and call do_signal() */
+ /* Call do_signal() */
- wsr a3, PS
movi a4, do_signal # int do_signal(struct pt_regs*, sigset_t*)
mov a6, a1
movi a7, 0
callx4 a4
j 1b
-3: /* Reenable interrupts and reschedule */
+3: /* Reschedule */
- wsr a3, PS
movi a4, schedule # void schedule (void)
callx4 a4
j 1b
- /* Restore the state of the task and return from the exception. */
-
-4: /* a2 holds GET_CURRENT(a2,a1) */
-
-#if XCHAL_EXTRA_SA_SIZE
+4: /* Restore optional registers. */
- /* For user exceptions, restore the extra state from the user's TCB. */
+ load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
- /* Note: a2 still contains GET_CURRENT(a2,a1) */
- addi a2, a2, THREAD_CP_SAVE
- xchal_extra_load_funcbody
+ wsr a3, PS /* disable interrupts */
- /* We must assume that xchal_extra_store_funcbody destroys
- * registers a2..a15. FIXME, this list can eventually be
- * reduced once real register requirements of the macro are
- * finalized. */
+ _bbci.l a3, PS_UM_BIT, kernel_exception_exit
-#endif /* XCHAL_EXTRA_SA_SIZE */
+user_exception_exit:
+ /* Restore the state of the task and return from the exception. */
/* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */
@@ -536,10 +503,6 @@ common_exception_return:
kernel_exception_exit:
- /* Disable interrupts (a3 holds PT_PS) */
-
- wsr a3, PS
-
#ifdef PREEMPTIBLE_KERNEL
#ifdef CONFIG_PREEMPT
@@ -618,6 +581,8 @@ kernel_exception_exit:
common_exception_exit:
+ /* Restore address registers. */
+
_bbsi.l a2, 1, 1f
l32i a4, a1, PT_AREG4
l32i a5, a1, PT_AREG5
@@ -1150,7 +1115,6 @@ CATCH
* excsave_1: a3
*
* Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler.
- * Note: We don't need to save a2 in depc (return value)
*/
ENTRY(fast_syscall_spill_registers)
@@ -1166,29 +1130,31 @@ ENTRY(fast_syscall_spill_registers)
rsr a0, SAR
xsr a3, EXCSAVE_1 # restore a3 and excsave_1
- s32i a0, a2, PT_AREG4 # store SAR to PT_AREG4
s32i a3, a2, PT_AREG3
+ s32i a4, a2, PT_AREG4
+ s32i a0, a2, PT_AREG5 # store SAR to PT_AREG5
/* The spill routine might clobber a7, a11, and a15. */
- s32i a7, a2, PT_AREG5
- s32i a11, a2, PT_AREG6
- s32i a15, a2, PT_AREG7
+ s32i a7, a2, PT_AREG7
+ s32i a11, a2, PT_AREG11
+ s32i a15, a2, PT_AREG15
- call0 _spill_registers # destroys a3, DEPC, and SAR
+ call0 _spill_registers # destroys a3, a4, and SAR
/* Advance PC, restore registers and SAR, and return from exception. */
- l32i a3, a2, PT_AREG4
+ l32i a3, a2, PT_AREG5
+ l32i a4, a2, PT_AREG4
l32i a0, a2, PT_AREG0
wsr a3, SAR
l32i a3, a2, PT_AREG3
/* Restore clobbered registers. */
- l32i a7, a2, PT_AREG5
- l32i a11, a2, PT_AREG6
- l32i a15, a2, PT_AREG7
+ l32i a7, a2, PT_AREG7
+ l32i a11, a2, PT_AREG11
+ l32i a15, a2, PT_AREG15
movi a2, 0
rfe
@@ -1247,16 +1213,6 @@ fast_syscall_spill_registers_fixup:
* Note: This frame might be the same as above.
*/
-#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
- /* Restore registers we precautiously saved.
- * We have the value of the 'right' a3
- */
-
- l32i a7, a2, PT_AREG5
- l32i a11, a2, PT_AREG6
- l32i a15, a2, PT_AREG7
-#endif
-
/* Setup stack pointer. */
addi a2, a2, -PT_USER_SIZE
@@ -1271,9 +1227,9 @@ fast_syscall_spill_registers_fixup:
movi a3, exc_table
rsr a0, EXCCAUSE
- addx4 a0, a0, a3 # find entry in table
- l32i a0, a0, EXC_TABLE_FAST_USER # load handler
- jx a0
+ addx4 a0, a0, a3 # find entry in table
+ l32i a0, a0, EXC_TABLE_FAST_USER # load handler
+ jx a0
fast_syscall_spill_registers_fixup_return:
@@ -1290,14 +1246,6 @@ fast_syscall_spill_registers_fixup_return:
s32i a2, a3, EXC_TABLE_PARAM
l32i a2, a3, EXC_TABLE_KSTK
-#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
- /* Save registers again that might be clobbered. */
-
- s32i a7, a2, PT_AREG5
- s32i a11, a2, PT_AREG6
- s32i a15, a2, PT_AREG7
-#endif
-
/* Load WB at the time the exception occurred. */
rsr a3, SAR # WB is still in SAR
@@ -1319,7 +1267,7 @@ fast_syscall_spill_registers_fixup_return:
* This is not a real function. The following conditions must be met:
*
* - must be called with call0.
- * - uses DEPC, a3 and SAR.
+ * - uses a3, a4 and SAR.
* - the last 'valid' register of each frame are clobbered.
* - the caller must have registered a fixup handler
* (or be inside a critical section)
@@ -1331,41 +1279,39 @@ ENTRY(_spill_registers)
/*
* Rotate ws so that the current windowbase is at bit 0.
* Assume ws = xxxwww1yy (www1 current window frame).
- * Rotate ws right so that a2 = yyxxxwww1.
+ * Rotate ws right so that a4 = yyxxxwww1.
*/
- wsr a2, DEPC # preserve a2
- rsr a2, WINDOWBASE
- rsr a3, WINDOWSTART
- ssr a2 # holds WB
- slli a2, a3, WSBITS
- or a3, a3, a2 # a2 = xxxwww1yyxxxwww1yy
- srl a3, a3
+ rsr a4, WINDOWBASE
+ rsr a3, WINDOWSTART # a3 = xxxwww1yy
+ ssr a4 # holds WB
+ slli a4, a3, WSBITS
+ or a3, a3, a4 # a3 = xxxwww1yyxxxwww1yy
+ srl a3, a3 # a3 = 00xxxwww1yyxxxwww1
/* We are done if there are no more than the current register frame. */
- extui a3, a3, 1, WSBITS-2 # a3 = 0yyxxxwww
- movi a2, (1 << (WSBITS-1))
+ extui a3, a3, 1, WSBITS-1 # a3 = 0yyxxxwww
+ movi a4, (1 << (WSBITS-1))
_beqz a3, .Lnospill # only one active frame? jump
/* We want 1 at the top, so that we return to the current windowbase */
- or a3, a3, a2 # 1yyxxxwww
+ or a3, a3, a4 # 1yyxxxwww
/* Skip empty frames - get 'oldest' WINDOWSTART-bit. */
wsr a3, WINDOWSTART # save shifted windowstart
- neg a2, a3
- and a3, a2, a3 # first bit set from right: 000010000
+ neg a4, a3
+ and a3, a4, a3 # first bit set from right: 000010000
- ffs_ws a2, a3 # a2: shifts to skip empty frames
+ ffs_ws a4, a3 # a4: shifts to skip empty frames
movi a3, WSBITS
- sub a2, a3, a2 # WSBITS-a2:number of 0-bits from right
- ssr a2 # save in SAR for later.
+ sub a4, a3, a4 # WSBITS-a4:number of 0-bits from right
+ ssr a4 # save in SAR for later.
rsr a3, WINDOWBASE
- add a3, a3, a2
- rsr a2, DEPC # restore a2
+ add a3, a3, a4
wsr a3, WINDOWBASE
rsync
@@ -1394,6 +1340,9 @@ ENTRY(_spill_registers)
l32e a4, a1, -16
j .Lc12c
+.Lnospill:
+ ret
+
.Lloop: _bbsi.l a3, 1, .Lc4
_bbci.l a3, 2, .Lc12
@@ -1419,9 +1368,7 @@ ENTRY(_spill_registers)
movi a3, 1
sll a3, a3
wsr a3, WINDOWSTART
-
-.Lnospill:
- jx a0
+ ret
.Lc4: s32e a4, a9, -16
s32e a5, a9, -12
@@ -1830,154 +1777,6 @@ ENTRY(fast_store_prohibited)
1: j _user_exception
-#if XCHAL_EXTRA_SA_SIZE
-
-#warning fast_coprocessor untested
-
-/*
- * Entry condition:
- *
- * a0: trashed, original value saved on stack (PT_AREG0)
- * a1: a1
- * a2: new stack pointer, original in DEPC
- * a3: dispatch table
- * depc: a2, original value saved on stack (PT_DEPC)
- * excsave_1: a3
- *
- * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
- * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
- */
-
-ENTRY(fast_coprocessor_double)
- wsr a0, EXCSAVE_1
- movi a0, unrecoverable_exception
- callx0 a0
-
-ENTRY(fast_coprocessor)
-
- /* Fatal if we are in a double exception. */
-
- l32i a0, a2, PT_DEPC
- _bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_coprocessor_double
-
- /* Save some registers a1, a3, a4, SAR */
-
- xsr a3, EXCSAVE_1
- s32i a3, a2, PT_AREG3
- rsr a3, SAR
- s32i a4, a2, PT_AREG4
- s32i a1, a2, PT_AREG1
- s32i a5, a1, PT_AREG5
- s32i a3, a2, PT_SAR
- mov a1, a2
-
- /* Currently, the HAL macros only guarantee saving a0 and a1.
- * These can and will be refined in the future, but for now,
- * just save the remaining registers of a2...a15.
- */
- s32i a6, a1, PT_AREG6
- s32i a7, a1, PT_AREG7
- s32i a8, a1, PT_AREG8
- s32i a9, a1, PT_AREG9
- s32i a10, a1, PT_AREG10
- s32i a11, a1, PT_AREG11
- s32i a12, a1, PT_AREG12
- s32i a13, a1, PT_AREG13
- s32i a14, a1, PT_AREG14
- s32i a15, a1, PT_AREG15
-
- /* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */
-
- rsr a0, EXCCAUSE
- addi a3, a0, -XCHAL_EXCCAUSE_COPROCESSOR0_DISABLED
-
- /* Set corresponding CPENABLE bit */
-
- movi a4, 1
- ssl a3 # SAR: 32 - coprocessor_number
- rsr a5, CPENABLE
- sll a4, a4
- or a4, a5, a4
- wsr a4, CPENABLE
- rsync
- movi a5, coprocessor_info # list of owner and offset into cp_save
- addx8 a0, a4, a5 # entry for CP
-
- bne a4, a5, .Lload # bit wasn't set before, cp not in use
-
- /* Now compare the current task with the owner of the coprocessor.
- * If they are the same, there is no reason to save or restore any
- * coprocessor state. Having already enabled the coprocessor,
- * branch ahead to return.
- */
- GET_CURRENT(a5,a1)
- l32i a4, a0, COPROCESSOR_INFO_OWNER # a4: current owner for this CP
- beq a4, a5, .Ldone
-
- /* Find location to dump current coprocessor state:
- * task_struct->task_cp_save_offset + coprocessor_offset[coprocessor]
- *
- * Note: a0 pointer to the entry in the coprocessor owner table,
- * a3 coprocessor number,
- * a4 current owner of coprocessor.
- */
- l32i a5, a0, COPROCESSOR_INFO_OFFSET
- addi a2, a4, THREAD_CP_SAVE
- add a2, a2, a5
-
- /* Store current coprocessor states. (a5 still has CP number) */
-
- xchal_cpi_store_funcbody
-
- /* The macro might have destroyed a3 (coprocessor number), but
- * SAR still has 32 - coprocessor_number!
- */
- movi a3, 32
- rsr a4, SAR
- sub a3, a3, a4
-
-.Lload: /* A new task now owns the corpocessors. Save its TCB pointer into
- * the coprocessor owner table.
- *
- * Note: a0 pointer to the entry in the coprocessor owner table,
- * a3 coprocessor number.
- */
- GET_CURRENT(a4,a1)
- s32i a4, a0, 0
-
- /* Find location from where to restore the current coprocessor state.*/
-
- l32i a5, a0, COPROCESSOR_INFO_OFFSET
- addi a2, a4, THREAD_CP_SAVE
- add a2, a2, a4
-
- xchal_cpi_load_funcbody
-
- /* We must assume that the xchal_cpi_store_funcbody macro destroyed
- * registers a2..a15.
- */
-
-.Ldone: l32i a15, a1, PT_AREG15
- l32i a14, a1, PT_AREG14
- l32i a13, a1, PT_AREG13
- l32i a12, a1, PT_AREG12
- l32i a11, a1, PT_AREG11
- l32i a10, a1, PT_AREG10
- l32i a9, a1, PT_AREG9
- l32i a8, a1, PT_AREG8
- l32i a7, a1, PT_AREG7
- l32i a6, a1, PT_AREG6
- l32i a5, a1, PT_AREG5
- l32i a4, a1, PT_AREG4
- l32i a3, a1, PT_AREG3
- l32i a2, a1, PT_AREG2
- l32i a0, a1, PT_AREG0
- l32i a1, a1, PT_AREG1
-
- rfe
-
-#endif /* XCHAL_EXTRA_SA_SIZE */
-
/*
* System Calls.
*
@@ -2086,20 +1885,36 @@ ENTRY(_switch_to)
entry a1, 16
- mov a4, a3 # preserve a3
+ mov a12, a2 # preserve 'prev' (a2)
+ mov a13, a3 # and 'next' (a3)
+
+ l32i a4, a2, TASK_THREAD_INFO
+ l32i a5, a3, TASK_THREAD_INFO
+
+ save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
- s32i a0, a2, THREAD_RA # save return address
- s32i a1, a2, THREAD_SP # save stack pointer
+ s32i a0, a12, THREAD_RA # save return address
+ s32i a1, a12, THREAD_SP # save stack pointer
- /* Disable ints while we manipulate the stack pointer; spill regs. */
+ /* Disable ints while we manipulate the stack pointer. */
- movi a5, (1 << PS_EXCM_BIT) | LOCKLEVEL
- xsr a5, PS
+ movi a14, (1 << PS_EXCM_BIT) | LOCKLEVEL
+ xsr a14, PS
rsr a3, EXCSAVE_1
rsync
s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */
- call0 _spill_registers
+ /* Switch CPENABLE */
+
+#if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
+ l32i a3, a5, THREAD_CPENABLE
+ xsr a3, CPENABLE
+ s32i a3, a4, THREAD_CPENABLE
+#endif
+
+ /* Flush register file. */
+
+ call0 _spill_registers # destroys a3, a4, and SAR
/* Set kernel stack (and leave critical section)
* Note: It's save to set it here. The stack will not be overwritten
@@ -2107,19 +1922,21 @@ ENTRY(_switch_to)
* we return from kernel space.
*/
- l32i a0, a4, TASK_THREAD_INFO
rsr a3, EXCSAVE_1 # exc_table
- movi a1, 0
- addi a0, a0, PT_REGS_OFFSET
- s32i a1, a3, EXC_TABLE_FIXUP
- s32i a0, a3, EXC_TABLE_KSTK
+ movi a6, 0
+ addi a7, a5, PT_REGS_OFFSET
+ s32i a6, a3, EXC_TABLE_FIXUP
+ s32i a7, a3, EXC_TABLE_KSTK
/* restore context of the task that 'next' addresses */
- l32i a0, a4, THREAD_RA /* restore return address */
- l32i a1, a4, THREAD_SP /* restore stack pointer */
+ l32i a0, a13, THREAD_RA # restore return address
+ l32i a1, a13, THREAD_SP # restore stack pointer
+
+ load_xtregs_user a5 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
- wsr a5, PS
+ wsr a14, PS
+ mov a2, a12 # return 'prev'
rsync
retw
diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c
index ddf14dcf2ad..3981a466c77 100644
--- a/arch/xtensa/kernel/module.c
+++ b/arch/xtensa/kernel/module.c
@@ -28,7 +28,7 @@ void *module_alloc(unsigned long size)
{
if (size == 0)
return NULL;
- return vmalloc(size);
+ return vmalloc_exec(size);
}
void module_free(struct module *mod, void *module_region)
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index f53d7bd9dfb..9185597eb6a 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -52,6 +52,55 @@ void (*pm_power_off)(void) = NULL;
EXPORT_SYMBOL(pm_power_off);
+#if XTENSA_HAVE_COPROCESSORS
+
+void coprocessor_release_all(struct thread_info *ti)
+{
+ unsigned long cpenable;
+ int i;
+
+ /* Make sure we don't switch tasks during this operation. */
+
+ preempt_disable();
+
+ /* Walk through all cp owners and release it for the requested one. */
+
+ cpenable = ti->cpenable;
+
+ for (i = 0; i < XCHAL_CP_MAX; i++) {
+ if (coprocessor_owner[i] == ti) {
+ coprocessor_owner[i] = 0;
+ cpenable &= ~(1 << i);
+ }
+ }
+
+ ti->cpenable = cpenable;
+ coprocessor_clear_cpenable();
+
+ preempt_enable();
+}
+
+void coprocessor_flush_all(struct thread_info *ti)
+{
+ unsigned long cpenable;
+ int i;
+
+ preempt_disable();
+
+ cpenable = ti->cpenable;
+
+ for (i = 0; i < XCHAL_CP_MAX; i++) {
+ if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti)
+ coprocessor_flush(ti, i);
+ cpenable >>= 1;
+ }
+
+ preempt_enable();
+}
+
+#endif
+
+
/*
* Powermanagement idle function, if any is provided by the platform.
*/
@@ -71,15 +120,36 @@ void cpu_idle(void)
}
/*
- * Free current thread data structures etc..
+ * This is called when the thread calls exit().
*/
-
void exit_thread(void)
{
+#if XTENSA_HAVE_COPROCESSORS
+ coprocessor_release_all(current_thread_info());
+#endif
}
+/*
+ * Flush thread state. This is called when a thread does an execve()
+ * Note that we flush coprocessor registers for the case execve fails.
+ */
void flush_thread(void)
{
+#if XTENSA_HAVE_COPROCESSORS
+ struct thread_info *ti = current_thread_info();
+ coprocessor_flush_all(ti);
+ coprocessor_release_all(ti);
+#endif
+}
+
+/*
+ * This is called before the thread is copied.
+ */
+void prepare_to_copy(struct task_struct *tsk)
+{
+#if XTENSA_HAVE_COPROCESSORS
+ coprocessor_flush_all(task_thread_info(tsk));
+#endif
}
/*
@@ -107,6 +177,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs *childregs;
+ struct thread_info *ti;
unsigned long tos;
int user_mode = user_mode(regs);
@@ -128,13 +199,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
p->set_child_tid = p->clear_child_tid = NULL;
p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1);
p->thread.sp = (unsigned long)childregs;
+
if (user_mode(regs)) {
int len = childregs->wmask & ~0xf;
childregs->areg[1] = usp;
memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4],
&regs->areg[XCHAL_NUM_AREGS - len/4], len);
-
+// FIXME: we need to set THREADPTR in thread_info...
if (clone_flags & CLONE_SETTLS)
childregs->areg[2] = childregs->areg[6];
@@ -142,6 +214,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
/* In kernel space, we start a new thread with a new stack. */
childregs->wmask = 1;
}
+
+#if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
+ ti = task_thread_info(p);
+ ti->cpenable = 0;
+#endif
+
return 0;
}
@@ -179,10 +257,6 @@ unsigned long get_wchan(struct task_struct *p)
}
/*
- * do_copy_regs() gathers information from 'struct pt_regs' and
- * 'current->thread.areg[]' to fill in the xtensa_gregset_t
- * structure.
- *
* xtensa_gregset_t and 'struct pt_regs' are vastly different formats
* of processor registers. Besides different ordering,
* xtensa_gregset_t contains non-live register information that
@@ -191,18 +265,19 @@ unsigned long get_wchan(struct task_struct *p)
*
*/
-void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
- struct task_struct *tsk)
+void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs)
{
- int i, n, wb_offset;
+ unsigned long wb, ws, wm;
+ int live, last;
- elfregs->xchal_config_id0 = XCHAL_HW_CONFIGID0;
- elfregs->xchal_config_id1 = XCHAL_HW_CONFIGID1;
+ wb = regs->windowbase;
+ ws = regs->windowstart;
+ wm = regs->wmask;
+ ws = ((ws >> wb) | (ws << (WSBITS - wb))) & ((1 << WSBITS) - 1);
- __asm__ __volatile__ ("rsr %0, 176\n" : "=a" (i));
- elfregs->cpux = i;
- __asm__ __volatile__ ("rsr %0, 208\n" : "=a" (i));
- elfregs->cpuy = i;
+ /* Don't leak any random bits. */
+
+ memset(elfregs, 0, sizeof (elfregs));
/* Note: PS.EXCM is not set while user task is running; its
* being set in regs->ps is for exception handling convenience.
@@ -210,204 +285,22 @@ void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
elfregs->pc = regs->pc;
elfregs->ps = (regs->ps & ~(1 << PS_EXCM_BIT));
- elfregs->exccause = regs->exccause;
- elfregs->excvaddr = regs->excvaddr;
- elfregs->windowbase = regs->windowbase;
- elfregs->windowstart = regs->windowstart;
elfregs->lbeg = regs->lbeg;
elfregs->lend = regs->lend;
elfregs->lcount = regs->lcount;
elfregs->sar = regs->sar;
- elfregs->syscall = regs->syscall;
-
- /* Copy register file.
- * The layout looks like this:
- *
- * | a0 ... a15 | Z ... Z | arX ... arY |
- * current window unused saved frames
- */
-
- memset (elfregs->ar, 0, sizeof(elfregs->ar));
+ elfregs->windowstart = ws;
- wb_offset = regs->windowbase * 4;
- n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
-
- for (i = 0; i < n; i++)
- elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
-
- n = (regs->wmask >> 4) * 4;
-
- for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
- elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
+ live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
+ last = XCHAL_NUM_AREGS - (wm >> 4) * 4;
+ memcpy(elfregs->a, regs->areg, live * 4);
+ memcpy(elfregs->a + last, regs->areg + last, (wm >> 4) * 16);
}
-void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs)
+int dump_fpu(void)
{
- do_copy_regs ((xtensa_gregset_t *)elfregs, regs, current);
-}
-
-
-/* The inverse of do_copy_regs(). No error or sanity checking. */
-
-void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
- struct task_struct *tsk)
-{
- int i, n, wb_offset;
-
- /* Note: PS.EXCM is not set while user task is running; it
- * needs to be set in regs->ps is for exception handling convenience.
- */
-
- regs->pc = elfregs->pc;
- regs->ps = (elfregs->ps | (1 << PS_EXCM_BIT));
- regs->exccause = elfregs->exccause;
- regs->excvaddr = elfregs->excvaddr;
- regs->windowbase = elfregs->windowbase;
- regs->windowstart = elfregs->windowstart;
- regs->lbeg = elfregs->lbeg;
- regs->lend = elfregs->lend;
- regs->lcount = elfregs->lcount;
- regs->sar = elfregs->sar;
- regs->syscall = elfregs->syscall;
-
- /* Clear everything. */
-
- memset (regs->areg, 0, sizeof(regs->areg));
-
- /* Copy regs from live window frame. */
-
- wb_offset = regs->windowbase * 4;
- n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
-
- for (i = 0; i < n; i++)
- regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
-
- n = (regs->wmask >> 4) * 4;
-
- for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
- regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
-}
-
-/*
- * do_save_fpregs() gathers information from 'struct pt_regs' and
- * 'current->thread' to fill in the elf_fpregset_t structure.
- *
- * Core files and ptrace use elf_fpregset_t.
- */
-
-void do_save_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs,
- struct task_struct *tsk)
-{
-#if XCHAL_HAVE_CP
-
- extern unsigned char _xtensa_reginfo_tables[];
- extern unsigned _xtensa_reginfo_table_size;
- int i;
- unsigned long flags;
-
- /* Before dumping coprocessor state from memory,
- * ensure any live coprocessor contents for this
- * task are first saved to memory:
- */
- local_irq_save(flags);
-
- for (i = 0; i < XCHAL_CP_MAX; i++) {
- if (tsk == coprocessor_info[i].owner) {
- enable_coprocessor(i);
- save_coprocessor_registers(
- tsk->thread.cp_save+coprocessor_info[i].offset,i);
- disable_coprocessor(i);
- }
- }
-
- local_irq_restore(flags);
-
- /* Now dump coprocessor & extra state: */
- memcpy((unsigned char*)fpregs,
- _xtensa_reginfo_tables, _xtensa_reginfo_table_size);
- memcpy((unsigned char*)fpregs + _xtensa_reginfo_table_size,
- tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
-#endif
-}
-
-/*
- * The inverse of do_save_fpregs().
- * Copies coprocessor and extra state from fpregs into regs and tsk->thread.
- * Returns 0 on success, non-zero if layout doesn't match.
- */
-
-int do_restore_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs,
- struct task_struct *tsk)
-{
-#if XCHAL_HAVE_CP
-
- extern unsigned char _xtensa_reginfo_tables[];
- extern unsigned _xtensa_reginfo_table_size;
- int i;
- unsigned long flags;
-
- /* Make sure save area layouts match.
- * FIXME: in the future we could allow restoring from
- * a different layout of the same registers, by comparing
- * fpregs' table with _xtensa_reginfo_tables and matching
- * entries and copying registers one at a time.
- * Not too sure yet whether that's very useful.
- */
-
- if( memcmp((unsigned char*)fpregs,
- _xtensa_reginfo_tables, _xtensa_reginfo_table_size) ) {
- return -1;
- }
-
- /* Before restoring coprocessor state from memory,
- * ensure any live coprocessor contents for this
- * task are first invalidated.
- */
-
- local_irq_save(flags);
-
- for (i = 0; i < XCHAL_CP_MAX; i++) {
- if (tsk == coprocessor_info[i].owner) {
- enable_coprocessor(i);
- save_coprocessor_registers(
- tsk->thread.cp_save+coprocessor_info[i].offset,i);
- coprocessor_info[i].owner = 0;
- disable_coprocessor(i);
- }
- }
-
- local_irq_restore(flags);
-
- /* Now restore coprocessor & extra state: */
-
- memcpy(tsk->thread.cp_save,
- (unsigned char*)fpregs + _xtensa_reginfo_table_size,
- XTENSA_CP_EXTRA_SIZE);
-#endif
return 0;
}
-/*
- * Fill in the CP structure for a core dump for a particular task.
- */
-
-int
-dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r)
-{
- return 0; /* no coprocessors active on this processor */
-}
-
-/*
- * Fill in the CP structure for a core dump.
- * This includes any FPU coprocessor.
- * Here, we dump all coprocessors, and other ("extra") custom state.
- *
- * This function is called by elf_core_dump() in fs/binfmt_elf.c
- * (in which case 'regs' comes from calls to do_coredump, see signals.c).
- */
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
-{
- return dump_task_fpu(regs, current, r);
-}
asmlinkage
long xtensa_clone(unsigned long clone_flags, unsigned long newsp,
@@ -421,8 +314,8 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp,
}
/*
- * * xtensa_execve() executes a new program.
- * */
+ * xtensa_execve() executes a new program.
+ */
asmlinkage
long xtensa_execve(char __user *name, char __user * __user *argv,
@@ -437,7 +330,6 @@ long xtensa_execve(char __user *name, char __user * __user *argv,
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- // FIXME: release coprocessor??
error = do_execve(filename, argv, envp, regs);
if (error == 0) {
task_lock(current);
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 5533c7850d5..9486882ef0a 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2007 Tensilica Inc.
*
* Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
* Chris Zankel <chris@zankel.net>
@@ -28,14 +28,10 @@
#include <asm/uaccess.h>
#include <asm/ptrace.h>
#include <asm/elf.h>
-
-#define TEST_KERNEL // verify kernel operations FIXME: remove
-
+#include <asm/coprocessor.h>
/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure single step bits etc are not set.
+ * Called by kernel/ptrace.c when detaching to disable single stepping.
*/
void ptrace_disable(struct task_struct *child)
@@ -43,136 +39,237 @@ void ptrace_disable(struct task_struct *child)
/* Nothing to do.. */
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+int ptrace_getregs(struct task_struct *child, void __user *uregs)
{
- int ret = -EPERM;
+ struct pt_regs *regs = task_pt_regs(child);
+ xtensa_gregset_t __user *gregset = uregs;
+ unsigned long wm = regs->wmask;
+ unsigned long wb = regs->windowbase;
+ int live, i;
+
+ if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t)))
+ return -EIO;
+
+ __put_user(regs->pc, &gregset->pc);
+ __put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps);
+ __put_user(regs->lbeg, &gregset->lbeg);
+ __put_user(regs->lend, &gregset->lend);
+ __put_user(regs->lcount, &gregset->lcount);
+ __put_user(regs->windowstart, &gregset->windowstart);
+ __put_user(regs->windowbase, &gregset->windowbase);
+
+ live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
+
+ for (i = 0; i < live; i++)
+ __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS));
+ for (i = XCHAL_NUM_AREGS - (wm >> 4) * 4; i < XCHAL_NUM_AREGS; i++)
+ __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS));
+
+ return 0;
+}
- switch (request) {
- case PTRACE_PEEKTEXT: /* read word at location addr. */
- case PTRACE_PEEKDATA:
- ret = generic_ptrace_peekdata(child, addr, data);
- goto out;
+int ptrace_setregs(struct task_struct *child, void __user *uregs)
+{
+ struct pt_regs *regs = task_pt_regs(child);
+ xtensa_gregset_t *gregset = uregs;
+ const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK;
+ unsigned long ps;
+ unsigned long wb;
- /* Read the word at location addr in the USER area. */
+ if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t)))
+ return -EIO;
- case PTRACE_PEEKUSR:
- {
- struct pt_regs *regs;
- unsigned long tmp;
+ __get_user(regs->pc, &gregset->pc);
+ __get_user(ps, &gregset->ps);
+ __get_user(regs->lbeg, &gregset->lbeg);
+ __get_user(regs->lend, &gregset->lend);
+ __get_user(regs->lcount, &gregset->lcount);
+ __get_user(regs->windowstart, &gregset->windowstart);
+ __get_user(wb, &gregset->windowbase);
+
+ regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT);
+
+ if (wb >= XCHAL_NUM_AREGS / 4)
+ return -EFAULT;
+
+ regs->windowbase = wb;
+
+ if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4,
+ gregset->a, wb * 16))
+ return -EFAULT;
+
+ if (__copy_from_user(regs->areg, gregset->a + wb*4, (WSBITS-wb) * 16))
+ return -EFAULT;
+
+ return 0;
+}
+
+
+int ptrace_getxregs(struct task_struct *child, void __user *uregs)
+{
+ struct pt_regs *regs = task_pt_regs(child);
+ struct thread_info *ti = task_thread_info(child);
+ elf_xtregs_t __user *xtregs = uregs;
+ int ret = 0;
+
+ if (!access_ok(VERIFY_WRITE, uregs, sizeof(elf_xtregs_t)))
+ return -EIO;
+
+#if XTENSA_HAVE_COPROCESSORS
+ /* Flush all coprocessor registers to memory. */
+ coprocessor_flush_all(ti);
+ ret |= __copy_to_user(&xtregs->cp0, &ti->xtregs_cp,
+ sizeof(xtregs_coprocessor_t));
+#endif
+ ret |= __copy_to_user(&xtregs->opt, &regs->xtregs_opt,
+ sizeof(xtregs->opt));
+ ret |= __copy_to_user(&xtregs->user,&ti->xtregs_user,
+ sizeof(xtregs->user));
+
+ return ret ? -EFAULT : 0;
+}
+
+int ptrace_setxregs(struct task_struct *child, void __user *uregs)
+{
+ struct thread_info *ti = task_thread_info(child);
+ struct pt_regs *regs = task_pt_regs(child);
+ elf_xtregs_t *xtregs = uregs;
+ int ret = 0;
+
+#if XTENSA_HAVE_COPROCESSORS
+ /* Flush all coprocessors before we overwrite them. */
+ coprocessor_flush_all(ti);
+ coprocessor_release_all(ti);
+
+ ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0,
+ sizeof(xtregs_coprocessor_t));
+#endif
+ ret |= __copy_from_user(&regs->xtregs_opt, &xtregs->opt,
+ sizeof(xtregs->opt));
+ ret |= __copy_from_user(&ti->xtregs_user, &xtregs->user,
+ sizeof(xtregs->user));
+
+ return ret ? -EFAULT : 0;
+}
+
+int ptrace_peekusr(struct task_struct *child, long regno, long __user *ret)
+{
+ struct pt_regs *regs;
+ unsigned long tmp;
- regs = task_pt_regs(child);
- tmp = 0; /* Default return value. */
+ regs = task_pt_regs(child);
+ tmp = 0; /* Default return value. */
- switch(addr) {
+ switch(regno) {
case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
- {
- int ar = addr - REG_AR_BASE - regs->windowbase * 4;
- ar &= (XCHAL_NUM_AREGS - 1);
- if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0)
- tmp = regs->areg[ar];
- else
- ret = -EIO;
+ tmp = regs->areg[regno - REG_AR_BASE];
break;
- }
+
case REG_A_BASE ... REG_A_BASE + 15:
- tmp = regs->areg[addr - REG_A_BASE];
+ tmp = regs->areg[regno - REG_A_BASE];
break;
+
case REG_PC:
tmp = regs->pc;
break;
+
case REG_PS:
/* Note: PS.EXCM is not set while user task is running;
* its being set in regs is for exception handling
* convenience. */
tmp = (regs->ps & ~(1 << PS_EXCM_BIT));
break;
+
case REG_WB:
- tmp = regs->windowbase;
- break;
+ break; /* tmp = 0 */
+
case REG_WS:
- tmp = regs->windowstart;
+ {
+ unsigned long wb = regs->windowbase;
+ unsigned long ws = regs->windowstart;
+ tmp = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<<WSBITS)-1);
break;
+ }
case REG_LBEG:
tmp = regs->lbeg;
break;
+
case REG_LEND:
tmp = regs->lend;
break;
+
case REG_LCOUNT:
tmp = regs->lcount;
break;
+
case REG_SAR:
tmp = regs->sar;
break;
- case REG_DEPC:
- tmp = regs->depc;
- break;
- case REG_EXCCAUSE:
- tmp = regs->exccause;
- break;
- case REG_EXCVADDR:
- tmp = regs->excvaddr;
- break;
+
case SYSCALL_NR:
tmp = regs->syscall;
break;
- default:
- tmp = 0;
- ret = -EIO;
- goto out;
- }
- ret = put_user(tmp, (unsigned long *) data);
- goto out;
- }
- case PTRACE_POKETEXT: /* write the word at location addr. */
- case PTRACE_POKEDATA:
- ret = generic_ptrace_pokedata(child, addr, data);
- goto out;
+ default:
+ return -EIO;
+ }
+ return put_user(tmp, ret);
+}
- case PTRACE_POKEUSR:
- {
- struct pt_regs *regs;
- regs = task_pt_regs(child);
+int ptrace_pokeusr(struct task_struct *child, long regno, long val)
+{
+ struct pt_regs *regs;
+ regs = task_pt_regs(child);
- switch (addr) {
+ switch (regno) {
case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
- {
- int ar = addr - REG_AR_BASE - regs->windowbase * 4;
- if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0)
- regs->areg[ar & (XCHAL_NUM_AREGS - 1)] = data;
- else
- ret = -EIO;
+ regs->areg[regno - REG_AR_BASE] = val;
break;
- }
+
case REG_A_BASE ... REG_A_BASE + 15:
- regs->areg[addr - REG_A_BASE] = data;
+ regs->areg[regno - REG_A_BASE] = val;
break;
+
case REG_PC:
- regs->pc = data;
+ regs->pc = val;
break;
+
case SYSCALL_NR:
- regs->syscall = data;
- break;
-#ifdef TEST_KERNEL
- case REG_WB:
- regs->windowbase = data;
- break;
- case REG_WS:
- regs->windowstart = data;
+ regs->syscall = val;
break;
-#endif
default:
- /* The rest are not allowed. */
- ret = -EIO;
- break;
- }
+ return -EIO;
+ }
+ return 0;
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+ int ret = -EPERM;
+
+ switch (request) {
+ case PTRACE_PEEKTEXT: /* read word at location addr. */
+ case PTRACE_PEEKDATA:
+ ret = generic_ptrace_peekdata(child, addr, data);
+ break;
+
+ case PTRACE_PEEKUSR: /* read register specified by addr. */
+ ret = ptrace_peekusr(child, addr, (void __user *) data);
+ break;
+
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ case PTRACE_POKEDATA:
+ ret = generic_ptrace_pokedata(child, addr, data);
+ break;
+
+ case PTRACE_POKEUSR: /* write register specified by addr. */
+ ret = ptrace_pokeusr(child, addr, data);
break;
- }
/* continue and stop at next (return from) syscall */
+
case PTRACE_SYSCALL:
case PTRACE_CONT: /* restart after signal. */
{
@@ -217,98 +314,26 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_GETREGS:
- {
- /* 'data' points to user memory in which to write.
- * Mainly due to the non-live register values, we
- * reformat the register values into something more
- * standard. For convenience, we use the handy
- * elf_gregset_t format. */
-
- xtensa_gregset_t format;
- struct pt_regs *regs = task_pt_regs(child);
-
- do_copy_regs (&format, regs, child);
-
- /* Now, copy to user space nice and easy... */
- ret = 0;
- if (copy_to_user((void *)data, &format, sizeof(elf_gregset_t)))
- ret = -EFAULT;
+ ret = ptrace_getregs(child, (void __user *) data);
break;
- }
case PTRACE_SETREGS:
- {
- /* 'data' points to user memory that contains the new
- * values in the elf_gregset_t format. */
-
- xtensa_gregset_t format;
- struct pt_regs *regs = task_pt_regs(child);
-
- if (copy_from_user(&format,(void *)data,sizeof(elf_gregset_t))){
- ret = -EFAULT;
- break;
- }
-
- /* FIXME: Perhaps we want some sanity checks on
- * these user-space values? See ARM version. Are
- * debuggers a security concern? */
-
- do_restore_regs (&format, regs, child);
-
- ret = 0;
- break;
- }
-
- case PTRACE_GETFPREGS:
- {
- /* 'data' points to user memory in which to write.
- * For convenience, we use the handy
- * elf_fpregset_t format. */
-
- elf_fpregset_t fpregs;
- struct pt_regs *regs = task_pt_regs(child);
-
- do_save_fpregs (&fpregs, regs, child);
-
- /* Now, copy to user space nice and easy... */
- ret = 0;
- if (copy_to_user((void *)data, &fpregs, sizeof(elf_fpregset_t)))
- ret = -EFAULT;
-
+ ret = ptrace_setregs(child, (void __user *) data);
break;
- }
-
- case PTRACE_SETFPREGS:
- {
- /* 'data' points to user memory that contains the new
- * values in the elf_fpregset_t format.
- */
- elf_fpregset_t fpregs;
- struct pt_regs *regs = task_pt_regs(child);
- ret = 0;
- if (copy_from_user(&fpregs, (void *)data, sizeof(elf_fpregset_t))) {
- ret = -EFAULT;
- break;
- }
-
- if (do_restore_fpregs (&fpregs, regs, child))
- ret = -EIO;
+ case PTRACE_GETXTREGS:
+ ret = ptrace_getxregs(child, (void __user *) data);
break;
- }
- case PTRACE_GETFPREGSIZE:
- /* 'data' points to 'unsigned long' set to the size
- * of elf_fpregset_t
- */
- ret = put_user(sizeof(elf_fpregset_t), (unsigned long *) data);
+ case PTRACE_SETXTREGS:
+ ret = ptrace_setxregs(child, (void __user *) data);
break;
default:
ret = ptrace_request(child, request, addr, data);
- goto out;
+ break;
}
- out:
+
return ret;
}
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index b80f2cb1b4f..5e6d75c9f92 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -60,11 +60,6 @@ struct ide_ops *ide_ops;
extern struct rtc_ops no_rtc_ops;
struct rtc_ops *rtc_ops;
-#ifdef CONFIG_PC_KEYB
-extern struct kbd_ops no_kbd_ops;
-struct kbd_ops *kbd_ops;
-#endif
-
#ifdef CONFIG_BLK_DEV_INITRD
extern void *initrd_start;
extern void *initrd_end;
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index 033aae0336d..f2220b5bdce 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -35,13 +35,17 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
extern struct task_struct *coproc_owners[];
-extern void release_all_cp (struct task_struct *);
-
struct rt_sigframe
{
struct siginfo info;
struct ucontext uc;
- cp_state_t cpstate;
+ struct {
+ xtregs_opt_t opt;
+ xtregs_user_t user;
+#if XTENSA_HAVE_COPROCESSORS
+ xtregs_coprocessor_t cp;
+#endif
+ } xtregs;
unsigned char retcode[6];
unsigned int window[4];
};
@@ -49,8 +53,6 @@ struct rt_sigframe
/*
* Flush register windows stored in pt_regs to stack.
* Returns 1 for errors.
- *
- * Note that windowbase, windowstart, and wmask are not updated!
*/
int
@@ -116,6 +118,9 @@ flush_window_regs_user(struct pt_regs *regs)
base += inc;
}
+ regs->wmask = 1;
+ regs->windowstart = 1 << wb;
+
return 0;
errout:
@@ -131,9 +136,10 @@ errout:
*/
static int
-setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate,
- struct pt_regs *regs, unsigned long mask)
+setup_sigcontext(struct rt_sigframe __user *frame, struct pt_regs *regs)
{
+ struct sigcontext __user *sc = &frame->uc.uc_mcontext;
+ struct thread_info *ti = current_thread_info();
int err = 0;
#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
@@ -147,23 +153,32 @@ setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate,
err |= flush_window_regs_user(regs);
err |= __copy_to_user (sc->sc_a, regs->areg, 16 * 4);
+ err |= __put_user(0, &sc->sc_xtregs);
- // err |= __copy_to_user (sc->sc_a, regs->areg, XCHAL_NUM_AREGS * 4)
+ if (err)
+ return err;
-#if XCHAL_HAVE_CP
-# error Coprocessors unsupported
- err |= save_cpextra(cpstate);
- err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate);
+#if XTENSA_HAVE_COPROCESSORS
+ coprocessor_flush_all(ti);
+ coprocessor_release_all(ti);
+ err |= __copy_to_user(&frame->xtregs.cp, &ti->xtregs_cp,
+ sizeof (frame->xtregs.cp));
#endif
- /* non-iBCS2 extensions.. */
- err |= __put_user(mask, &sc->oldmask);
+ err |= __copy_to_user(&frame->xtregs.opt, &regs->xtregs_opt,
+ sizeof (xtregs_opt_t));
+ err |= __copy_to_user(&frame->xtregs.user, &ti->xtregs_user,
+ sizeof (xtregs_user_t));
+
+ err |= __put_user(err ? NULL : &frame->xtregs, &sc->sc_xtregs);
return err;
}
static int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame)
{
+ struct sigcontext __user *sc = &frame->uc.uc_mcontext;
+ struct thread_info *ti = current_thread_info();
unsigned int err = 0;
unsigned long ps;
@@ -181,6 +196,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
regs->windowbase = 0;
regs->windowstart = 1;
+ regs->syscall = -1; /* disable syscall checks */
+
/* For PS, restore only PS.CALLINC.
* Assume that all other bits are either the same as for the signal
* handler, or the user mode value doesn't matter (e.g. PS.OWB).
@@ -196,8 +213,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
err |= __copy_from_user(regs->areg, sc->sc_a, 16 * 4);
-#if XCHAL_HAVE_CP
-# error Coprocessors unsupported
+ if (err)
+ return err;
+
/* The signal handler may have used coprocessors in which
* case they are still enabled. We disable them to force a
* reloading of the original task's CP state by the lazy
@@ -205,20 +223,20 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
* Also, we essentially discard any coprocessor state that the
* signal handler created. */
- if (!err) {
- struct task_struct *tsk = current;
- release_all_cp(tsk);
- err |= __copy_from_user(tsk->thread.cpextra, sc->sc_cpstate,
- XTENSA_CP_EXTRA_SIZE);
- }
+#if XTENSA_HAVE_COPROCESSORS
+ coprocessor_release_all(ti);
+ err |= __copy_from_user(&ti->xtregs_cp, &frame->xtregs.cp,
+ sizeof (frame->xtregs.cp));
#endif
+ err |= __copy_from_user(&ti->xtregs_user, &frame->xtregs.user,
+ sizeof (xtregs_user_t));
+ err |= __copy_from_user(&regs->xtregs_opt, &frame->xtregs.opt,
+ sizeof (xtregs_opt_t));
- regs->syscall = -1; /* disable syscall checks */
return err;
}
-
/*
* Do a signal return; undo the signal stack.
*/
@@ -247,7 +265,7 @@ asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3,
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
+ if (restore_sigcontext(regs, frame))
goto badframe;
ret = regs->areg[2];
@@ -360,18 +378,22 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(sas_ss_flags(regs->areg[1]),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
- err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate,
- regs, set->sig[0]);
+ err |= setup_sigcontext(frame, regs);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
- /* Create sys_rt_sigreturn syscall in stack frame */
+ if (ka->sa.sa_flags & SA_RESTORER) {
+ ra = (unsigned long)ka->sa.sa_restorer;
+ } else {
- err |= gen_return_code(frame->retcode);
+ /* Create sys_rt_sigreturn syscall in stack frame */
- if (err) {
- goto give_sigsegv;
+ err |= gen_return_code(frame->retcode);
+
+ if (err) {
+ goto give_sigsegv;
+ }
+ ra = (unsigned long) frame->retcode;
}
-
/*
* Create signal handler execution context.
@@ -385,7 +407,6 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up a stack frame for a call4
* Note: PS.CALLINC is set to one by start_thread
*/
- ra = (unsigned long) frame->retcode;
regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000;
regs->areg[6] = (unsigned long) signal;
regs->areg[7] = (unsigned long) &frame->info;
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 397bcd6ad08..c7a021d9f69 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -118,28 +118,28 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault },
{ EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault },
/* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
-#if (XCHAL_CP_MASK & 1)
+#if XTENSA_HAVE_COPROCESSOR(0)
COPROCESSOR(0),
#endif
-#if (XCHAL_CP_MASK & 2)
+#if XTENSA_HAVE_COPROCESSOR(1)
COPROCESSOR(1),
#endif
-#if (XCHAL_CP_MASK & 4)
+#if XTENSA_HAVE_COPROCESSOR(2)
COPROCESSOR(2),
#endif
-#if (XCHAL_CP_MASK & 8)
+#if XTENSA_HAVE_COPROCESSOR(3)
COPROCESSOR(3),
#endif
-#if (XCHAL_CP_MASK & 16)
+#if XTENSA_HAVE_COPROCESSOR(4)
COPROCESSOR(4),
#endif
-#if (XCHAL_CP_MASK & 32)
+#if XTENSA_HAVE_COPROCESSOR(5)
COPROCESSOR(5),
#endif
-#if (XCHAL_CP_MASK & 64)
+#if XTENSA_HAVE_COPROCESSOR(6)
COPROCESSOR(6),
#endif
-#if (XCHAL_CP_MASK & 128)
+#if XTENSA_HAVE_COPROCESSOR(7)
COPROCESSOR(7),
#endif
{ EXCCAUSE_MAPPED_DEBUG, 0, do_debug },
@@ -349,9 +349,7 @@ void show_regs(struct pt_regs * regs)
wmask = regs->wmask & ~1;
- for (i = 0; i < 32; i++) {
- if (wmask & (1 << (i / 4)))
- break;
+ for (i = 0; i < 16; i++) {
if ((i % 8) == 0)
printk ("\n" KERN_INFO "a%02d: ", i);
printk("%08lx ", regs->areg[i]);
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index 7d0f55a4982..51f4fb6f16f 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -136,7 +136,9 @@ SECTIONS
__init_begin = .;
.init.text : {
_sinittext = .;
- *(.init.literal) INIT_TEXT
+ *(.init.literal) *(.cpuinit.literal)
+ *(.devinit.literal) *(.meminit.literal)
+ INIT_TEXT
_einittext = .;
}
@@ -161,6 +163,8 @@ SECTIONS
.DoubleExceptionVector.literal);
RELOCATE_ENTRY(_DoubleExceptionVector_text,
.DoubleExceptionVector.text);
+ RELOCATE_ENTRY(_DebugInterruptVector_text,
+ .DebugInterruptVector.text);
__boot_reloc_table_end = ABSOLUTE(.) ;
}
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c
index 9a1fa9478ae..3ba990c6767 100644
--- a/arch/xtensa/mm/cache.c
+++ b/arch/xtensa/mm/cache.c
@@ -25,7 +25,6 @@
#include <linux/swap.h>
#include <linux/pagemap.h>
-#include <asm/pgtable.h>
#include <asm/bootparam.h>
#include <asm/mmu_context.h>
#include <asm/tlb.h>
@@ -181,9 +180,9 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte)
#else
if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)
&& (vma->vm_flags & VM_EXEC) != 0) {
- unsigned long vaddr = addr & PAGE_MASK;
- __flush_dcache_page(vaddr);
- __invalidate_icache_page(vaddr);
+ unsigned long paddr = (unsigned long) page_address(page);
+ __flush_dcache_page(paddr);
+ __invalidate_icache_page(paddr);
set_bit(PG_arch_1, &page->flags);
}
#endif
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index b3086f34a8e..81d0560eaea 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -309,7 +309,7 @@ void show_mem(void)
struct kmem_cache *pgtable_cache __read_mostly;
-static void pgd_ctor(void *addr, struct kmem_cache *cache, unsigned long flags)
+static void pgd_ctor(struct kmem_cache *cache, void* addr)
{
pte_t* ptep = (pte_t*)addr;
int i;
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S
index e1f880368e3..c885664211d 100644
--- a/arch/xtensa/mm/misc.S
+++ b/arch/xtensa/mm/misc.S
@@ -295,7 +295,7 @@ ENTRY(__tlbtemp_mapping_itlb)
ENTRY(__invalidate_icache_page_alias)
entry sp, 16
- addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
+ addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
mov a4, a2
witlb a6, a2
isync
diff --git a/arch/xtensa/platform-iss/Makefile b/arch/xtensa/platforms/iss/Makefile
index af96e314d71..af96e314d71 100644
--- a/arch/xtensa/platform-iss/Makefile
+++ b/arch/xtensa/platforms/iss/Makefile
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platforms/iss/console.c
index 854677d0c3f..9141e369073 100644
--- a/arch/xtensa/platform-iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -43,6 +43,7 @@ static DEFINE_SPINLOCK(timer_lock);
int errno;
+static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__));
static int __simc (int a, int b, int c, int d, int e, int f)
{
int ret;
diff --git a/arch/xtensa/platform-iss/io.c b/arch/xtensa/platforms/iss/io.c
index 5b161a5cb65..5b161a5cb65 100644
--- a/arch/xtensa/platform-iss/io.c
+++ b/arch/xtensa/platforms/iss/io.c
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platforms/iss/network.c
index f21b9b0899a..a2e25221742 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platforms/iss/network.c
@@ -31,7 +31,6 @@
#include <linux/bootmem.h>
#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
-#include <linux/timer.h>
#include <linux/platform_device.h>
#include <asm/platform/simcall.h>
@@ -108,6 +107,7 @@ struct iss_net_private {
static int errno;
+static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__));
static int __simc (int a, int b, int c, int d, int e, int f)
{
int ret;
diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platforms/iss/setup.c
index f60c8cf6dfb..f60c8cf6dfb 100644
--- a/arch/xtensa/platform-iss/setup.c
+++ b/arch/xtensa/platforms/iss/setup.c
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 6901eedeffc..55c5f1fc4f1 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -259,8 +259,11 @@ int blk_do_ordered(struct request_queue *q, struct request **rqp)
static void bio_end_empty_barrier(struct bio *bio, int err)
{
- if (err)
+ if (err) {
+ if (err == -EOPNOTSUPP)
+ set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
clear_bit(BIO_UPTODATE, &bio->bi_flags);
+ }
complete(bio->bi_private);
}
@@ -309,7 +312,9 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
*error_sector = bio->bi_sector;
ret = 0;
- if (!bio_flagged(bio, BIO_UPTODATE))
+ if (bio_flagged(bio, BIO_EOPNOTSUPP))
+ ret = -EOPNOTSUPP;
+ else if (!bio_flagged(bio, BIO_UPTODATE))
ret = -EIO;
bio_put(bio);
diff --git a/block/blk-core.c b/block/blk-core.c
index e9754dc98ec..2a438a93f72 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -38,7 +38,7 @@ static int __make_request(struct request_queue *q, struct bio *bio);
/*
* For the allocated request tables
*/
-struct kmem_cache *request_cachep;
+static struct kmem_cache *request_cachep;
/*
* For queue allocation
@@ -134,6 +134,7 @@ void rq_init(struct request_queue *q, struct request *rq)
rq->cmd_len = 0;
memset(rq->cmd, 0, sizeof(rq->cmd));
rq->data_len = 0;
+ rq->extra_len = 0;
rq->sense_len = 0;
rq->data = NULL;
rq->sense = NULL;
@@ -423,7 +424,6 @@ void blk_put_queue(struct request_queue *q)
{
kobject_put(&q->kobj);
}
-EXPORT_SYMBOL(blk_put_queue);
void blk_cleanup_queue(struct request_queue *q)
{
@@ -591,7 +591,6 @@ int blk_get_queue(struct request_queue *q)
return 1;
}
-EXPORT_SYMBOL(blk_get_queue);
static inline void blk_free_request(struct request_queue *q, struct request *rq)
{
@@ -1767,6 +1766,7 @@ static inline void __end_request(struct request *rq, int uptodate,
/**
* blk_rq_bytes - Returns bytes left to complete in the entire request
+ * @rq: the request being processed
**/
unsigned int blk_rq_bytes(struct request *rq)
{
@@ -1779,6 +1779,7 @@ EXPORT_SYMBOL_GPL(blk_rq_bytes);
/**
* blk_rq_cur_bytes - Returns bytes left to complete in the current segment
+ * @rq: the request being processed
**/
unsigned int blk_rq_cur_bytes(struct request *rq)
{
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 80245dc30c7..e34df7c9fc3 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -17,17 +17,13 @@ static struct kmem_cache *iocontext_cachep;
static void cfq_dtor(struct io_context *ioc)
{
- struct cfq_io_context *cic[1];
- int r;
+ if (!hlist_empty(&ioc->cic_list)) {
+ struct cfq_io_context *cic;
- /*
- * We don't have a specific key to lookup with, so use the gang
- * lookup to just retrieve the first item stored. The cfq exit
- * function will iterate the full tree, so any member will do.
- */
- r = radix_tree_gang_lookup(&ioc->radix_root, (void **) cic, 0, 1);
- if (r > 0)
- cic[0]->dtor(ioc);
+ cic = list_entry(ioc->cic_list.first, struct cfq_io_context,
+ cic_list);
+ cic->dtor(ioc);
+ }
}
/*
@@ -57,18 +53,16 @@ EXPORT_SYMBOL(put_io_context);
static void cfq_exit(struct io_context *ioc)
{
- struct cfq_io_context *cic[1];
- int r;
-
rcu_read_lock();
- /*
- * See comment for cfq_dtor()
- */
- r = radix_tree_gang_lookup(&ioc->radix_root, (void **) cic, 0, 1);
- rcu_read_unlock();
- if (r > 0)
- cic[0]->exit(ioc);
+ if (!hlist_empty(&ioc->cic_list)) {
+ struct cfq_io_context *cic;
+
+ cic = list_entry(ioc->cic_list.first, struct cfq_io_context,
+ cic_list);
+ cic->exit(ioc);
+ }
+ rcu_read_unlock();
}
/* Called by the exitting task */
@@ -105,6 +99,7 @@ struct io_context *alloc_io_context(gfp_t gfp_flags, int node)
ret->nr_batch_requests = 0; /* because this is 0 */
ret->aic = NULL;
INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH);
+ INIT_HLIST_HEAD(&ret->cic_list);
ret->ioc_data = NULL;
}
@@ -176,7 +171,7 @@ void copy_io_context(struct io_context **pdst, struct io_context **psrc)
}
EXPORT_SYMBOL(copy_io_context);
-int __init blk_ioc_init(void)
+static int __init blk_ioc_init(void)
{
iocontext_cachep = kmem_cache_create("blkdev_ioc",
sizeof(struct io_context), 0, SLAB_PANIC, NULL);
diff --git a/block/blk-map.c b/block/blk-map.c
index 955d75c1a58..c07d9c8317f 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -43,6 +43,7 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
void __user *ubuf, unsigned int len)
{
unsigned long uaddr;
+ unsigned int alignment;
struct bio *bio, *orig_bio;
int reading, ret;
@@ -53,8 +54,8 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
* direct dma. else, set up kernel bounce buffers
*/
uaddr = (unsigned long) ubuf;
- if (!(uaddr & queue_dma_alignment(q)) &&
- !(len & queue_dma_alignment(q)))
+ alignment = queue_dma_alignment(q) | q->dma_pad_mask;
+ if (!(uaddr & alignment) && !(len & alignment))
bio = bio_map_user(q, NULL, uaddr, len, reading);
else
bio = bio_copy_user(q, uaddr, len, reading);
@@ -139,10 +140,31 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
ubuf += ret;
}
+ /*
+ * __blk_rq_map_user() copies the buffers if starting address
+ * or length isn't aligned to dma_pad_mask. As the copied
+ * buffer is always page aligned, we know that there's enough
+ * room for padding. Extend the last bio and update
+ * rq->data_len accordingly.
+ *
+ * On unmap, bio_uncopy_user() will use unmodified
+ * bio_map_data pointed to by bio->bi_private.
+ */
+ if (len & q->dma_pad_mask) {
+ unsigned int pad_len = (q->dma_pad_mask & ~len) + 1;
+ struct bio *tail = rq->biotail;
+
+ tail->bi_io_vec[tail->bi_vcnt - 1].bv_len += pad_len;
+ tail->bi_size += pad_len;
+
+ rq->extra_len += pad_len;
+ }
+
rq->buffer = rq->data = NULL;
return 0;
unmap_rq:
blk_rq_unmap_user(bio);
+ rq->bio = NULL;
return ret;
}
EXPORT_SYMBOL(blk_rq_map_user);
@@ -195,7 +217,6 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
rq->buffer = rq->data = NULL;
return 0;
}
-EXPORT_SYMBOL(blk_rq_map_user_iov);
/**
* blk_rq_unmap_user - unmap a request with user data
diff --git a/block/blk-merge.c b/block/blk-merge.c
index d3b84bbb776..0f58616bcd7 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -220,7 +220,10 @@ new_segment:
bvprv = bvec;
} /* segments in rq */
- if (q->dma_drain_size) {
+ if (q->dma_drain_size && q->dma_drain_needed(rq)) {
+ if (rq->cmd_flags & REQ_RW)
+ memset(q->dma_drain_buffer, 0, q->dma_drain_size);
+
sg->page_link &= ~0x02;
sg = sg_next(sg);
sg_set_page(sg, virt_to_page(q->dma_drain_buffer),
@@ -228,6 +231,7 @@ new_segment:
((unsigned long)q->dma_drain_buffer) &
(PAGE_SIZE - 1));
nsegs++;
+ rq->extra_len += q->dma_drain_size;
}
if (sg)
diff --git a/block/blk-settings.c b/block/blk-settings.c
index c8d0c572409..1344a0ea5cc 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -140,7 +140,7 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_addr)
/* Assume anything <= 4GB can be handled by IOMMU.
Actually some IOMMUs can handle everything, but I don't
know of a way to test this here. */
- if (b_pfn < (min_t(u64, 0xffffffff, BLK_BOUNCE_HIGH) >> PAGE_SHIFT))
+ if (b_pfn <= (min_t(u64, 0xffffffff, BLK_BOUNCE_HIGH) >> PAGE_SHIFT))
dma = 1;
q->bounce_pfn = max_low_pfn;
#else
@@ -293,9 +293,26 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
EXPORT_SYMBOL(blk_queue_stack_limits);
/**
- * blk_queue_dma_drain - Set up a drain buffer for excess dma.
+ * blk_queue_dma_pad - set pad mask
+ * @q: the request queue for the device
+ * @mask: pad mask
+ *
+ * Set pad mask. Direct IO requests are padded to the mask specified.
*
+ * Appending pad buffer to a request modifies ->data_len such that it
+ * includes the pad buffer. The original requested data length can be
+ * obtained using blk_rq_raw_data_len().
+ **/
+void blk_queue_dma_pad(struct request_queue *q, unsigned int mask)
+{
+ q->dma_pad_mask = mask;
+}
+EXPORT_SYMBOL(blk_queue_dma_pad);
+
+/**
+ * blk_queue_dma_drain - Set up a drain buffer for excess dma.
* @q: the request queue for the device
+ * @dma_drain_needed: fn which returns non-zero if drain is necessary
* @buf: physically contiguous buffer
* @size: size of the buffer in bytes
*
@@ -315,14 +332,16 @@ EXPORT_SYMBOL(blk_queue_stack_limits);
* device can support otherwise there won't be room for the drain
* buffer.
*/
-int blk_queue_dma_drain(struct request_queue *q, void *buf,
- unsigned int size)
+int blk_queue_dma_drain(struct request_queue *q,
+ dma_drain_needed_fn *dma_drain_needed,
+ void *buf, unsigned int size)
{
if (q->max_hw_segments < 2 || q->max_phys_segments < 2)
return -EINVAL;
/* make room for appending the drain */
--q->max_hw_segments;
--q->max_phys_segments;
+ q->dma_drain_needed = dma_drain_needed;
q->dma_drain_buffer = buf;
q->dma_drain_size = size;
@@ -386,7 +405,7 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask)
}
EXPORT_SYMBOL(blk_queue_update_dma_alignment);
-int __init blk_settings_init(void)
+static int __init blk_settings_init(void)
{
blk_max_low_pfn = max_low_pfn - 1;
blk_max_pfn = max_pfn - 1;
diff --git a/block/blk-tag.c b/block/blk-tag.c
index a8c37d4bbb3..4780a46ce23 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -6,6 +6,8 @@
#include <linux/bio.h>
#include <linux/blkdev.h>
+#include "blk.h"
+
/**
* blk_queue_find_tag - find a request by its tag and queue
* @q: The request queue for the device
diff --git a/block/blk.h b/block/blk.h
index ec898dd0c65..ec9120fb789 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -32,6 +32,8 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect);
void blk_queue_congestion_threshold(struct request_queue *q);
+int blk_dev_init(void);
+
/*
* Return the threshold (number of used requests) at which the queue is
* considered to be congested. It include a little hysteresis to keep the
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index ca198e61fa6..0f962ecae91 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1145,38 +1145,19 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
/*
* Call func for each cic attached to this ioc. Returns number of cic's seen.
*/
-#define CIC_GANG_NR 16
static unsigned int
call_for_each_cic(struct io_context *ioc,
void (*func)(struct io_context *, struct cfq_io_context *))
{
- struct cfq_io_context *cics[CIC_GANG_NR];
- unsigned long index = 0;
- unsigned int called = 0;
- int nr;
+ struct cfq_io_context *cic;
+ struct hlist_node *n;
+ int called = 0;
rcu_read_lock();
-
- do {
- int i;
-
- /*
- * Perhaps there's a better way - this just gang lookups from
- * 0 to the end, restarting after each CIC_GANG_NR from the
- * last key + 1.
- */
- nr = radix_tree_gang_lookup(&ioc->radix_root, (void **) cics,
- index, CIC_GANG_NR);
- if (!nr)
- break;
-
- called += nr;
- index = 1 + (unsigned long) cics[nr - 1]->key;
-
- for (i = 0; i < nr; i++)
- func(ioc, cics[i]);
- } while (nr == CIC_GANG_NR);
-
+ hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) {
+ func(ioc, cic);
+ called++;
+ }
rcu_read_unlock();
return called;
@@ -1190,6 +1171,7 @@ static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
spin_lock_irqsave(&ioc->lock, flags);
radix_tree_delete(&ioc->radix_root, cic->dead_key);
+ hlist_del_rcu(&cic->cic_list);
spin_unlock_irqrestore(&ioc->lock, flags);
kmem_cache_free(cfq_ioc_pool, cic);
@@ -1280,6 +1262,7 @@ cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
if (cic) {
cic->last_end_request = jiffies;
INIT_LIST_HEAD(&cic->queue_list);
+ INIT_HLIST_NODE(&cic->cic_list);
cic->dtor = cfq_free_io_context;
cic->exit = cfq_exit_io_context;
elv_ioc_count_inc(ioc_count);
@@ -1501,6 +1484,7 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
rcu_assign_pointer(ioc->ioc_data, NULL);
radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd);
+ hlist_del_rcu(&cic->cic_list);
spin_unlock_irqrestore(&ioc->lock, flags);
cfq_cic_free(cic);
@@ -1561,6 +1545,8 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc,
spin_lock_irqsave(&ioc->lock, flags);
ret = radix_tree_insert(&ioc->radix_root,
(unsigned long) cfqd, cic);
+ if (!ret)
+ hlist_add_head_rcu(&cic->cic_list, &ioc->cic_list);
spin_unlock_irqrestore(&ioc->lock, flags);
radix_tree_preload_end();
diff --git a/block/elevator.c b/block/elevator.c
index bafbae0344d..88318c38360 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -134,6 +134,21 @@ static struct elevator_type *elevator_get(const char *name)
spin_lock(&elv_list_lock);
e = elevator_find(name);
+ if (!e) {
+ char elv[ELV_NAME_MAX + strlen("-iosched")];
+
+ spin_unlock(&elv_list_lock);
+
+ if (!strcmp(name, "anticipatory"))
+ sprintf(elv, "as-iosched");
+ else
+ sprintf(elv, "%s-iosched", name);
+
+ request_module(elv);
+ spin_lock(&elv_list_lock);
+ e = elevator_find(name);
+ }
+
if (e && !try_module_get(e->elevator_owner))
e = NULL;
diff --git a/block/genhd.c b/block/genhd.c
index 53f2238e69c..c44527d16c5 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -17,11 +17,15 @@
#include <linux/buffer_head.h>
#include <linux/mutex.h>
+#include "blk.h"
+
static DEFINE_MUTEX(block_class_lock);
#ifndef CONFIG_SYSFS_DEPRECATED
struct kobject *block_depr;
#endif
+static struct device_type disk_type;
+
/*
* Can be deleted altogether. Later.
*
@@ -346,8 +350,6 @@ const struct seq_operations partitions_op = {
#endif
-extern int blk_dev_init(void);
-
static struct kobject *base_probe(dev_t devt, int *part, void *data)
{
if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0)
@@ -502,7 +504,7 @@ struct class block_class = {
.name = "block",
};
-struct device_type disk_type = {
+static struct device_type disk_type = {
.name = "disk",
.groups = disk_attr_groups,
.release = disk_release,
@@ -632,12 +634,14 @@ static void media_change_notify_thread(struct work_struct *work)
put_device(gd->driverfs_dev);
}
+#if 0
void genhd_media_change_notify(struct gendisk *disk)
{
get_device(disk->driverfs_dev);
schedule_work(&disk->async_notify);
}
EXPORT_SYMBOL_GPL(genhd_media_change_notify);
+#endif /* 0 */
dev_t blk_lookup_devt(const char *name)
{
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 9675b34638d..a2c3a936ebf 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -529,6 +529,7 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->data = NULL;
rq->data_len = 0;
+ rq->extra_len = 0;
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
memset(rq->cmd, 0, sizeof(rq->cmd));
rq->cmd[0] = cmd;
diff --git a/drivers/acorn/char/defkeymap-l7200.c b/drivers/acorn/char/defkeymap-l7200.c
index 28a5fbc6aa1..93d80a1c36f 100644
--- a/drivers/acorn/char/defkeymap-l7200.c
+++ b/drivers/acorn/char/defkeymap-l7200.c
@@ -347,40 +347,40 @@ char *func_table[MAX_NR_FUNC] = {
};
struct kbdiacruc accent_table[MAX_DIACR] = {
- {'`', 'A', '\300'}, {'`', 'a', '\340'},
- {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
- {'^', 'A', '\302'}, {'^', 'a', '\342'},
- {'~', 'A', '\303'}, {'~', 'a', '\343'},
- {'"', 'A', '\304'}, {'"', 'a', '\344'},
- {'O', 'A', '\305'}, {'o', 'a', '\345'},
- {'0', 'A', '\305'}, {'0', 'a', '\345'},
- {'A', 'A', '\305'}, {'a', 'a', '\345'},
- {'A', 'E', '\306'}, {'a', 'e', '\346'},
- {',', 'C', '\307'}, {',', 'c', '\347'},
- {'`', 'E', '\310'}, {'`', 'e', '\350'},
- {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
- {'^', 'E', '\312'}, {'^', 'e', '\352'},
- {'"', 'E', '\313'}, {'"', 'e', '\353'},
- {'`', 'I', '\314'}, {'`', 'i', '\354'},
- {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
- {'^', 'I', '\316'}, {'^', 'i', '\356'},
- {'"', 'I', '\317'}, {'"', 'i', '\357'},
- {'-', 'D', '\320'}, {'-', 'd', '\360'},
- {'~', 'N', '\321'}, {'~', 'n', '\361'},
- {'`', 'O', '\322'}, {'`', 'o', '\362'},
- {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
- {'^', 'O', '\324'}, {'^', 'o', '\364'},
- {'~', 'O', '\325'}, {'~', 'o', '\365'},
- {'"', 'O', '\326'}, {'"', 'o', '\366'},
- {'/', 'O', '\330'}, {'/', 'o', '\370'},
- {'`', 'U', '\331'}, {'`', 'u', '\371'},
- {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
- {'^', 'U', '\333'}, {'^', 'u', '\373'},
- {'"', 'U', '\334'}, {'"', 'u', '\374'},
- {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
- {'T', 'H', '\336'}, {'t', 'h', '\376'},
- {'s', 's', '\337'}, {'"', 'y', '\377'},
- {'s', 'z', '\337'}, {'i', 'j', '\377'},
+ {'`', 'A', 0300}, {'`', 'a', 0340},
+ {'\'', 'A', 0301}, {'\'', 'a', 0341},
+ {'^', 'A', 0302}, {'^', 'a', 0342},
+ {'~', 'A', 0303}, {'~', 'a', 0343},
+ {'"', 'A', 0304}, {'"', 'a', 0344},
+ {'O', 'A', 0305}, {'o', 'a', 0345},
+ {'0', 'A', 0305}, {'0', 'a', 0345},
+ {'A', 'A', 0305}, {'a', 'a', 0345},
+ {'A', 'E', 0306}, {'a', 'e', 0346},
+ {',', 'C', 0307}, {',', 'c', 0347},
+ {'`', 'E', 0310}, {'`', 'e', 0350},
+ {'\'', 'E', 0311}, {'\'', 'e', 0351},
+ {'^', 'E', 0312}, {'^', 'e', 0352},
+ {'"', 'E', 0313}, {'"', 'e', 0353},
+ {'`', 'I', 0314}, {'`', 'i', 0354},
+ {'\'', 'I', 0315}, {'\'', 'i', 0355},
+ {'^', 'I', 0316}, {'^', 'i', 0356},
+ {'"', 'I', 0317}, {'"', 'i', 0357},
+ {'-', 'D', 0320}, {'-', 'd', 0360},
+ {'~', 'N', 0321}, {'~', 'n', 0361},
+ {'`', 'O', 0322}, {'`', 'o', 0362},
+ {'\'', 'O', 0323}, {'\'', 'o', 0363},
+ {'^', 'O', 0324}, {'^', 'o', 0364},
+ {'~', 'O', 0325}, {'~', 'o', 0365},
+ {'"', 'O', 0326}, {'"', 'o', 0366},
+ {'/', 'O', 0330}, {'/', 'o', 0370},
+ {'`', 'U', 0331}, {'`', 'u', 0371},
+ {'\'', 'U', 0332}, {'\'', 'u', 0372},
+ {'^', 'U', 0333}, {'^', 'u', 0373},
+ {'"', 'U', 0334}, {'"', 'u', 0374},
+ {'\'', 'Y', 0335}, {'\'', 'y', 0375},
+ {'T', 'H', 0336}, {'t', 'h', 0376},
+ {'s', 's', 0337}, {'"', 'y', 0377},
+ {'s', 'z', 0337}, {'i', 'j', 0377},
};
unsigned int accent_table_size = 68;
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 7222a18a031..caf873c14bf 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -943,7 +943,11 @@ int __init acpi_ec_ecdt_probe(void)
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
boot_ec->gpe = ecdt_ptr->gpe;
- boot_ec->handle = ACPI_ROOT_OBJECT;
+ if (ACPI_FAILURE(acpi_get_handle(NULL, ecdt_ptr->id,
+ &boot_ec->handle))) {
+ pr_info("Failed to locate handle for boot EC\n");
+ boot_ec->handle = ACPI_ROOT_OBJECT;
+ }
} else {
/* This workaround is needed only on some broken machines,
* which require early EC, but fail to provide ECDT */
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
index 2e9ce94798c..3f51b7e84a1 100644
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -338,6 +338,7 @@ acpi_ex_pci_config_space_handler(u32 function,
acpi_status status = AE_OK;
struct acpi_pci_id *pci_id;
u16 pci_register;
+ u32 value32;
ACPI_FUNCTION_TRACE(ex_pci_config_space_handler);
@@ -364,9 +365,9 @@ acpi_ex_pci_config_space_handler(u32 function,
switch (function) {
case ACPI_READ:
- *value = 0;
status = acpi_os_read_pci_configuration(pci_id, pci_register,
- value, bit_width);
+ &value32, bit_width);
+ *value = value32;
break;
case ACPI_WRITE:
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 48cb705b274..c8e3cba423e 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -256,22 +256,28 @@ static int acpi_fan_add(struct acpi_device *device)
cdev = thermal_cooling_device_register("Fan", device,
&fan_cooling_ops);
- if (cdev)
+ if (IS_ERR(cdev)) {
+ result = PTR_ERR(cdev);
+ goto end;
+ }
+ if (cdev) {
printk(KERN_INFO PREFIX
"%s is registered as cooling_device%d\n",
device->dev.bus_id, cdev->id);
- else
- goto end;
- acpi_driver_data(device) = cdev;
- result = sysfs_create_link(&device->dev.kobj, &cdev->device.kobj,
- "thermal_cooling");
- if (result)
- return result;
- result = sysfs_create_link(&cdev->device.kobj, &device->dev.kobj,
- "device");
- if (result)
- return result;
+ acpi_driver_data(device) = cdev;
+ result = sysfs_create_link(&device->dev.kobj,
+ &cdev->device.kobj,
+ "thermal_cooling");
+ if (result)
+ return result;
+
+ result = sysfs_create_link(&cdev->device.kobj,
+ &device->dev.kobj,
+ "device");
+ if (result)
+ return result;
+ }
result = acpi_fan_add_fs(device);
if (result)
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 75ccf5d18bf..a3cc8a98255 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -670,21 +670,26 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
pr->cdev = thermal_cooling_device_register("Processor", device,
&processor_cooling_ops);
- if (pr->cdev)
+ if (IS_ERR(pr->cdev)) {
+ result = PTR_ERR(pr->cdev);
+ goto end;
+ }
+ if (pr->cdev) {
printk(KERN_INFO PREFIX
"%s is registered as cooling_device%d\n",
device->dev.bus_id, pr->cdev->id);
- else
- goto end;
- result = sysfs_create_link(&device->dev.kobj, &pr->cdev->device.kobj,
- "thermal_cooling");
- if (result)
- return result;
- result = sysfs_create_link(&pr->cdev->device.kobj, &device->dev.kobj,
- "device");
- if (result)
- return result;
+ result = sysfs_create_link(&device->dev.kobj,
+ &pr->cdev->device.kobj,
+ "thermal_cooling");
+ if (result)
+ return result;
+ result = sysfs_create_link(&pr->cdev->device.kobj,
+ &device->dev.kobj,
+ "device");
+ if (result)
+ return result;
+ }
if (pr->flags.throttling) {
printk(KERN_INFO PREFIX "%s [%s] (supports",
@@ -809,10 +814,12 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
acpi_processor_remove_fs(device);
- sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
- sysfs_remove_link(&pr->cdev->device.kobj, "device");
- thermal_cooling_device_unregister(pr->cdev);
- pr->cdev = NULL;
+ if (pr->cdev) {
+ sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
+ sysfs_remove_link(&pr->cdev->device.kobj, "device");
+ thermal_cooling_device_unregister(pr->cdev);
+ pr->cdev = NULL;
+ }
processors[pr->id] = NULL;
@@ -826,8 +833,6 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
* Acpi processor hotplug support *
****************************************************************************/
-static int is_processor_present(acpi_handle handle);
-
static int is_processor_present(acpi_handle handle)
{
acpi_status status;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 980e1c33e6c..6f3b217699e 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -364,7 +364,7 @@ int acpi_processor_resume(struct acpi_device * device)
return 0;
}
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
static int tsc_halts_in_c(int state)
{
switch (boot_cpu_data.x86_vendor) {
@@ -544,7 +544,7 @@ static void acpi_processor_idle(void)
/* Get end time (ticks) */
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+#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");
@@ -609,7 +609,7 @@ static void acpi_processor_idle(void)
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
}
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+#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");
@@ -1500,7 +1500,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
acpi_idle_do_entry(cx);
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
/* TSC could halt in idle, so notify users */
if (tsc_halts_in_c(cx->type))
mark_tsc_unstable("TSC halts in idle");;
@@ -1614,7 +1614,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
spin_unlock(&c3_lock);
}
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
/* TSC could halt in idle, so notify users */
if (tsc_halts_in_c(ACPI_STATE_C3))
mark_tsc_unstable("TSC halts in idle");
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 34f15757108..eba55b7d6c9 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -36,16 +36,20 @@ ACPI_MODULE_NAME("utils");
/* --------------------------------------------------------------------------
Object Evaluation Helpers
-------------------------------------------------------------------------- */
+static void
+acpi_util_eval_error(acpi_handle h, acpi_string p, acpi_status s)
+{
#ifdef ACPI_DEBUG_OUTPUT
-#define acpi_util_eval_error(h,p,s) {\
- char prefix[80] = {'\0'};\
- struct acpi_buffer buffer = {sizeof(prefix), prefix};\
- acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",\
- (char *) prefix, p, acpi_format_exception(s))); }
+ char prefix[80] = {'\0'};
+ struct acpi_buffer buffer = {sizeof(prefix), prefix};
+ acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",
+ (char *) prefix, p, acpi_format_exception(s)));
#else
-#define acpi_util_eval_error(h,p,s)
+ return;
#endif
+}
+
acpi_status
acpi_extract_package(union acpi_object *package,
struct acpi_buffer *format, struct acpi_buffer *buffer)
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 7f714fa2a45..12cce69b544 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -731,6 +731,9 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->cdev = thermal_cooling_device_register("LCD",
device->dev, &video_cooling_ops);
+ if (IS_ERR(device->cdev))
+ return;
+
if (device->cdev) {
printk(KERN_INFO PREFIX
"%s is registered as cooling_device%d\n",
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 29e71bddd6f..8a49835bd0f 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -85,6 +85,7 @@ enum {
board_ahci_ign_iferr = 2,
board_ahci_sb600 = 3,
board_ahci_mv = 4,
+ board_ahci_sb700 = 5,
/* global controller registers */
HOST_CAP = 0x00, /* host capabilities */
@@ -185,6 +186,7 @@ enum {
AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */
AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */
AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */
+ AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */
/* ap->flags bits */
@@ -254,6 +256,7 @@ static void ahci_vt8251_error_handler(struct ata_port *ap);
static void ahci_p5wdh_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
static int ahci_port_resume(struct ata_port *ap);
+static void ahci_dev_config(struct ata_device *dev);
static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl);
static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
u32 opts);
@@ -293,6 +296,8 @@ static const struct ata_port_operations ahci_ops = {
.check_altstatus = ahci_check_status,
.dev_select = ata_noop_dev_select,
+ .dev_config = ahci_dev_config,
+
.tf_read = ahci_tf_read,
.qc_defer = sata_pmp_qc_defer_cmd_switch,
@@ -424,7 +429,7 @@ static const struct ata_port_info ahci_port_info[] = {
/* board_ahci_sb600 */
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
- AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_PMP),
+ AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
.link_flags = AHCI_LFLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
@@ -442,6 +447,16 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
+ /* board_ahci_sb700 */
+ {
+ AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
+ AHCI_HFLAG_NO_PMP),
+ .flags = AHCI_FLAG_COMMON,
+ .link_flags = AHCI_LFLAG_COMMON,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_ops,
+ },
};
static const struct pci_device_id ahci_pci_tbl[] = {
@@ -484,12 +499,12 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* ATI */
{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
- { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700/800 */
- { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb600 }, /* ATI SB700/800 */
- { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb600 }, /* ATI SB700/800 */
- { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb600 }, /* ATI SB700/800 */
- { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb600 }, /* ATI SB700/800 */
- { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb600 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb700 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb700 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb700 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb700 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb700 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700 }, /* ATI SB700/800 */
/* VIA */
{ PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
@@ -1165,6 +1180,14 @@ static void ahci_init_controller(struct ata_host *host)
VPRINTK("HOST_CTL 0x%x\n", tmp);
}
+static void ahci_dev_config(struct ata_device *dev)
+{
+ struct ahci_host_priv *hpriv = dev->link->ap->host->private_data;
+
+ if (hpriv->flags & AHCI_HFLAG_SECT255)
+ dev->max_sectors = 255;
+}
+
static unsigned int ahci_dev_classify(struct ata_port *ap)
{
void __iomem *port_mmio = ahci_port_base(ap);
@@ -1932,7 +1955,7 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
u32 ctl;
- if (mesg.event == PM_EVENT_SUSPEND) {
+ if (mesg.event & PM_EVENT_SLEEP) {
/* AHCI spec rev1.1 section 8.3.3:
* Software must disable interrupts prior to requesting a
* transition of the HBA to D3 state.
@@ -1975,16 +1998,11 @@ static int ahci_port_start(struct ata_port *ap)
struct ahci_port_priv *pp;
void *mem;
dma_addr_t mem_dma;
- int rc;
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
return -ENOMEM;
- rc = ata_pad_alloc(ap, dev);
- if (rc)
- return rc;
-
mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma,
GFP_KERNEL);
if (!mem)
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 9c2515f67de..fae8404254c 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -1339,7 +1339,7 @@ static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
* cycles and power trying to do something to the sleeping
* beauty.
*/
- if (piix_broken_suspend() && mesg.event == PM_EVENT_SUSPEND) {
+ if (piix_broken_suspend() && (mesg.event & PM_EVENT_SLEEP)) {
pci_save_state(pdev);
/* mark its power state as "unknown", since we don't
@@ -1652,7 +1652,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
u8 tmp;
pci_read_config_byte(pdev, PIIX_SCC, &tmp);
if (tmp == PIIX_AHCI_DEVICE) {
- int rc = piix_disable_ahci(pdev);
+ rc = piix_disable_ahci(pdev);
if (rc)
return rc;
}
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 004dae4ea5b..4fbcce758b0 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -87,11 +87,33 @@ static struct workqueue_struct *ata_wq;
struct workqueue_struct *ata_aux_wq;
+struct ata_force_param {
+ const char *name;
+ unsigned int cbl;
+ int spd_limit;
+ unsigned long xfer_mask;
+ unsigned int horkage_on;
+ unsigned int horkage_off;
+};
+
+struct ata_force_ent {
+ int port;
+ int device;
+ struct ata_force_param param;
+};
+
+static struct ata_force_ent *ata_force_tbl;
+static int ata_force_tbl_size;
+
+static char ata_force_param_buf[PAGE_SIZE] __initdata;
+module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0444);
+MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/kernel-parameters.txt for details)");
+
int atapi_enabled = 1;
module_param(atapi_enabled, int, 0444);
MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
-int atapi_dmadir = 0;
+static int atapi_dmadir = 0;
module_param(atapi_dmadir, int, 0444);
MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)");
@@ -130,6 +152,179 @@ MODULE_VERSION(DRV_VERSION);
/**
+ * ata_force_cbl - force cable type according to libata.force
+ * @ap: ATA port of interest
+ *
+ * Force cable type according to libata.force and whine about it.
+ * The last entry which has matching port number is used, so it
+ * can be specified as part of device force parameters. For
+ * example, both "a:40c,1.00:udma4" and "1.00:40c,udma4" have the
+ * same effect.
+ *
+ * LOCKING:
+ * EH context.
+ */
+void ata_force_cbl(struct ata_port *ap)
+{
+ int i;
+
+ for (i = ata_force_tbl_size - 1; i >= 0; i--) {
+ const struct ata_force_ent *fe = &ata_force_tbl[i];
+
+ if (fe->port != -1 && fe->port != ap->print_id)
+ continue;
+
+ if (fe->param.cbl == ATA_CBL_NONE)
+ continue;
+
+ ap->cbl = fe->param.cbl;
+ ata_port_printk(ap, KERN_NOTICE,
+ "FORCE: cable set to %s\n", fe->param.name);
+ return;
+ }
+}
+
+/**
+ * ata_force_spd_limit - force SATA spd limit according to libata.force
+ * @link: ATA link of interest
+ *
+ * Force SATA spd limit according to libata.force and whine about
+ * it. When only the port part is specified (e.g. 1:), the limit
+ * applies to all links connected to both the host link and all
+ * fan-out ports connected via PMP. If the device part is
+ * specified as 0 (e.g. 1.00:), it specifies the first fan-out
+ * link not the host link. Device number 15 always points to the
+ * host link whether PMP is attached or not.
+ *
+ * LOCKING:
+ * EH context.
+ */
+static void ata_force_spd_limit(struct ata_link *link)
+{
+ int linkno, i;
+
+ if (ata_is_host_link(link))
+ linkno = 15;
+ else
+ linkno = link->pmp;
+
+ for (i = ata_force_tbl_size - 1; i >= 0; i--) {
+ const struct ata_force_ent *fe = &ata_force_tbl[i];
+
+ if (fe->port != -1 && fe->port != link->ap->print_id)
+ continue;
+
+ if (fe->device != -1 && fe->device != linkno)
+ continue;
+
+ if (!fe->param.spd_limit)
+ continue;
+
+ link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
+ ata_link_printk(link, KERN_NOTICE,
+ "FORCE: PHY spd limit set to %s\n", fe->param.name);
+ return;
+ }
+}
+
+/**
+ * ata_force_xfermask - force xfermask according to libata.force
+ * @dev: ATA device of interest
+ *
+ * Force xfer_mask according to libata.force and whine about it.
+ * For consistency with link selection, device number 15 selects
+ * the first device connected to the host link.
+ *
+ * LOCKING:
+ * EH context.
+ */
+static void ata_force_xfermask(struct ata_device *dev)
+{
+ int devno = dev->link->pmp + dev->devno;
+ int alt_devno = devno;
+ int i;
+
+ /* allow n.15 for the first device attached to host port */
+ if (ata_is_host_link(dev->link) && devno == 0)
+ alt_devno = 15;
+
+ for (i = ata_force_tbl_size - 1; i >= 0; i--) {
+ const struct ata_force_ent *fe = &ata_force_tbl[i];
+ unsigned long pio_mask, mwdma_mask, udma_mask;
+
+ if (fe->port != -1 && fe->port != dev->link->ap->print_id)
+ continue;
+
+ if (fe->device != -1 && fe->device != devno &&
+ fe->device != alt_devno)
+ continue;
+
+ if (!fe->param.xfer_mask)
+ continue;
+
+ ata_unpack_xfermask(fe->param.xfer_mask,
+ &pio_mask, &mwdma_mask, &udma_mask);
+ if (udma_mask)
+ dev->udma_mask = udma_mask;
+ else if (mwdma_mask) {
+ dev->udma_mask = 0;
+ dev->mwdma_mask = mwdma_mask;
+ } else {
+ dev->udma_mask = 0;
+ dev->mwdma_mask = 0;
+ dev->pio_mask = pio_mask;
+ }
+
+ ata_dev_printk(dev, KERN_NOTICE,
+ "FORCE: xfer_mask set to %s\n", fe->param.name);
+ return;
+ }
+}
+
+/**
+ * ata_force_horkage - force horkage according to libata.force
+ * @dev: ATA device of interest
+ *
+ * Force horkage according to libata.force and whine about it.
+ * For consistency with link selection, device number 15 selects
+ * the first device connected to the host link.
+ *
+ * LOCKING:
+ * EH context.
+ */
+static void ata_force_horkage(struct ata_device *dev)
+{
+ int devno = dev->link->pmp + dev->devno;
+ int alt_devno = devno;
+ int i;
+
+ /* allow n.15 for the first device attached to host port */
+ if (ata_is_host_link(dev->link) && devno == 0)
+ alt_devno = 15;
+
+ for (i = 0; i < ata_force_tbl_size; i++) {
+ const struct ata_force_ent *fe = &ata_force_tbl[i];
+
+ if (fe->port != -1 && fe->port != dev->link->ap->print_id)
+ continue;
+
+ if (fe->device != -1 && fe->device != devno &&
+ fe->device != alt_devno)
+ continue;
+
+ if (!(~dev->horkage & fe->param.horkage_on) &&
+ !(dev->horkage & fe->param.horkage_off))
+ continue;
+
+ dev->horkage |= fe->param.horkage_on;
+ dev->horkage &= ~fe->param.horkage_off;
+
+ ata_dev_printk(dev, KERN_NOTICE,
+ "FORCE: horkage modified (%s)\n", fe->param.name);
+ }
+}
+
+/**
* ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
* @tf: Taskfile to convert
* @pmp: Port multiplier port
@@ -2067,6 +2262,7 @@ int ata_dev_configure(struct ata_device *dev)
/* set horkage */
dev->horkage |= ata_dev_blacklisted(dev);
+ ata_force_horkage(dev);
/* let ACPI work its magic */
rc = ata_acpi_on_devcfg(dev);
@@ -2200,6 +2396,7 @@ int ata_dev_configure(struct ata_device *dev)
else if (dev->class == ATA_DEV_ATAPI) {
const char *cdb_intr_string = "";
const char *atapi_an_string = "";
+ const char *dma_dir_string = "";
u32 sntf;
rc = atapi_cdb_len(id);
@@ -2240,13 +2437,19 @@ int ata_dev_configure(struct ata_device *dev)
cdb_intr_string = ", CDB intr";
}
+ if (atapi_dmadir || atapi_id_dmadir(dev->id)) {
+ dev->flags |= ATA_DFLAG_DMADIR;
+ dma_dir_string = ", DMADIR";
+ }
+
/* print device info to dmesg */
if (ata_msg_drv(ap) && print_info)
ata_dev_printk(dev, KERN_INFO,
- "ATAPI: %s, %s, max %s%s%s\n",
+ "ATAPI: %s, %s, max %s%s%s%s\n",
modelbuf, fwrevbuf,
ata_mode_string(xfer_mask),
- cdb_intr_string, atapi_an_string);
+ cdb_intr_string, atapi_an_string,
+ dma_dir_string);
}
/* determine max_sectors */
@@ -3150,6 +3353,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
mode_mask = ATA_DMA_MASK_CFA;
ata_dev_xfermask(dev);
+ ata_force_xfermask(dev);
pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0);
dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
@@ -4190,6 +4394,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
/* Devices which report 1 sector over size HPA */
{ "ST340823A", NULL, ATA_HORKAGE_HPA_SIZE, },
{ "ST320413A", NULL, ATA_HORKAGE_HPA_SIZE, },
+ { "ST310211A", NULL, ATA_HORKAGE_HPA_SIZE, },
/* Devices which get the IVB wrong */
{ "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, },
@@ -4492,30 +4697,13 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
struct scatterlist *sg = qc->sg;
int dir = qc->dma_dir;
- void *pad_buf = NULL;
WARN_ON(sg == NULL);
- VPRINTK("unmapping %u sg elements\n", qc->mapped_n_elem);
-
- /* if we padded the buffer out to 32-bit bound, and data
- * xfer direction is from-device, we must copy from the
- * pad buffer back into the supplied buffer
- */
- if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE))
- pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
+ VPRINTK("unmapping %u sg elements\n", qc->n_elem);
- if (qc->mapped_n_elem)
- dma_unmap_sg(ap->dev, sg, qc->mapped_n_elem, dir);
- /* restore last sg */
- if (qc->last_sg)
- *qc->last_sg = qc->saved_last_sg;
- if (pad_buf) {
- struct scatterlist *psg = &qc->extra_sg[1];
- void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
- memcpy(addr + psg->offset, pad_buf, qc->pad_len);
- kunmap_atomic(addr, KM_IRQ0);
- }
+ if (qc->n_elem)
+ dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
qc->flags &= ~ATA_QCFLAG_DMAMAP;
qc->sg = NULL;
@@ -4658,43 +4846,6 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
}
/**
- * atapi_qc_may_overflow - Check whether data transfer may overflow
- * @qc: ATA command in question
- *
- * ATAPI commands which transfer variable length data to host
- * might overflow due to application error or hardare bug. This
- * function checks whether overflow should be drained and ignored
- * for @qc.
- *
- * LOCKING:
- * None.
- *
- * RETURNS:
- * 1 if @qc may overflow; otherwise, 0.
- */
-static int atapi_qc_may_overflow(struct ata_queued_cmd *qc)
-{
- if (qc->tf.protocol != ATAPI_PROT_PIO &&
- qc->tf.protocol != ATAPI_PROT_DMA)
- return 0;
-
- if (qc->tf.flags & ATA_TFLAG_WRITE)
- return 0;
-
- switch (qc->cdb[0]) {
- case READ_10:
- case READ_12:
- case WRITE_10:
- case WRITE_12:
- case GPCMD_READ_CD:
- case GPCMD_READ_CD_MSF:
- return 0;
- }
-
- return 1;
-}
-
-/**
* ata_std_qc_defer - Check whether a qc needs to be deferred
* @qc: ATA command in question
*
@@ -4781,97 +4932,6 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
qc->cursg = qc->sg;
}
-static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc,
- unsigned int *n_elem_extra,
- unsigned int *nbytes_extra)
-{
- struct ata_port *ap = qc->ap;
- unsigned int n_elem = qc->n_elem;
- struct scatterlist *lsg, *copy_lsg = NULL, *tsg = NULL, *esg = NULL;
-
- *n_elem_extra = 0;
- *nbytes_extra = 0;
-
- /* needs padding? */
- qc->pad_len = qc->nbytes & 3;
-
- if (likely(!qc->pad_len))
- return n_elem;
-
- /* locate last sg and save it */
- lsg = sg_last(qc->sg, n_elem);
- qc->last_sg = lsg;
- qc->saved_last_sg = *lsg;
-
- sg_init_table(qc->extra_sg, ARRAY_SIZE(qc->extra_sg));
-
- if (qc->pad_len) {
- struct scatterlist *psg = &qc->extra_sg[1];
- void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
- unsigned int offset;
-
- WARN_ON(qc->dev->class != ATA_DEV_ATAPI);
-
- memset(pad_buf, 0, ATA_DMA_PAD_SZ);
-
- /* psg->page/offset are used to copy to-be-written
- * data in this function or read data in ata_sg_clean.
- */
- offset = lsg->offset + lsg->length - qc->pad_len;
- sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT),
- qc->pad_len, offset_in_page(offset));
-
- if (qc->tf.flags & ATA_TFLAG_WRITE) {
- void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
- memcpy(pad_buf, addr + psg->offset, qc->pad_len);
- kunmap_atomic(addr, KM_IRQ0);
- }
-
- sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
- sg_dma_len(psg) = ATA_DMA_PAD_SZ;
-
- /* Trim the last sg entry and chain the original and
- * padding sg lists.
- *
- * Because chaining consumes one sg entry, one extra
- * sg entry is allocated and the last sg entry is
- * copied to it if the length isn't zero after padded
- * amount is removed.
- *
- * If the last sg entry is completely replaced by
- * padding sg entry, the first sg entry is skipped
- * while chaining.
- */
- lsg->length -= qc->pad_len;
- if (lsg->length) {
- copy_lsg = &qc->extra_sg[0];
- tsg = &qc->extra_sg[0];
- } else {
- n_elem--;
- tsg = &qc->extra_sg[1];
- }
-
- esg = &qc->extra_sg[1];
-
- (*n_elem_extra)++;
- (*nbytes_extra) += 4 - qc->pad_len;
- }
-
- if (copy_lsg)
- sg_set_page(copy_lsg, sg_page(lsg), lsg->length, lsg->offset);
-
- sg_chain(lsg, 1, tsg);
- sg_mark_end(esg);
-
- /* sglist can't start with chaining sg entry, fast forward */
- if (qc->sg == lsg) {
- qc->sg = tsg;
- qc->cursg = tsg;
- }
-
- return n_elem;
-}
-
/**
* ata_sg_setup - DMA-map the scatter-gather table associated with a command.
* @qc: Command with scatter-gather table to be mapped.
@@ -4888,26 +4948,17 @@ static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc,
static int ata_sg_setup(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- unsigned int n_elem, n_elem_extra, nbytes_extra;
+ unsigned int n_elem;
VPRINTK("ENTER, ata%u\n", ap->print_id);
- n_elem = ata_sg_setup_extra(qc, &n_elem_extra, &nbytes_extra);
+ n_elem = dma_map_sg(ap->dev, qc->sg, qc->n_elem, qc->dma_dir);
+ if (n_elem < 1)
+ return -1;
- if (n_elem) {
- n_elem = dma_map_sg(ap->dev, qc->sg, n_elem, qc->dma_dir);
- if (n_elem < 1) {
- /* restore last sg */
- if (qc->last_sg)
- *qc->last_sg = qc->saved_last_sg;
- return -1;
- }
- DPRINTK("%d sg elements mapped\n", n_elem);
- }
+ DPRINTK("%d sg elements mapped\n", n_elem);
- qc->n_elem = qc->mapped_n_elem = n_elem;
- qc->n_elem += n_elem_extra;
- qc->nbytes += nbytes_extra;
+ qc->n_elem = n_elem;
qc->flags |= ATA_QCFLAG_DMAMAP;
return 0;
@@ -5145,46 +5196,22 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
*/
static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
{
- int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
+ int rw = (qc->tf.flags & ATA_TFLAG_WRITE) ? WRITE : READ;
struct ata_port *ap = qc->ap;
- struct ata_eh_info *ehi = &qc->dev->link->eh_info;
+ struct ata_device *dev = qc->dev;
+ struct ata_eh_info *ehi = &dev->link->eh_info;
struct scatterlist *sg;
struct page *page;
unsigned char *buf;
- unsigned int offset, count;
+ unsigned int offset, count, consumed;
next_sg:
sg = qc->cursg;
if (unlikely(!sg)) {
- /*
- * The end of qc->sg is reached and the device expects
- * more data to transfer. In order not to overrun qc->sg
- * and fulfill length specified in the byte count register,
- * - for read case, discard trailing data from the device
- * - for write case, padding zero data to the device
- */
- u16 pad_buf[1] = { 0 };
- unsigned int i;
-
- if (bytes > qc->curbytes - qc->nbytes + ATAPI_MAX_DRAIN) {
- ata_ehi_push_desc(ehi, "too much trailing data "
- "buf=%u cur=%u bytes=%u",
- qc->nbytes, qc->curbytes, bytes);
- return -1;
- }
-
- /* overflow is exptected for misc ATAPI commands */
- if (bytes && !atapi_qc_may_overflow(qc))
- ata_dev_printk(qc->dev, KERN_WARNING, "ATAPI %u bytes "
- "trailing data (cdb=%02x nbytes=%u)\n",
- bytes, qc->cdb[0], qc->nbytes);
-
- for (i = 0; i < (bytes + 1) / 2; i++)
- ap->ops->data_xfer(qc->dev, (unsigned char *)pad_buf, 2, do_write);
-
- qc->curbytes += bytes;
-
- return 0;
+ ata_ehi_push_desc(ehi, "unexpected or too much trailing data "
+ "buf=%u cur=%u bytes=%u",
+ qc->nbytes, qc->curbytes, bytes);
+ return -1;
}
page = sg_page(sg);
@@ -5210,18 +5237,16 @@ next_sg:
buf = kmap_atomic(page, KM_IRQ0);
/* do the actual data transfer */
- ap->ops->data_xfer(qc->dev, buf + offset, count, do_write);
+ consumed = ap->ops->data_xfer(dev, buf + offset, count, rw);
kunmap_atomic(buf, KM_IRQ0);
local_irq_restore(flags);
} else {
buf = page_address(page);
- ap->ops->data_xfer(qc->dev, buf + offset, count, do_write);
+ consumed = ap->ops->data_xfer(dev, buf + offset, count, rw);
}
- bytes -= count;
- if ((count & 1) && bytes)
- bytes--;
+ bytes -= min(bytes, consumed);
qc->curbytes += count;
qc->cursg_ofs += count;
@@ -5230,9 +5255,11 @@ next_sg:
qc->cursg_ofs = 0;
}
+ /* consumed can be larger than count only for the last transfer */
+ WARN_ON(qc->cursg && count != consumed);
+
if (bytes)
goto next_sg;
-
return 0;
}
@@ -5250,6 +5277,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *dev = qc->dev;
+ struct ata_eh_info *ehi = &dev->link->eh_info;
unsigned int ireason, bc_lo, bc_hi, bytes;
int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
@@ -5267,26 +5295,28 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
/* shall be cleared to zero, indicating xfer of data */
if (unlikely(ireason & (1 << 0)))
- goto err_out;
+ goto atapi_check;
/* make sure transfer direction matches expected */
i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0;
if (unlikely(do_write != i_write))
- goto err_out;
+ goto atapi_check;
if (unlikely(!bytes))
- goto err_out;
+ goto atapi_check;
VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes);
- if (__atapi_pio_bytes(qc, bytes))
+ if (unlikely(__atapi_pio_bytes(qc, bytes)))
goto err_out;
ata_altstatus(ap); /* flush */
return;
-err_out:
- ata_dev_printk(dev, KERN_INFO, "ATAPI check failed\n");
+ atapi_check:
+ ata_ehi_push_desc(ehi, "ATAPI check failed (ireason=0x%x bytes=%u)",
+ ireason, bytes);
+ err_out:
qc->err_mask |= AC_ERR_HSM;
ap->hsm_task_state = HSM_ST_ERR;
}
@@ -5971,9 +6001,6 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
*/
BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes));
- /* ata_sg_setup() may update nbytes */
- qc->raw_nbytes = qc->nbytes;
-
if (ata_is_dma(prot) || (ata_is_pio(prot) &&
(ap->flags & ATA_FLAG_PIO_DMA)))
if (ata_sg_setup(qc))
@@ -6582,19 +6609,12 @@ void ata_host_resume(struct ata_host *host)
int ata_port_start(struct ata_port *ap)
{
struct device *dev = ap->dev;
- int rc;
ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
GFP_KERNEL);
if (!ap->prd)
return -ENOMEM;
- rc = ata_pad_alloc(ap, dev);
- if (rc)
- return rc;
-
- DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd,
- (unsigned long long)ap->prd_dma);
return 0;
}
@@ -6681,7 +6701,8 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
*/
int sata_link_init_spd(struct ata_link *link)
{
- u32 scontrol, spd;
+ u32 scontrol;
+ u8 spd;
int rc;
rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
@@ -6692,6 +6713,8 @@ int sata_link_init_spd(struct ata_link *link)
if (spd)
link->hw_sata_spd_limit &= (1 << spd) - 1;
+ ata_force_spd_limit(link);
+
link->sata_spd_limit = link->hw_sata_spd_limit;
return 0;
@@ -7086,7 +7109,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
DPRINTK("probe begin\n");
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
- int rc;
/* probe */
if (ap->ops->error_handler) {
@@ -7353,7 +7375,7 @@ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
pci_save_state(pdev);
pci_disable_device(pdev);
- if (mesg.event == PM_EVENT_SUSPEND)
+ if (mesg.event & PM_EVENT_SLEEP)
pci_set_power_state(pdev, PCI_D3hot);
}
@@ -7403,10 +7425,187 @@ int ata_pci_device_resume(struct pci_dev *pdev)
#endif /* CONFIG_PCI */
+static int __init ata_parse_force_one(char **cur,
+ struct ata_force_ent *force_ent,
+ const char **reason)
+{
+ /* FIXME: Currently, there's no way to tag init const data and
+ * using __initdata causes build failure on some versions of
+ * gcc. Once __initdataconst is implemented, add const to the
+ * following structure.
+ */
+ static struct ata_force_param force_tbl[] __initdata = {
+ { "40c", .cbl = ATA_CBL_PATA40 },
+ { "80c", .cbl = ATA_CBL_PATA80 },
+ { "short40c", .cbl = ATA_CBL_PATA40_SHORT },
+ { "unk", .cbl = ATA_CBL_PATA_UNK },
+ { "ign", .cbl = ATA_CBL_PATA_IGN },
+ { "sata", .cbl = ATA_CBL_SATA },
+ { "1.5Gbps", .spd_limit = 1 },
+ { "3.0Gbps", .spd_limit = 2 },
+ { "noncq", .horkage_on = ATA_HORKAGE_NONCQ },
+ { "ncq", .horkage_off = ATA_HORKAGE_NONCQ },
+ { "pio0", .xfer_mask = 1 << (ATA_SHIFT_PIO + 0) },
+ { "pio1", .xfer_mask = 1 << (ATA_SHIFT_PIO + 1) },
+ { "pio2", .xfer_mask = 1 << (ATA_SHIFT_PIO + 2) },
+ { "pio3", .xfer_mask = 1 << (ATA_SHIFT_PIO + 3) },
+ { "pio4", .xfer_mask = 1 << (ATA_SHIFT_PIO + 4) },
+ { "pio5", .xfer_mask = 1 << (ATA_SHIFT_PIO + 5) },
+ { "pio6", .xfer_mask = 1 << (ATA_SHIFT_PIO + 6) },
+ { "mwdma0", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 0) },
+ { "mwdma1", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 1) },
+ { "mwdma2", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 2) },
+ { "mwdma3", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 3) },
+ { "mwdma4", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 4) },
+ { "udma0", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 0) },
+ { "udma16", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 0) },
+ { "udma/16", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 0) },
+ { "udma1", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 1) },
+ { "udma25", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 1) },
+ { "udma/25", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 1) },
+ { "udma2", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 2) },
+ { "udma33", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 2) },
+ { "udma/33", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 2) },
+ { "udma3", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 3) },
+ { "udma44", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 3) },
+ { "udma/44", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 3) },
+ { "udma4", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 4) },
+ { "udma66", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 4) },
+ { "udma/66", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 4) },
+ { "udma5", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 5) },
+ { "udma100", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 5) },
+ { "udma/100", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 5) },
+ { "udma6", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
+ { "udma133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
+ { "udma/133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
+ { "udma7", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 7) },
+ };
+ char *start = *cur, *p = *cur;
+ char *id, *val, *endp;
+ const struct ata_force_param *match_fp = NULL;
+ int nr_matches = 0, i;
+
+ /* find where this param ends and update *cur */
+ while (*p != '\0' && *p != ',')
+ p++;
+
+ if (*p == '\0')
+ *cur = p;
+ else
+ *cur = p + 1;
+
+ *p = '\0';
+
+ /* parse */
+ p = strchr(start, ':');
+ if (!p) {
+ val = strstrip(start);
+ goto parse_val;
+ }
+ *p = '\0';
+
+ id = strstrip(start);
+ val = strstrip(p + 1);
+
+ /* parse id */
+ p = strchr(id, '.');
+ if (p) {
+ *p++ = '\0';
+ force_ent->device = simple_strtoul(p, &endp, 10);
+ if (p == endp || *endp != '\0') {
+ *reason = "invalid device";
+ return -EINVAL;
+ }
+ }
+
+ force_ent->port = simple_strtoul(id, &endp, 10);
+ if (p == endp || *endp != '\0') {
+ *reason = "invalid port/link";
+ return -EINVAL;
+ }
+
+ parse_val:
+ /* parse val, allow shortcuts so that both 1.5 and 1.5Gbps work */
+ for (i = 0; i < ARRAY_SIZE(force_tbl); i++) {
+ const struct ata_force_param *fp = &force_tbl[i];
+
+ if (strncasecmp(val, fp->name, strlen(val)))
+ continue;
+
+ nr_matches++;
+ match_fp = fp;
+
+ if (strcasecmp(val, fp->name) == 0) {
+ nr_matches = 1;
+ break;
+ }
+ }
+
+ if (!nr_matches) {
+ *reason = "unknown value";
+ return -EINVAL;
+ }
+ if (nr_matches > 1) {
+ *reason = "ambigious value";
+ return -EINVAL;
+ }
+
+ force_ent->param = *match_fp;
+
+ return 0;
+}
+
+static void __init ata_parse_force_param(void)
+{
+ int idx = 0, size = 1;
+ int last_port = -1, last_device = -1;
+ char *p, *cur, *next;
+
+ /* calculate maximum number of params and allocate force_tbl */
+ for (p = ata_force_param_buf; *p; p++)
+ if (*p == ',')
+ size++;
+
+ ata_force_tbl = kzalloc(sizeof(ata_force_tbl[0]) * size, GFP_KERNEL);
+ if (!ata_force_tbl) {
+ printk(KERN_WARNING "ata: failed to extend force table, "
+ "libata.force ignored\n");
+ return;
+ }
+
+ /* parse and populate the table */
+ for (cur = ata_force_param_buf; *cur != '\0'; cur = next) {
+ const char *reason = "";
+ struct ata_force_ent te = { .port = -1, .device = -1 };
+
+ next = cur;
+ if (ata_parse_force_one(&next, &te, &reason)) {
+ printk(KERN_WARNING "ata: failed to parse force "
+ "parameter \"%s\" (%s)\n",
+ cur, reason);
+ continue;
+ }
+
+ if (te.port == -1) {
+ te.port = last_port;
+ te.device = last_device;
+ }
+
+ ata_force_tbl[idx++] = te;
+
+ last_port = te.port;
+ last_device = te.device;
+ }
+
+ ata_force_tbl_size = idx;
+}
static int __init ata_init(void)
{
ata_probe_timeout *= HZ;
+
+ ata_parse_force_param();
+
ata_wq = create_workqueue("ata");
if (!ata_wq)
return -ENOMEM;
@@ -7423,6 +7622,7 @@ static int __init ata_init(void)
static void __exit ata_exit(void)
{
+ kfree(ata_force_tbl);
destroy_workqueue(ata_wq);
destroy_workqueue(ata_aux_wq);
}
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 4e31071acc0..698ce2cea52 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2393,9 +2393,11 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
}
/* PDIAG- should have been released, ask cable type if post-reset */
- if (ata_is_host_link(link) && ap->ops->cable_detect &&
- (ehc->i.flags & ATA_EHI_DID_RESET))
- ap->cbl = ap->ops->cable_detect(ap);
+ if ((ehc->i.flags & ATA_EHI_DID_RESET) && ata_is_host_link(link)) {
+ if (ap->ops->cable_detect)
+ ap->cbl = ap->ops->cable_detect(ap);
+ ata_force_cbl(ap);
+ }
/* Configure new devices forward such that user doesn't see
* device detection messages backwards.
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index caef2bbd4a8..d91f5090ba9 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -35,7 +35,7 @@ static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val)
ata_tf_init(pmp_dev, &tf);
tf.command = ATA_CMD_PMP_READ;
tf.protocol = ATA_PROT_NODATA;
- tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48;
tf.feature = reg;
tf.device = link->pmp;
@@ -71,7 +71,7 @@ static unsigned int sata_pmp_write(struct ata_link *link, int reg, u32 val)
ata_tf_init(pmp_dev, &tf);
tf.command = ATA_CMD_PMP_WRITE;
tf.protocol = ATA_PROT_NODATA;
- tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48;
tf.feature = reg;
tf.device = link->pmp;
tf.nsect = val & 0xff;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index c02c490122d..8f0e8f2bc62 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -826,30 +826,62 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
sdev->max_device_blocked = 1;
}
-static void ata_scsi_dev_config(struct scsi_device *sdev,
- struct ata_device *dev)
+/**
+ * atapi_drain_needed - Check whether data transfer may overflow
+ * @rq: request to be checked
+ *
+ * ATAPI commands which transfer variable length data to host
+ * might overflow due to application error or hardare bug. This
+ * function checks whether overflow should be drained and ignored
+ * for @request.
+ *
+ * LOCKING:
+ * None.
+ *
+ * RETURNS:
+ * 1 if ; otherwise, 0.
+ */
+static int atapi_drain_needed(struct request *rq)
+{
+ if (likely(!blk_pc_request(rq)))
+ return 0;
+
+ if (!rq->data_len || (rq->cmd_flags & REQ_RW))
+ return 0;
+
+ return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC;
+}
+
+static int ata_scsi_dev_config(struct scsi_device *sdev,
+ struct ata_device *dev)
{
/* configure max sectors */
blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
- /* SATA DMA transfers must be multiples of 4 byte, so
- * we need to pad ATAPI transfers using an extra sg.
- * Decrement max hw segments accordingly.
- */
if (dev->class == ATA_DEV_ATAPI) {
struct request_queue *q = sdev->request_queue;
- blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
+ void *buf;
- /* set the min alignment */
+ /* set the min alignment and padding */
blk_queue_update_dma_alignment(sdev->request_queue,
ATA_DMA_PAD_SZ - 1);
- } else
+ blk_queue_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1);
+
+ /* configure draining */
+ buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL);
+ if (!buf) {
+ ata_dev_printk(dev, KERN_ERR,
+ "drain buffer allocation failed\n");
+ return -ENOMEM;
+ }
+
+ blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN);
+ } else {
/* ATA devices must be sector aligned */
blk_queue_update_dma_alignment(sdev->request_queue,
ATA_SECT_SIZE - 1);
-
- if (dev->class == ATA_DEV_ATA)
sdev->manage_start_stop = 1;
+ }
if (dev->flags & ATA_DFLAG_AN)
set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events);
@@ -861,6 +893,8 @@ static void ata_scsi_dev_config(struct scsi_device *sdev,
depth = min(ATA_MAX_QUEUE - 1, depth);
scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth);
}
+
+ return 0;
}
/**
@@ -879,13 +913,14 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
{
struct ata_port *ap = ata_shost_to_port(sdev->host);
struct ata_device *dev = __ata_scsi_find_dev(ap, sdev);
+ int rc = 0;
ata_scsi_sdev_config(sdev);
if (dev)
- ata_scsi_dev_config(sdev, dev);
+ rc = ata_scsi_dev_config(sdev, dev);
- return 0;
+ return rc;
}
/**
@@ -905,6 +940,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
void ata_scsi_slave_destroy(struct scsi_device *sdev)
{
struct ata_port *ap = ata_shost_to_port(sdev->host);
+ struct request_queue *q = sdev->request_queue;
unsigned long flags;
struct ata_device *dev;
@@ -920,6 +956,10 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
ata_port_schedule_eh(ap);
}
spin_unlock_irqrestore(ap->lock, flags);
+
+ kfree(q->dma_drain_buffer);
+ q->dma_drain_buffer = NULL;
+ q->dma_drain_size = 0;
}
/**
@@ -1655,12 +1695,17 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
u8 *rbuf;
unsigned int buflen, rc;
struct scsi_cmnd *cmd = args->cmd;
+ unsigned long flags;
+
+ local_irq_save(flags);
buflen = ata_scsi_rbuf_get(cmd, &rbuf);
memset(rbuf, 0, buflen);
rc = actor(args, rbuf, buflen);
ata_scsi_rbuf_put(cmd, rbuf);
+ local_irq_restore(flags);
+
if (rc == 0)
cmd->result = SAM_STAT_GOOD;
args->done(cmd);
@@ -1862,7 +1907,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
* spin_lock_irqsave(host lock)
*/
-unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
+static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen)
{
u8 pbuf[60];
@@ -2434,6 +2479,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) {
u8 *buf = NULL;
unsigned int buflen;
+ unsigned long flags;
+
+ local_irq_save(flags);
buflen = ata_scsi_rbuf_get(cmd, &buf);
@@ -2451,6 +2499,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
}
ata_scsi_rbuf_put(cmd, buf);
+
+ local_irq_restore(flags);
}
cmd->result = SAM_STAT_GOOD;
@@ -2489,7 +2539,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
}
qc->tf.command = ATA_CMD_PACKET;
- qc->nbytes = scsi_bufflen(scmd);
+ qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len;
/* check whether ATAPI DMA is safe */
if (!using_pio && ata_check_atapi_dma(qc))
@@ -2500,7 +2550,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
* want to set it properly, and for DMA where it is
* effectively meaningless.
*/
- nbytes = min(qc->nbytes, (unsigned int)63 * 1024);
+ nbytes = min(scmd->request->data_len, (unsigned int)63 * 1024);
/* Most ATAPI devices which honor transfer chunk size don't
* behave according to the spec when odd chunk size which
@@ -2543,7 +2593,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
qc->tf.protocol = ATAPI_PROT_DMA;
qc->tf.feature |= ATAPI_PKT_DMA;
- if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE))
+ if ((dev->flags & ATA_DFLAG_DMADIR) &&
+ (scmd->sc_data_direction != DMA_TO_DEVICE))
/* some SATA bridges need us to indicate data xfer direction */
qc->tf.feature |= ATAPI_DMADIR;
}
@@ -2825,7 +2876,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
* TODO: find out if we need to do more here to
* cover scatter/gather case.
*/
- qc->nbytes = scsi_bufflen(scmd);
+ qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len;
/* request result TF and be quiet about device error */
qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET;
@@ -3555,7 +3606,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
* @ap: Port to initialize
*
* Called just after data structures for each port are
- * initialized. Allocates DMA pad.
+ * initialized.
*
* May be used as the port_start() entry in ata_port_operations.
*
@@ -3564,7 +3615,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
*/
int ata_sas_port_start(struct ata_port *ap)
{
- return ata_pad_alloc(ap, ap->dev);
+ return 0;
}
EXPORT_SYMBOL_GPL(ata_sas_port_start);
@@ -3572,8 +3623,6 @@ EXPORT_SYMBOL_GPL(ata_sas_port_start);
* ata_port_stop - Undo ata_sas_port_start()
* @ap: Port to shut down
*
- * Frees the DMA pad.
- *
* May be used as the port_stop() entry in ata_port_operations.
*
* LOCKING:
@@ -3582,7 +3631,6 @@ EXPORT_SYMBOL_GPL(ata_sas_port_start);
void ata_sas_port_stop(struct ata_port *ap)
{
- ata_pad_free(ap, ap->dev);
}
EXPORT_SYMBOL_GPL(ata_sas_port_stop);
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 409ffb9af16..aa884f71a12 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -56,11 +56,11 @@ enum {
extern unsigned int ata_print_id;
extern struct workqueue_struct *ata_aux_wq;
extern int atapi_enabled;
-extern int atapi_dmadir;
extern int atapi_passthru16;
extern int libata_fua;
extern int libata_noacpi;
extern int libata_allow_tpm;
+extern void ata_force_cbl(struct ata_port *ap);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index 244098a80ce..bdc3b9d7395 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -77,8 +77,8 @@ static int pacpi_cable_detect(struct ata_port *ap)
static void pacpi_error_handler(struct ata_port *ap)
{
- return ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset,
- NULL, ata_std_postreset);
+ ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset, NULL,
+ ata_std_postreset);
}
/**
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index ea567e2b170..4b8d9b592ca 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -146,9 +146,8 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline)
static void amd_error_handler(struct ata_port *ap)
{
- return ata_bmdma_drive_eh(ap, amd_pre_reset,
- ata_std_softreset, NULL,
- ata_std_postreset);
+ ata_bmdma_drive_eh(ap, amd_pre_reset, ata_std_softreset, NULL,
+ ata_std_postreset);
}
static int amd_cable_detect(struct ata_port *ap)
@@ -506,7 +505,6 @@ static struct ata_port_operations amd133_port_ops = {
static struct ata_port_operations nv100_port_ops = {
.set_piomode = nv100_set_piomode,
.set_dmamode = nv100_set_dmamode,
- .mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
@@ -541,7 +539,6 @@ static struct ata_port_operations nv100_port_ops = {
static struct ata_port_operations nv133_port_ops = {
.set_piomode = nv133_set_piomode,
.set_dmamode = nv133_set_dmamode,
- .mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 9623f529553..408bdc1a977 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -227,7 +227,7 @@ static struct scsi_host_template atiixp_sht = {
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
+ .sg_tablesize = LIBATA_DUMB_MAX_PRD,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -259,7 +259,7 @@ static struct ata_port_operations atiixp_port_ops = {
.bmdma_stop = atiixp_bmdma_stop,
.bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
+ .qc_prep = ata_dumb_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer,
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
index d753e568588..1c4ff9b52b5 100644
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -40,7 +40,7 @@
#include <asm/msr.h>
#define DRV_NAME "pata_cs5536"
-#define DRV_VERSION "0.0.6"
+#define DRV_VERSION "0.0.7"
enum {
CFG = 0,
@@ -85,7 +85,7 @@ static const u8 pci_reg[4] = {
PCI_IDE_CFG, PCI_IDE_DTC, PCI_IDE_CAST, PCI_IDE_ETC,
};
-static inline int cs5536_read(struct pci_dev *pdev, int reg, int *val)
+static inline int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
{
if (unlikely(use_msr)) {
u32 dummy;
@@ -153,8 +153,8 @@ static void cs5536_set_piomode(struct ata_port *ap, struct ata_device *adev)
struct ata_device *pair = ata_dev_pair(adev);
int mode = adev->pio_mode - XFER_PIO_0;
int cmdmode = mode;
- int dshift = ap->port_no ? IDE_D1_SHIFT : IDE_D0_SHIFT;
- int cshift = ap->port_no ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
+ int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ int cshift = adev->devno ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
u32 dtc, cast, etc;
if (pair)
@@ -201,7 +201,7 @@ static void cs5536_set_dmamode(struct ata_port *ap, struct ata_device *adev)
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 dtc, etc;
int mode = adev->dma_mode;
- int dshift = ap->port_no ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
if (mode >= XFER_UDMA_0) {
cs5536_read(pdev, ETC, &etc);
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 0713872cf65..a742efa0da2 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -27,7 +27,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt366"
-#define DRV_VERSION "0.6.1"
+#define DRV_VERSION "0.6.2"
struct hpt_clock {
u8 xfer_speed;
@@ -180,9 +180,9 @@ static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask)
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
mask &= ~ATA_MASK_UDMA;
if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3))
- mask &= ~(0x07 << ATA_SHIFT_UDMA);
+ mask &= ~(0xF8 << ATA_SHIFT_UDMA);
if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
- mask &= ~(0x0F << ATA_SHIFT_UDMA);
+ mask &= ~(0xF0 << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(adev, mask);
}
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 68eb34929ce..9a10878b2ad 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -24,7 +24,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt37x"
-#define DRV_VERSION "0.6.9"
+#define DRV_VERSION "0.6.11"
struct hpt_clock {
u8 xfer_speed;
@@ -281,7 +281,7 @@ static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask)
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
mask &= ~ATA_MASK_UDMA;
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
- mask &= ~(0x1F << ATA_SHIFT_UDMA);
+ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(adev, mask);
}
@@ -297,7 +297,7 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
{
if (adev->class == ATA_DEV_ATA) {
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
- mask &= ~ (0x1F << ATA_SHIFT_UDMA);
+ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(adev, mask);
}
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index 5b8586dac63..f97068be2d7 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -304,12 +304,6 @@ static int icside_dma_init(struct pata_icside_info *info)
}
-static int pata_icside_port_start(struct ata_port *ap)
-{
- /* No PRD to alloc */
- return ata_pad_alloc(ap, ap->dev);
-}
-
static struct scsi_host_template pata_icside_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -389,8 +383,6 @@ static struct ata_port_operations pata_icside_port_ops = {
.irq_clear = ata_dummy_noret,
.irq_on = ata_irq_on,
- .port_start = pata_icside_port_start,
-
.bmdma_stop = pata_icside_bmdma_stop,
.bmdma_status = pata_icside_bmdma_status,
};
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 5b8174d9406..00bbbbd50e9 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -115,7 +115,8 @@ static int jmicron_pre_reset(struct ata_link *link, unsigned long deadline)
static void jmicron_error_handler(struct ata_port *ap)
{
- return ata_bmdma_drive_eh(ap, jmicron_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ ata_bmdma_drive_eh(ap, jmicron_pre_reset, ata_std_softreset, NULL,
+ ata_std_postreset);
}
/* No PIO or DMA methods needed for this device */
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 6c59969fd50..50fe08ebe23 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -774,14 +774,14 @@ static struct ata_port_operations opti82c46x_port_ops = {
static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
- struct legacy_data *qdi = ap->host->private_data;
+ struct legacy_data *ld_qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
- if (qdi->fast) {
+ if (ld_qdi->fast) {
active = 8 - FIT(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18);
} else {
@@ -790,9 +790,9 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
timing = (recovery << 4) | active | 0x08;
- qdi->clock[adev->devno] = timing;
+ ld_qdi->clock[adev->devno] = timing;
- outb(timing, qdi->timing);
+ outb(timing, ld_qdi->timing);
}
/**
@@ -808,14 +808,14 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
- struct legacy_data *qdi = ap->host->private_data;
+ struct legacy_data *ld_qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
- if (qdi->fast) {
+ if (ld_qdi->fast) {
active = 8 - FIT(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18);
} else {
@@ -824,12 +824,12 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
timing = (recovery << 4) | active | 0x08;
- qdi->clock[adev->devno] = timing;
+ ld_qdi->clock[adev->devno] = timing;
- outb(timing, qdi->timing + 2 * ap->port_no);
+ outb(timing, ld_qdi->timing + 2 * ap->port_no);
/* Clear the FIFO */
if (adev->class != ATA_DEV_ATA)
- outb(0x5F, qdi->timing + 3);
+ outb(0x5F, ld_qdi->timing + 3);
}
/**
@@ -845,14 +845,14 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
- struct legacy_data *qdi = ap->host->private_data;
+ struct legacy_data *ld_qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
- if (qdi->fast) {
+ if (ld_qdi->fast) {
active = 8 - FIT(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18);
} else {
@@ -860,11 +860,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
recovery = 15 - FIT(t.recover, 0, 15);
}
timing = (recovery << 4) | active | 0x08;
- qdi->clock[adev->devno] = timing;
- outb(timing, qdi->timing + 2 * adev->devno);
+ ld_qdi->clock[adev->devno] = timing;
+ outb(timing, ld_qdi->timing + 2 * adev->devno);
/* Clear the FIFO */
if (adev->class != ATA_DEV_ATA)
- outb(0x5F, qdi->timing + 3);
+ outb(0x5F, ld_qdi->timing + 3);
}
/**
@@ -879,12 +879,12 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
- struct legacy_data *qdi = ap->host->private_data;
+ struct legacy_data *ld_qdi = ap->host->private_data;
- if (qdi->clock[adev->devno] != qdi->last) {
+ if (ld_qdi->clock[adev->devno] != ld_qdi->last) {
if (adev->pio_mode) {
- qdi->last = qdi->clock[adev->devno];
- outb(qdi->clock[adev->devno], qdi->timing +
+ ld_qdi->last = ld_qdi->clock[adev->devno];
+ outb(ld_qdi->clock[adev->devno], ld_qdi->timing +
2 * ap->port_no);
}
}
@@ -1037,12 +1037,12 @@ static u8 winbond_readcfg(unsigned long port, u8 reg)
static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
- struct legacy_data *winbond = ap->host->private_data;
+ struct legacy_data *ld_winbond = ap->host->private_data;
int active, recovery;
u8 reg;
int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2);
- reg = winbond_readcfg(winbond->timing, 0x81);
+ reg = winbond_readcfg(ld_winbond->timing, 0x81);
/* Get the timing data in cycles */
if (reg & 0x40) /* Fast VLB bus, assume 50MHz */
@@ -1053,7 +1053,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
active = (FIT(t.active, 3, 17) - 1) & 0x0F;
recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F;
timing = (active << 4) | recovery;
- winbond_writecfg(winbond->timing, timing, reg);
+ winbond_writecfg(ld_winbond->timing, timing, reg);
/* Load the setup timing */
@@ -1063,7 +1063,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
if (!ata_pio_need_iordy(adev))
reg |= 0x02; /* IORDY off */
reg |= (FIT(t.setup, 0, 3) << 6);
- winbond_writecfg(winbond->timing, timing + 1, reg);
+ winbond_writecfg(ld_winbond->timing, timing + 1, reg);
}
static int winbond_port(struct platform_device *dev,
@@ -1278,8 +1278,6 @@ static __init int legacy_init_one(struct legacy_probe *probe)
}
}
fail:
- if (host)
- ata_host_detach(host);
platform_device_unregister(pdev);
return ret;
}
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index 9afc8a32b22..a81f25d8723 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -85,8 +85,8 @@ static int marvell_cable_detect(struct ata_port *ap)
static void marvell_error_handler(struct ata_port *ap)
{
- return ata_bmdma_drive_eh(ap, marvell_pre_reset, ata_std_softreset,
- NULL, ata_std_postreset);
+ ata_bmdma_drive_eh(ap, marvell_pre_reset, ata_std_softreset, NULL,
+ ata_std_postreset);
}
/* No PIO or DMA methods needed for this device */
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index 55055b27524..6c016deeaed 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -1007,6 +1007,8 @@ static const struct ata_port_operations scc_pata_ops = {
.qc_issue = ata_qc_issue_prot,
.freeze = scc_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+
.error_handler = scc_error_handler,
.post_internal_cmd = scc_bmdma_stop,
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index 9c523fbf529..a589c0fa0db 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -226,7 +226,7 @@ static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned lo
for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
if (!strcmp(p, model_num))
- mask &= ~(0x1F << ATA_SHIFT_UDMA);
+ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(adev, mask);
}
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index efcb66b6cce..07791a7a48a 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -335,7 +335,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,
dma_addr_t indirect_ext_segment_paddr;
unsigned int si;
- VPRINTK("SATA FSL : cd = 0x%x, prd = 0x%x\n", cmd_desc, prd);
+ VPRINTK("SATA FSL : cd = 0x%p, prd = 0x%p\n", cmd_desc, prd);
indirect_ext_segment_paddr = cmd_desc_paddr +
SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16;
@@ -459,7 +459,8 @@ static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc)
VPRINTK("CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x\n",
ioread32(CE + hcr_base),
ioread32(DE + hcr_base),
- ioread32(CC + hcr_base), ioread32(COMMANDSTAT + csr_base));
+ ioread32(CC + hcr_base),
+ ioread32(COMMANDSTAT + host_priv->csr_base));
return 0;
}
@@ -522,7 +523,8 @@ static void sata_fsl_freeze(struct ata_port *ap)
ioread32(CQ + hcr_base),
ioread32(CA + hcr_base),
ioread32(CE + hcr_base), ioread32(DE + hcr_base));
- VPRINTK("CmdStat = 0x%x\n", ioread32(csr_base + COMMANDSTAT));
+ VPRINTK("CmdStat = 0x%x\n",
+ ioread32(host_priv->csr_base + COMMANDSTAT));
/* disable interrupts on the controller/port */
temp = ioread32(hcr_base + HCONTROL);
@@ -601,21 +603,9 @@ static int sata_fsl_port_start(struct ata_port *ap)
if (!pp)
return -ENOMEM;
- /*
- * allocate per command dma alignment pad buffer, which is used
- * internally by libATA to ensure that all transfers ending on
- * unaligned boundaries are padded, to align on Dword boundaries
- */
- retval = ata_pad_alloc(ap, dev);
- if (retval) {
- kfree(pp);
- return retval;
- }
-
mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma,
GFP_KERNEL);
if (!mem) {
- ata_pad_free(ap, dev);
kfree(pp);
return -ENOMEM;
}
@@ -694,7 +684,6 @@ static void sata_fsl_port_stop(struct ata_port *ap)
dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ,
pp->cmdslot, pp->cmdslot_paddr);
- ata_pad_free(ap, dev);
kfree(pp);
}
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 04b571764af..6ebebde8454 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -870,7 +870,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
struct mv_host_priv *hpriv = ap->host->private_data;
int hard_port = mv_hardport_from_port(ap->port_no);
void __iomem *hc_mmio = mv_hc_base_from_port(
- ap->host->iomap[MV_PRIMARY_BAR], hard_port);
+ mv_host_base(ap->host), hard_port);
u32 hc_irq_cause, ipending;
/* clear EDMA event indicators, if any */
@@ -1158,17 +1158,13 @@ static int mv_port_start(struct ata_port *ap)
struct mv_port_priv *pp;
void __iomem *port_mmio = mv_ap_base(ap);
unsigned long flags;
- int tag, rc;
+ int tag;
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
return -ENOMEM;
ap->private_data = pp;
- rc = ata_pad_alloc(ap, dev);
- if (rc)
- return rc;
-
pp->crqb = dma_pool_alloc(hpriv->crqb_pool, GFP_KERNEL, &pp->crqb_dma);
if (!pp->crqb)
return -ENOMEM;
@@ -1542,7 +1538,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
eh_freeze_mask = EDMA_EH_FREEZE_5;
if (edma_err_cause & EDMA_ERR_SELF_DIS_5) {
- struct mv_port_priv *pp = ap->private_data;
+ pp = ap->private_data;
pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
ata_ehi_push_desc(ehi, "EDMA self-disable");
}
@@ -1550,7 +1546,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
eh_freeze_mask = EDMA_EH_FREEZE;
if (edma_err_cause & EDMA_ERR_SELF_DIS) {
- struct mv_port_priv *pp = ap->private_data;
+ pp = ap->private_data;
pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
ata_ehi_push_desc(ehi, "EDMA self-disable");
}
@@ -2951,7 +2947,8 @@ static int mv_platform_probe(struct platform_device *pdev)
hpriv->n_ports = n_ports;
host->iomap = NULL;
- hpriv->base = ioremap(res->start, res->end - res->start + 1);
+ hpriv->base = devm_ioremap(&pdev->dev, res->start,
+ res->end - res->start + 1);
hpriv->base -= MV_SATAHC0_REG_BASE;
rc = mv_create_dma_pools(hpriv, &pdev->dev);
@@ -2983,11 +2980,8 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ata_host *host = dev_get_drvdata(dev);
- struct mv_host_priv *hpriv = host->private_data;
- void __iomem *base = hpriv->base;
ata_host_detach(host);
- iounmap(base);
return 0;
}
@@ -3198,6 +3192,7 @@ MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:sata_mv");
#ifdef CONFIG_PCI
module_param(msi, int, 0444);
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index a07d319f6e8..f251a5f569d 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -543,7 +543,7 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc)
idx = 0;
for_each_sg(qc->sg, sg, qc->n_elem, si) {
u32 addr, offset;
- u32 sg_len, len;
+ u32 sg_len;
/* determine if physical DMA addr spans 64K boundary.
* Note h/w doesn't support 64-bit, so we unconditionally
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index b4b1f91ea69..df7988df790 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -1234,7 +1234,6 @@ static int sil24_port_start(struct ata_port *ap)
union sil24_cmd_block *cb;
size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS;
dma_addr_t cb_dma;
- int rc;
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
@@ -1247,10 +1246,6 @@ static int sil24_port_start(struct ata_port *ap)
return -ENOMEM;
memset(cb, 0, cb_size);
- rc = ata_pad_alloc(ap, dev);
- if (rc)
- return rc;
-
pp->cmd_block = cb;
pp->cmd_block_dma = cb_dma;
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 69f651e0bc9..840d1c4a785 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -45,6 +45,8 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi.h>
#include <linux/libata.h>
#ifdef CONFIG_PPC_OF
@@ -59,6 +61,7 @@ enum {
/* ap->flags bits */
K2_FLAG_SATA_8_PORTS = (1 << 24),
K2_FLAG_NO_ATAPI_DMA = (1 << 25),
+ K2_FLAG_BAR_POS_3 = (1 << 26),
/* Taskfile registers offsets */
K2_SATA_TF_CMD_OFFSET = 0x00,
@@ -88,8 +91,10 @@ enum {
/* Port stride */
K2_SATA_PORT_OFFSET = 0x100,
- board_svw4 = 0,
- board_svw8 = 1,
+ chip_svw4 = 0,
+ chip_svw8 = 1,
+ chip_svw42 = 2, /* bar 3 */
+ chip_svw43 = 3, /* bar 5 */
};
static u8 k2_stat_check_status(struct ata_port *ap);
@@ -97,10 +102,25 @@ static u8 k2_stat_check_status(struct ata_port *ap);
static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
{
+ u8 cmnd = qc->scsicmd->cmnd[0];
+
if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
return -1; /* ATAPI DMA not supported */
+ else {
+ switch (cmnd) {
+ case READ_10:
+ case READ_12:
+ case READ_16:
+ case WRITE_10:
+ case WRITE_12:
+ case WRITE_16:
+ return 0;
+
+ default:
+ return -1;
+ }
- return 0;
+ }
}
static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
@@ -354,7 +374,7 @@ static const struct ata_port_operations k2_sata_ops = {
};
static const struct ata_port_info k2_port_info[] = {
- /* board_svw4 */
+ /* chip_svw4 */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
@@ -363,7 +383,7 @@ static const struct ata_port_info k2_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
- /* board_svw8 */
+ /* chip_svw8 */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
@@ -373,6 +393,24 @@ static const struct ata_port_info k2_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
+ /* chip_svw42 */
+ {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &k2_sata_ops,
+ },
+ /* chip_svw43 */
+ {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &k2_sata_ops,
+ },
};
static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
@@ -402,7 +440,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
{ &k2_port_info[ent->driver_data], NULL };
struct ata_host *host;
void __iomem *mmio_base;
- int n_ports, i, rc;
+ int n_ports, i, rc, bar_pos;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
@@ -416,6 +454,9 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
if (!host)
return -ENOMEM;
+ bar_pos = 5;
+ if (ppi[0]->flags & K2_FLAG_BAR_POS_3)
+ bar_pos = 3;
/*
* If this driver happens to only be useful on Apple's K2, then
* we should check that here as it has a normal Serverworks ID
@@ -428,17 +469,23 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
* Check if we have resources mapped at all (second function may
* have been disabled by firmware)
*/
- if (pci_resource_len(pdev, 5) == 0)
+ if (pci_resource_len(pdev, bar_pos) == 0) {
+ /* In IDE mode we need to pin the device to ensure that
+ pcim_release does not clear the busmaster bit in config
+ space, clearing causes busmaster DMA to fail on
+ ports 3 & 4 */
+ pcim_pin_device(pdev);
return -ENODEV;
+ }
/* Request and iomap PCI regions */
- rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
+ rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME);
if (rc == -EBUSY)
pcim_pin_device(pdev);
if (rc)
return rc;
host->iomap = pcim_iomap_table(pdev);
- mmio_base = host->iomap[5];
+ mmio_base = host->iomap[bar_pos];
/* different controllers have different number of ports - currently 4 or 8 */
/* All ports are on the same function. Multi-function device is no
@@ -483,11 +530,13 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
* controller
* */
static const struct pci_device_id k2_sata_pci_tbl[] = {
- { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 },
- { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 },
- { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw8 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0411), chip_svw43 },
{ }
};
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 30caa033719..0d03f44824f 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -333,8 +333,8 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline)
static void vt6420_error_handler(struct ata_port *ap)
{
- return ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset,
- NULL, ata_std_postreset);
+ ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset, NULL,
+ ata_std_postreset);
}
static int vt6421_pata_cable_detect(struct ata_port *ap)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 055989e9479..2d207ad3033 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -658,9 +658,10 @@ int bus_add_driver(struct device_driver *drv)
pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
+ if (!priv) {
+ error = -ENOMEM;
+ goto out_put_bus;
+ }
klist_init(&priv->klist_devices, NULL, NULL);
priv->driver = drv;
drv->p = priv;
@@ -668,7 +669,7 @@ int bus_add_driver(struct device_driver *drv)
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
"%s", drv->name);
if (error)
- goto out_put_bus;
+ goto out_unregister;
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 9c0070b5bd3..7de543d1d0b 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -621,7 +621,8 @@ static struct kobject *get_device_parent(struct device *dev,
static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
{
/* see if we live in a "glue" directory */
- if (!dev->class || glue_dir->kset != &dev->class->class_dirs)
+ if (!glue_dir || !dev->class ||
+ glue_dir->kset != &dev->class->class_dirs)
return;
kobject_put(glue_dir);
@@ -770,17 +771,10 @@ int device_add(struct device *dev)
struct class_interface *class_intf;
int error;
- error = pm_sleep_lock();
- if (error) {
- dev_warn(dev, "Suspicious %s during suspend\n", __FUNCTION__);
- dump_stack();
- return error;
- }
-
dev = get_device(dev);
if (!dev || !strlen(dev->bus_id)) {
error = -EINVAL;
- goto Error;
+ goto Done;
}
pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__);
@@ -843,11 +837,9 @@ int device_add(struct device *dev)
}
Done:
put_device(dev);
- pm_sleep_unlock();
return error;
BusError:
device_pm_remove(dev);
- dpm_sysfs_remove(dev);
PMError:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index ba75184c653..bf31a0170a4 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -120,6 +120,9 @@ EXPORT_SYMBOL_GPL(driver_remove_file);
/**
* driver_add_kobj - add a kobject below the specified driver
+ * @drv: requesting device driver
+ * @kobj: kobject to add below this driver
+ * @fmt: format string that names the kobject
*
* You really don't want to do this, this is only here due to one looney
* iseries driver, go poke those developers if you are annoyed about
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index bdc03f7e842..d887d5cb5be 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -48,7 +48,6 @@
*/
LIST_HEAD(dpm_active);
-static LIST_HEAD(dpm_locked);
static LIST_HEAD(dpm_off);
static LIST_HEAD(dpm_off_irq);
static LIST_HEAD(dpm_destroy);
@@ -81,28 +80,6 @@ void device_pm_add(struct device *dev)
*/
void device_pm_remove(struct device *dev)
{
- /*
- * If this function is called during a suspend, it will be blocked,
- * because we're holding the device's semaphore at that time, which may
- * lead to a deadlock. In that case we want to print a warning.
- * However, it may also be called by unregister_dropped_devices() with
- * the device's semaphore released, in which case the warning should
- * not be printed.
- */
- if (down_trylock(&dev->sem)) {
- if (down_read_trylock(&pm_sleep_rwsem)) {
- /* No suspend in progress, wait on dev->sem */
- down(&dev->sem);
- up_read(&pm_sleep_rwsem);
- } else {
- /* Suspend in progress, we may deadlock */
- dev_warn(dev, "Suspicious %s during suspend\n",
- __FUNCTION__);
- dump_stack();
- /* The user has been warned ... */
- down(&dev->sem);
- }
- }
pr_debug("PM: Removing info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus",
kobject_name(&dev->kobj));
@@ -110,7 +87,6 @@ void device_pm_remove(struct device *dev)
dpm_sysfs_remove(dev);
list_del_init(&dev->power.entry);
mutex_unlock(&dpm_list_mtx);
- up(&dev->sem);
}
/**
@@ -230,6 +206,8 @@ static int resume_device(struct device *dev)
TRACE_DEVICE(dev);
TRACE_RESUME(0);
+ down(&dev->sem);
+
if (dev->bus && dev->bus->resume) {
dev_dbg(dev,"resuming\n");
error = dev->bus->resume(dev);
@@ -245,6 +223,8 @@ static int resume_device(struct device *dev)
error = dev->class->resume(dev);
}
+ up(&dev->sem);
+
TRACE_RESUME(error);
return error;
}
@@ -266,7 +246,7 @@ static void dpm_resume(void)
struct list_head *entry = dpm_off.next;
struct device *dev = to_device(entry);
- list_move_tail(entry, &dpm_locked);
+ list_move_tail(entry, &dpm_active);
mutex_unlock(&dpm_list_mtx);
resume_device(dev);
mutex_lock(&dpm_list_mtx);
@@ -275,25 +255,6 @@ static void dpm_resume(void)
}
/**
- * unlock_all_devices - Release each device's semaphore
- *
- * Go through the dpm_off list. Put each device on the dpm_active
- * list and unlock it.
- */
-static void unlock_all_devices(void)
-{
- mutex_lock(&dpm_list_mtx);
- while (!list_empty(&dpm_locked)) {
- struct list_head *entry = dpm_locked.prev;
- struct device *dev = to_device(entry);
-
- list_move(entry, &dpm_active);
- up(&dev->sem);
- }
- mutex_unlock(&dpm_list_mtx);
-}
-
-/**
* unregister_dropped_devices - Unregister devices scheduled for removal
*
* Unregister all devices on the dpm_destroy list.
@@ -305,7 +266,6 @@ static void unregister_dropped_devices(void)
struct list_head *entry = dpm_destroy.next;
struct device *dev = to_device(entry);
- up(&dev->sem);
mutex_unlock(&dpm_list_mtx);
/* This also removes the device from the list */
device_unregister(dev);
@@ -324,7 +284,6 @@ void device_resume(void)
{
might_sleep();
dpm_resume();
- unlock_all_devices();
unregister_dropped_devices();
up_write(&pm_sleep_rwsem);
}
@@ -388,18 +347,15 @@ int device_power_down(pm_message_t state)
struct list_head *entry = dpm_off.prev;
struct device *dev = to_device(entry);
- list_del_init(&dev->power.entry);
error = suspend_device_late(dev, state);
if (error) {
printk(KERN_ERR "Could not power down device %s: "
"error %d\n",
kobject_name(&dev->kobj), error);
- if (list_empty(&dev->power.entry))
- list_add(&dev->power.entry, &dpm_off);
break;
}
- if (list_empty(&dev->power.entry))
- list_add(&dev->power.entry, &dpm_off_irq);
+ if (!list_empty(&dev->power.entry))
+ list_move(&dev->power.entry, &dpm_off_irq);
}
if (!error)
@@ -415,10 +371,12 @@ EXPORT_SYMBOL_GPL(device_power_down);
* @dev: Device.
* @state: Power state device is entering.
*/
-int suspend_device(struct device *dev, pm_message_t state)
+static int suspend_device(struct device *dev, pm_message_t state)
{
int error = 0;
+ down(&dev->sem);
+
if (dev->power.power_state.event) {
dev_dbg(dev, "PM: suspend %d-->%d\n",
dev->power.power_state.event, state.event);
@@ -441,6 +399,9 @@ int suspend_device(struct device *dev, pm_message_t state)
error = dev->bus->suspend(dev, state);
suspend_report_result(dev->bus->suspend, error);
}
+
+ up(&dev->sem);
+
return error;
}
@@ -461,13 +422,13 @@ static int dpm_suspend(pm_message_t state)
int error = 0;
mutex_lock(&dpm_list_mtx);
- while (!list_empty(&dpm_locked)) {
- struct list_head *entry = dpm_locked.prev;
+ while (!list_empty(&dpm_active)) {
+ struct list_head *entry = dpm_active.prev;
struct device *dev = to_device(entry);
- list_del_init(&dev->power.entry);
mutex_unlock(&dpm_list_mtx);
error = suspend_device(dev, state);
+ mutex_lock(&dpm_list_mtx);
if (error) {
printk(KERN_ERR "Could not suspend device %s: "
"error %d%s\n",
@@ -476,15 +437,10 @@ static int dpm_suspend(pm_message_t state)
(error == -EAGAIN ?
" (please convert to suspend_late)" :
""));
- mutex_lock(&dpm_list_mtx);
- if (list_empty(&dev->power.entry))
- list_add(&dev->power.entry, &dpm_locked);
- mutex_unlock(&dpm_list_mtx);
break;
}
- mutex_lock(&dpm_list_mtx);
- if (list_empty(&dev->power.entry))
- list_add(&dev->power.entry, &dpm_off);
+ if (!list_empty(&dev->power.entry))
+ list_move(&dev->power.entry, &dpm_off);
}
mutex_unlock(&dpm_list_mtx);
@@ -492,37 +448,8 @@ static int dpm_suspend(pm_message_t state)
}
/**
- * lock_all_devices - Acquire every device's semaphore
- *
- * Go through the dpm_active list. Carefully lock each device's
- * semaphore and put it in on the dpm_locked list.
- */
-static void lock_all_devices(void)
-{
- mutex_lock(&dpm_list_mtx);
- while (!list_empty(&dpm_active)) {
- struct list_head *entry = dpm_active.next;
- struct device *dev = to_device(entry);
-
- /* Required locking order is dev->sem first,
- * then dpm_list_mutex. Hence this awkward code.
- */
- get_device(dev);
- mutex_unlock(&dpm_list_mtx);
- down(&dev->sem);
- mutex_lock(&dpm_list_mtx);
-
- if (list_empty(entry))
- up(&dev->sem); /* Device was removed */
- else
- list_move_tail(entry, &dpm_locked);
- put_device(dev);
- }
- mutex_unlock(&dpm_list_mtx);
-}
-
-/**
* device_suspend - Save state and stop all devices in system.
+ * @state: new power management state
*
* Prevent new devices from being registered, then lock all devices
* and suspend them.
@@ -533,7 +460,6 @@ int device_suspend(pm_message_t state)
might_sleep();
down_write(&pm_sleep_rwsem);
- lock_all_devices();
error = dpm_suspend(state);
if (error)
device_resume();
diff --git a/drivers/base/transport_class.c b/drivers/base/transport_class.c
index f25e7c6b2d2..40bca48abc1 100644
--- a/drivers/base/transport_class.c
+++ b/drivers/base/transport_class.c
@@ -126,9 +126,7 @@ static int transport_setup_classdev(struct attribute_container *cont,
}
/**
- * transport_setup_device - declare a new dev for transport class association
- * but don't make it visible yet.
- *
+ * transport_setup_device - declare a new dev for transport class association but don't make it visible yet.
* @dev: the generic device representing the entity being added
*
* Usually, dev represents some component in the HBA system (either
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 9715be3f248..55bd35c0f08 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -33,6 +33,7 @@
#include <linux/blkpg.h>
#include <linux/timer.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/hdreg.h>
#include <linux/spinlock.h>
@@ -131,7 +132,6 @@ static struct board_type products[] = {
/*define how many times we will try a command because of bus resets */
#define MAX_CMD_RETRIES 3
-#define READ_AHEAD 1024
#define MAX_CTLR 32
/* Originally cciss driver only supports 8 major numbers */
@@ -174,8 +174,6 @@ static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
static void fail_all_cmds(unsigned long ctlr);
#ifdef CONFIG_PROC_FS
-static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data);
static void cciss_procinit(int i);
#else
static void cciss_procinit(int i)
@@ -240,24 +238,46 @@ static inline CommandList_struct *removeQ(CommandList_struct **Qptr,
*/
#define ENG_GIG 1000000000
#define ENG_GIG_FACTOR (ENG_GIG/512)
+#define ENGAGE_SCSI "engage scsi"
static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
"UNKNOWN"
};
static struct proc_dir_entry *proc_cciss;
-static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data)
+static void cciss_seq_show_header(struct seq_file *seq)
{
- off_t pos = 0;
- off_t len = 0;
- int size, i, ctlr;
- ctlr_info_t *h = (ctlr_info_t *) data;
- drive_info_struct *drv;
- unsigned long flags;
- sector_t vol_sz, vol_sz_frac;
+ ctlr_info_t *h = seq->private;
+
+ seq_printf(seq, "%s: HP %s Controller\n"
+ "Board ID: 0x%08lx\n"
+ "Firmware Version: %c%c%c%c\n"
+ "IRQ: %d\n"
+ "Logical drives: %d\n"
+ "Current Q depth: %d\n"
+ "Current # commands on controller: %d\n"
+ "Max Q depth since init: %d\n"
+ "Max # commands on controller since init: %d\n"
+ "Max SG entries since init: %d\n",
+ h->devname,
+ h->product_name,
+ (unsigned long)h->board_id,
+ h->firm_ver[0], h->firm_ver[1], h->firm_ver[2],
+ h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT],
+ h->num_luns,
+ h->Qdepth, h->commands_outstanding,
+ h->maxQsinceinit, h->max_outstanding, h->maxSG);
- ctlr = h->ctlr;
+#ifdef CONFIG_CISS_SCSI_TAPE
+ cciss_seq_tape_report(seq, h->ctlr);
+#endif /* CONFIG_CISS_SCSI_TAPE */
+}
+
+static void *cciss_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ ctlr_info_t *h = seq->private;
+ unsigned ctlr = h->ctlr;
+ unsigned long flags;
/* prevent displaying bogus info during configuration
* or deconfiguration of a logical volume
@@ -265,115 +285,155 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
if (h->busy_configuring) {
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
- return -EBUSY;
+ return ERR_PTR(-EBUSY);
}
h->busy_configuring = 1;
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
- size = sprintf(buffer, "%s: HP %s Controller\n"
- "Board ID: 0x%08lx\n"
- "Firmware Version: %c%c%c%c\n"
- "IRQ: %d\n"
- "Logical drives: %d\n"
- "Max sectors: %d\n"
- "Current Q depth: %d\n"
- "Current # commands on controller: %d\n"
- "Max Q depth since init: %d\n"
- "Max # commands on controller since init: %d\n"
- "Max SG entries since init: %d\n\n",
- h->devname,
- h->product_name,
- (unsigned long)h->board_id,
- h->firm_ver[0], h->firm_ver[1], h->firm_ver[2],
- h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT],
- h->num_luns,
- h->cciss_max_sectors,
- h->Qdepth, h->commands_outstanding,
- h->maxQsinceinit, h->max_outstanding, h->maxSG);
-
- pos += size;
- len += size;
- cciss_proc_tape_report(ctlr, buffer, &pos, &len);
- for (i = 0; i <= h->highest_lun; i++) {
-
- drv = &h->drv[i];
- if (drv->heads == 0)
- continue;
+ if (*pos == 0)
+ cciss_seq_show_header(seq);
- vol_sz = drv->nr_blocks;
- vol_sz_frac = sector_div(vol_sz, ENG_GIG_FACTOR);
- vol_sz_frac *= 100;
- sector_div(vol_sz_frac, ENG_GIG_FACTOR);
+ return pos;
+}
+
+static int cciss_seq_show(struct seq_file *seq, void *v)
+{
+ sector_t vol_sz, vol_sz_frac;
+ ctlr_info_t *h = seq->private;
+ unsigned ctlr = h->ctlr;
+ loff_t *pos = v;
+ drive_info_struct *drv = &h->drv[*pos];
+
+ if (*pos > h->highest_lun)
+ return 0;
+
+ if (drv->heads == 0)
+ return 0;
+
+ vol_sz = drv->nr_blocks;
+ vol_sz_frac = sector_div(vol_sz, ENG_GIG_FACTOR);
+ vol_sz_frac *= 100;
+ sector_div(vol_sz_frac, ENG_GIG_FACTOR);
+
+ if (drv->raid_level > 5)
+ drv->raid_level = RAID_UNKNOWN;
+ seq_printf(seq, "cciss/c%dd%d:"
+ "\t%4u.%02uGB\tRAID %s\n",
+ ctlr, (int) *pos, (int)vol_sz, (int)vol_sz_frac,
+ raid_label[drv->raid_level]);
+ return 0;
+}
+
+static void *cciss_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ctlr_info_t *h = seq->private;
+
+ if (*pos > h->highest_lun)
+ return NULL;
+ *pos += 1;
+
+ return pos;
+}
+
+static void cciss_seq_stop(struct seq_file *seq, void *v)
+{
+ ctlr_info_t *h = seq->private;
+
+ /* Only reset h->busy_configuring if we succeeded in setting
+ * it during cciss_seq_start. */
+ if (v == ERR_PTR(-EBUSY))
+ return;
- if (drv->raid_level > 5)
- drv->raid_level = RAID_UNKNOWN;
- size = sprintf(buffer + len, "cciss/c%dd%d:"
- "\t%4u.%02uGB\tRAID %s\n",
- ctlr, i, (int)vol_sz, (int)vol_sz_frac,
- raid_label[drv->raid_level]);
- pos += size;
- len += size;
- }
-
- *eof = 1;
- *start = buffer + offset;
- len -= offset;
- if (len > length)
- len = length;
h->busy_configuring = 0;
- return len;
}
-static int
-cciss_proc_write(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
+static struct seq_operations cciss_seq_ops = {
+ .start = cciss_seq_start,
+ .show = cciss_seq_show,
+ .next = cciss_seq_next,
+ .stop = cciss_seq_stop,
+};
+
+static int cciss_seq_open(struct inode *inode, struct file *file)
{
- unsigned char cmd[80];
- int len;
-#ifdef CONFIG_CISS_SCSI_TAPE
- ctlr_info_t *h = (ctlr_info_t *) data;
- int rc;
+ int ret = seq_open(file, &cciss_seq_ops);
+ struct seq_file *seq = file->private_data;
+
+ if (!ret)
+ seq->private = PDE(inode)->data;
+
+ return ret;
+}
+
+static ssize_t
+cciss_proc_write(struct file *file, const char __user *buf,
+ size_t length, loff_t *ppos)
+{
+ int err;
+ char *buffer;
+
+#ifndef CONFIG_CISS_SCSI_TAPE
+ return -EINVAL;
#endif
- if (count > sizeof(cmd) - 1)
+ if (!buf || length > PAGE_SIZE - 1)
return -EINVAL;
- if (copy_from_user(cmd, buffer, count))
- return -EFAULT;
- cmd[count] = '\0';
- len = strlen(cmd); // above 3 lines ensure safety
- if (len && cmd[len - 1] == '\n')
- cmd[--len] = '\0';
-# ifdef CONFIG_CISS_SCSI_TAPE
- if (strcmp("engage scsi", cmd) == 0) {
+
+ buffer = (char *)__get_free_page(GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ err = -EFAULT;
+ if (copy_from_user(buffer, buf, length))
+ goto out;
+ buffer[length] = '\0';
+
+#ifdef CONFIG_CISS_SCSI_TAPE
+ if (strncmp(ENGAGE_SCSI, buffer, sizeof ENGAGE_SCSI - 1) == 0) {
+ struct seq_file *seq = file->private_data;
+ ctlr_info_t *h = seq->private;
+ int rc;
+
rc = cciss_engage_scsi(h->ctlr);
if (rc != 0)
- return -rc;
- return count;
- }
+ err = -rc;
+ else
+ err = length;
+ } else
+#endif /* CONFIG_CISS_SCSI_TAPE */
+ err = -EINVAL;
/* might be nice to have "disengage" too, but it's not
safely possible. (only 1 module use count, lock issues.) */
-# endif
- return -EINVAL;
+
+out:
+ free_page((unsigned long)buffer);
+ return err;
}
-/*
- * Get us a file in /proc/cciss that says something about each controller.
- * Create /proc/cciss if it doesn't exist yet.
- */
+static struct file_operations cciss_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = cciss_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+ .write = cciss_proc_write,
+};
+
static void __devinit cciss_procinit(int i)
{
struct proc_dir_entry *pde;
- if (proc_cciss == NULL) {
+ if (proc_cciss == NULL)
proc_cciss = proc_mkdir("cciss", proc_root_driver);
- if (!proc_cciss)
- return;
- }
+ if (!proc_cciss)
+ return;
+ pde = proc_create(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP |
+ S_IROTH, proc_cciss,
+ &cciss_proc_fops);
+ if (!pde)
+ return;
- pde = create_proc_read_entry(hba[i]->devname,
- S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH,
- proc_cciss, cciss_proc_get_info, hba[i]);
- pde->write_proc = cciss_proc_write;
+ pde->data = hba[i];
}
#endif /* CONFIG_PROC_FS */
@@ -1341,7 +1401,6 @@ geo_inq:
disk->private_data = &h->drv[drv_index];
/* Set up queue information */
- disk->queue->backing_dev_info.ra_pages = READ_AHEAD;
blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask);
/* This is a hardware imposed limit. */
@@ -3434,7 +3493,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
}
drv->queue = q;
- q->backing_dev_info.ra_pages = READ_AHEAD;
blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);
/* This is a hardware imposed limit. */
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 55178e9973a..45ac09300eb 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -1404,21 +1404,18 @@ cciss_engage_scsi(int ctlr)
}
static void
-cciss_proc_tape_report(int ctlr, unsigned char *buffer, off_t *pos, off_t *len)
+cciss_seq_tape_report(struct seq_file *seq, int ctlr)
{
unsigned long flags;
- int size;
-
- *pos = *pos -1; *len = *len - 1; // cut off the last trailing newline
CPQ_TAPE_LOCK(ctlr, flags);
- size = sprintf(buffer + *len,
+ seq_printf(seq,
"Sequential access devices: %d\n\n",
ccissscsi[ctlr].ndevices);
CPQ_TAPE_UNLOCK(ctlr, flags);
- *pos += size; *len += size;
}
+
/* Need at least one of these error handlers to keep ../scsi/hosts.c from
* complaining. Doing a host- or bus-reset can't do anything good here.
* Despite what it might say in scsi_error.c, there may well be commands
@@ -1498,6 +1495,5 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
#define cciss_scsi_setup(cntl_num)
#define cciss_unregister_scsi(ctlr)
#define cciss_register_scsi(ctlr)
-#define cciss_proc_tape_report(ctlr, buffer, pos, len)
#endif /* CONFIG_CISS_SCSI_TAPE */
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 018753c59b8..b53fdb0a282 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -655,6 +655,7 @@ static int __init nbd_init(void)
for (i = 0; i < nbds_max; i++) {
struct gendisk *disk = alloc_disk(1);
+ elevator_t *old_e;
if (!disk)
goto out;
nbd_dev[i].disk = disk;
@@ -668,6 +669,11 @@ static int __init nbd_init(void)
put_disk(disk);
goto out;
}
+ old_e = disk->queue->elevator;
+ if (elevator_init(disk->queue, "deadline") == 0 ||
+ elevator_init(disk->queue, "noop") == 0) {
+ elevator_exit(old_e);
+ }
}
if (register_blkdev(NBD_MAJOR, "nbd")) {
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 674cd66dcab..18feb1c7c33 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -849,7 +849,8 @@ static int pkt_flush_cache(struct pktcdvd_device *pd)
/*
* speed is given as the normal factor, e.g. 4 for 4x
*/
-static int pkt_set_speed(struct pktcdvd_device *pd, unsigned write_speed, unsigned read_speed)
+static noinline_for_stack int pkt_set_speed(struct pktcdvd_device *pd,
+ unsigned write_speed, unsigned read_speed)
{
struct packet_command cgc;
struct request_sense sense;
@@ -1776,7 +1777,8 @@ static int pkt_get_track_info(struct pktcdvd_device *pd, __u16 track, __u8 type,
return pkt_generic_packet(pd, &cgc);
}
-static int pkt_get_last_written(struct pktcdvd_device *pd, long *last_written)
+static noinline_for_stack int pkt_get_last_written(struct pktcdvd_device *pd,
+ long *last_written)
{
disc_information di;
track_information ti;
@@ -1813,7 +1815,7 @@ static int pkt_get_last_written(struct pktcdvd_device *pd, long *last_written)
/*
* write mode select package based on pd->settings
*/
-static int pkt_set_write_settings(struct pktcdvd_device *pd)
+static noinline_for_stack int pkt_set_write_settings(struct pktcdvd_device *pd)
{
struct packet_command cgc;
struct request_sense sense;
@@ -1972,7 +1974,7 @@ static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di)
return 1;
}
-static int pkt_probe_settings(struct pktcdvd_device *pd)
+static noinline_for_stack int pkt_probe_settings(struct pktcdvd_device *pd)
{
struct packet_command cgc;
unsigned char buf[12];
@@ -2071,7 +2073,8 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
/*
* enable/disable write caching on drive
*/
-static int pkt_write_caching(struct pktcdvd_device *pd, int set)
+static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd,
+ int set)
{
struct packet_command cgc;
struct request_sense sense;
@@ -2116,7 +2119,8 @@ static int pkt_lock_door(struct pktcdvd_device *pd, int lockflag)
/*
* Returns drive maximum write speed
*/
-static int pkt_get_max_speed(struct pktcdvd_device *pd, unsigned *write_speed)
+static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd,
+ unsigned *write_speed)
{
struct packet_command cgc;
struct request_sense sense;
@@ -2177,7 +2181,8 @@ static char us_clv_to_speed[16] = {
/*
* reads the maximum media speed from ATIP
*/
-static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
+static noinline_for_stack int pkt_media_speed(struct pktcdvd_device *pd,
+ unsigned *speed)
{
struct packet_command cgc;
struct request_sense sense;
@@ -2249,7 +2254,7 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
}
}
-static int pkt_perform_opc(struct pktcdvd_device *pd)
+static noinline_for_stack int pkt_perform_opc(struct pktcdvd_device *pd)
{
struct packet_command cgc;
struct request_sense sense;
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 8afce67c0aa..9c6f3f99208 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -37,6 +37,7 @@
#include <linux/interrupt.h>
#include <linux/blkdev.h>
+#include <linux/hdreg.h>
#include <linux/module.h>
#include <xen/xenbus.h>
@@ -135,6 +136,22 @@ static void blkif_restart_queue_callback(void *arg)
schedule_work(&info->work);
}
+int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
+{
+ /* We don't have real geometry info, but let's at least return
+ values consistent with the size of the device */
+ sector_t nsect = get_capacity(bd->bd_disk);
+ sector_t cylinders = nsect;
+
+ hg->heads = 0xff;
+ hg->sectors = 0x3f;
+ sector_div(cylinders, hg->heads * hg->sectors);
+ hg->cylinders = cylinders;
+ if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
+ hg->cylinders = 0xffff;
+ return 0;
+}
+
/*
* blkif_queue_request
*
@@ -937,6 +954,7 @@ static struct block_device_operations xlvbd_block_fops =
.owner = THIS_MODULE,
.open = blkif_open,
.release = blkif_release,
+ .getgeo = blkif_getgeo,
};
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index e68821d074b..7e31d5f1bc8 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -208,6 +208,7 @@ static int hci_uart_close(struct hci_dev *hdev)
return 0;
hci_uart_flush(hdev);
+ hdev->flush = NULL;
return 0;
}
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 372c7ef633d..f16c94cbf48 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -116,6 +116,7 @@ static struct usb_device_id blacklist_ids[] = {
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
/* Broadcom BCM2045 */
+ { USB_DEVICE(0x0a5c, 0x2039), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
{ USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* IBM/Lenovo ThinkPad with Broadcom chip */
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index db259e60289..12f5baea439 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -1152,8 +1152,8 @@ clean_up_and_return:
/* This code is similar to that in open_for_data. The routine is called
whenever an audio play operation is requested.
*/
-int check_for_audio_disc(struct cdrom_device_info * cdi,
- struct cdrom_device_ops * cdo)
+static int check_for_audio_disc(struct cdrom_device_info * cdi,
+ struct cdrom_device_ops * cdo)
{
int ret;
tracktype tracks;
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 87be46406da..d2866999214 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -41,6 +41,7 @@ static int amd_create_page_map(struct amd_page_map *page_map)
if (page_map->real == NULL)
return -ENOMEM;
+#ifndef CONFIG_X86
SetPageReserved(virt_to_page(page_map->real));
global_cache_flush();
page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
@@ -52,6 +53,10 @@ static int amd_create_page_map(struct amd_page_map *page_map)
return -ENOMEM;
}
global_cache_flush();
+#else
+ set_memory_uc((unsigned long)page_map->real, 1);
+ page_map->remapped = page_map->real;
+#endif
for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
writel(agp_bridge->scratch_page, page_map->remapped+i);
@@ -63,8 +68,12 @@ static int amd_create_page_map(struct amd_page_map *page_map)
static void amd_free_page_map(struct amd_page_map *page_map)
{
+#ifndef CONFIG_X86
iounmap(page_map->remapped);
ClearPageReserved(virt_to_page(page_map->real));
+#else
+ set_memory_wb((unsigned long)page_map->real, 1);
+#endif
free_page((unsigned long) page_map->real);
}
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 2d46b713c8f..55c97f62324 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -60,18 +60,9 @@ static int ati_create_page_map(struct ati_page_map *page_map)
if (page_map->real == NULL)
return -ENOMEM;
- SetPageReserved(virt_to_page(page_map->real));
+ set_memory_uc((unsigned long)page_map->real, 1);
err = map_page_into_agp(virt_to_page(page_map->real));
- page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
- PAGE_SIZE);
- if (page_map->remapped == NULL || err) {
- ClearPageReserved(virt_to_page(page_map->real));
- free_page((unsigned long) page_map->real);
- page_map->real = NULL;
- return -ENOMEM;
- }
- /*CACHE_FLUSH();*/
- global_cache_flush();
+ page_map->remapped = page_map->real;
for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
writel(agp_bridge->scratch_page, page_map->remapped+i);
@@ -85,8 +76,7 @@ static int ati_create_page_map(struct ati_page_map *page_map)
static void ati_free_page_map(struct ati_page_map *page_map)
{
unmap_page_from_agp(virt_to_page(page_map->real));
- iounmap(page_map->remapped);
- ClearPageReserved(virt_to_page(page_map->real));
+ set_memory_wb((unsigned long)page_map->real, 1);
free_page((unsigned long) page_map->real);
}
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 7484bc759c4..7fc0c99a3a5 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -932,9 +932,14 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
agp_gatt_table = (void *)table;
bridge->driver->cache_flush();
+#ifdef CONFIG_X86
+ set_memory_uc((unsigned long)table, 1 << page_order);
+ bridge->gatt_table = (void *)table;
+#else
bridge->gatt_table = ioremap_nocache(virt_to_gart(table),
(PAGE_SIZE * (1 << page_order)));
bridge->driver->cache_flush();
+#endif
if (bridge->gatt_table == NULL) {
for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
@@ -991,7 +996,11 @@ int agp_generic_free_gatt_table(struct agp_bridge_data *bridge)
* called, then all agp memory is deallocated and removed
* from the table. */
+#ifdef CONFIG_X86
+ set_memory_wb((unsigned long)bridge->gatt_table, 1 << page_order);
+#else
iounmap(bridge->gatt_table);
+#endif
table = (char *) bridge->gatt_table_real;
table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index eb1a1c73819..b6791846809 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -14,6 +14,9 @@
#define SIS_TLBCNTRL 0x97
#define SIS_TLBFLUSH 0x98
+#define PCI_DEVICE_ID_SI_662 0x0662
+#define PCI_DEVICE_ID_SI_671 0x0671
+
static int __devinitdata agp_sis_force_delay = 0;
static int __devinitdata agp_sis_agp_spec = -1;
@@ -27,8 +30,8 @@ static int sis_fetch_size(void)
values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if ((temp_size == values[i].size_value) ||
- ((temp_size & ~(0x03)) ==
- (values[i].size_value & ~(0x03)))) {
+ ((temp_size & ~(0x07)) ==
+ (values[i].size_value & ~(0x07)))) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
@@ -214,6 +217,26 @@ static void __devexit agp_sis_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
+#ifdef CONFIG_PM
+
+static int agp_sis_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ pci_save_state(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static int agp_sis_resume(struct pci_dev *pdev)
+{
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ return sis_driver.configure();
+}
+
+#endif /* CONFIG_PM */
+
static struct pci_device_id agp_sis_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
@@ -331,6 +354,22 @@ static struct pci_device_id agp_sis_pci_table[] = {
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_SI,
+ .device = PCI_DEVICE_ID_SI_662,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
+ {
+ .class = (PCI_CLASS_BRIDGE_HOST << 8),
+ .class_mask = ~0,
+ .vendor = PCI_VENDOR_ID_SI,
+ .device = PCI_DEVICE_ID_SI_671,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
+ {
+ .class = (PCI_CLASS_BRIDGE_HOST << 8),
+ .class_mask = ~0,
+ .vendor = PCI_VENDOR_ID_SI,
.device = PCI_DEVICE_ID_SI_730,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
@@ -393,6 +432,10 @@ static struct pci_driver agp_sis_pci_driver = {
.id_table = agp_sis_pci_table,
.probe = agp_sis_probe,
.remove = agp_sis_remove,
+#ifdef CONFIG_PM
+ .suspend = agp_sis_suspend,
+ .resume = agp_sis_resume,
+#endif
};
static int __init agp_sis_init(void)
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 551ef25063e..e08934e58f3 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -52,28 +52,20 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map)
if (page_map->real == NULL) {
return -ENOMEM;
}
- SetPageReserved(virt_to_page(page_map->real));
- global_cache_flush();
- page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
- PAGE_SIZE);
- if (page_map->remapped == NULL) {
- ClearPageReserved(virt_to_page(page_map->real));
- free_page((unsigned long) page_map->real);
- page_map->real = NULL;
- return -ENOMEM;
- }
- global_cache_flush();
+
+ set_memory_uc((unsigned long)page_map->real, 1);
+ page_map->remapped = page_map->real;
for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++)
writel(agp_bridge->scratch_page, page_map->remapped+i);
+ /* Red Pen: Everyone else does pci posting flush here */
return 0;
}
static void serverworks_free_page_map(struct serverworks_page_map *page_map)
{
- iounmap(page_map->remapped);
- ClearPageReserved(virt_to_page(page_map->real));
+ set_memory_wb((unsigned long)page_map->real, 1);
free_page((unsigned long) page_map->real);
}
diff --git a/drivers/char/defkeymap.c_shipped b/drivers/char/defkeymap.c_shipped
index 0aa419a6176..d2208dfe3f6 100644
--- a/drivers/char/defkeymap.c_shipped
+++ b/drivers/char/defkeymap.c_shipped
@@ -223,40 +223,40 @@ char *func_table[MAX_NR_FUNC] = {
};
struct kbdiacruc accent_table[MAX_DIACR] = {
- {'`', 'A', '\300'}, {'`', 'a', '\340'},
- {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
- {'^', 'A', '\302'}, {'^', 'a', '\342'},
- {'~', 'A', '\303'}, {'~', 'a', '\343'},
- {'"', 'A', '\304'}, {'"', 'a', '\344'},
- {'O', 'A', '\305'}, {'o', 'a', '\345'},
- {'0', 'A', '\305'}, {'0', 'a', '\345'},
- {'A', 'A', '\305'}, {'a', 'a', '\345'},
- {'A', 'E', '\306'}, {'a', 'e', '\346'},
- {',', 'C', '\307'}, {',', 'c', '\347'},
- {'`', 'E', '\310'}, {'`', 'e', '\350'},
- {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
- {'^', 'E', '\312'}, {'^', 'e', '\352'},
- {'"', 'E', '\313'}, {'"', 'e', '\353'},
- {'`', 'I', '\314'}, {'`', 'i', '\354'},
- {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
- {'^', 'I', '\316'}, {'^', 'i', '\356'},
- {'"', 'I', '\317'}, {'"', 'i', '\357'},
- {'-', 'D', '\320'}, {'-', 'd', '\360'},
- {'~', 'N', '\321'}, {'~', 'n', '\361'},
- {'`', 'O', '\322'}, {'`', 'o', '\362'},
- {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
- {'^', 'O', '\324'}, {'^', 'o', '\364'},
- {'~', 'O', '\325'}, {'~', 'o', '\365'},
- {'"', 'O', '\326'}, {'"', 'o', '\366'},
- {'/', 'O', '\330'}, {'/', 'o', '\370'},
- {'`', 'U', '\331'}, {'`', 'u', '\371'},
- {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
- {'^', 'U', '\333'}, {'^', 'u', '\373'},
- {'"', 'U', '\334'}, {'"', 'u', '\374'},
- {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
- {'T', 'H', '\336'}, {'t', 'h', '\376'},
- {'s', 's', '\337'}, {'"', 'y', '\377'},
- {'s', 'z', '\337'}, {'i', 'j', '\377'},
+ {'`', 'A', 0300}, {'`', 'a', 0340},
+ {'\'', 'A', 0301}, {'\'', 'a', 0341},
+ {'^', 'A', 0302}, {'^', 'a', 0342},
+ {'~', 'A', 0303}, {'~', 'a', 0343},
+ {'"', 'A', 0304}, {'"', 'a', 0344},
+ {'O', 'A', 0305}, {'o', 'a', 0345},
+ {'0', 'A', 0305}, {'0', 'a', 0345},
+ {'A', 'A', 0305}, {'a', 'a', 0345},
+ {'A', 'E', 0306}, {'a', 'e', 0346},
+ {',', 'C', 0307}, {',', 'c', 0347},
+ {'`', 'E', 0310}, {'`', 'e', 0350},
+ {'\'', 'E', 0311}, {'\'', 'e', 0351},
+ {'^', 'E', 0312}, {'^', 'e', 0352},
+ {'"', 'E', 0313}, {'"', 'e', 0353},
+ {'`', 'I', 0314}, {'`', 'i', 0354},
+ {'\'', 'I', 0315}, {'\'', 'i', 0355},
+ {'^', 'I', 0316}, {'^', 'i', 0356},
+ {'"', 'I', 0317}, {'"', 'i', 0357},
+ {'-', 'D', 0320}, {'-', 'd', 0360},
+ {'~', 'N', 0321}, {'~', 'n', 0361},
+ {'`', 'O', 0322}, {'`', 'o', 0362},
+ {'\'', 'O', 0323}, {'\'', 'o', 0363},
+ {'^', 'O', 0324}, {'^', 'o', 0364},
+ {'~', 'O', 0325}, {'~', 'o', 0365},
+ {'"', 'O', 0326}, {'"', 'o', 0366},
+ {'/', 'O', 0330}, {'/', 'o', 0370},
+ {'`', 'U', 0331}, {'`', 'u', 0371},
+ {'\'', 'U', 0332}, {'\'', 'u', 0372},
+ {'^', 'U', 0333}, {'^', 'u', 0373},
+ {'"', 'U', 0334}, {'"', 'u', 0374},
+ {'\'', 'Y', 0335}, {'\'', 'y', 0375},
+ {'T', 'H', 0336}, {'t', 'h', 0376},
+ {'s', 's', 0337}, {'"', 'y', 0377},
+ {'s', 'z', 0337}, {'i', 'j', 0377},
};
unsigned int accent_table_size = 68;
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 19d3be5c4b2..a6789f25009 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -568,7 +568,7 @@ struct drm_driver {
void (*postclose) (struct drm_device *, struct drm_file *);
void (*lastclose) (struct drm_device *);
int (*unload) (struct drm_device *);
- int (*suspend) (struct drm_device *);
+ int (*suspend) (struct drm_device *, pm_message_t state);
int (*resume) (struct drm_device *);
int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
void (*dma_ready) (struct drm_device *);
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index f5246884367..715b361f0c2 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -83,6 +83,7 @@
{0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
{0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
@@ -236,6 +237,7 @@
{0x1002, 0x7297, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
{0, 0, 0}
#define r128_PCI_IDS \
@@ -313,6 +315,7 @@
{0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
+ {0x1039, 0x6351, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
{0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index fa36153619e..05ed5043254 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -36,7 +36,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
printk(KERN_ERR "%s\n", __FUNCTION__);
if (drm_dev->driver->suspend)
- return drm_dev->driver->suspend(drm_dev);
+ return drm_dev->driver->suspend(drm_dev, state);
return 0;
}
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index cea4105374b..3d65c4dcd0c 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -66,7 +66,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
}
/**
- * \c nopage method for AGP virtual memory.
+ * \c fault method for AGP virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
@@ -76,8 +76,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
* map, get the page, increment the use count and return it.
*/
#if __OS_HAS_AGP
-static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->head->dev;
@@ -89,19 +88,24 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
* Find the right map
*/
if (!drm_core_has_AGP(dev))
- goto vm_nopage_error;
+ goto vm_fault_error;
if (!dev->agp || !dev->agp->cant_use_aperture)
- goto vm_nopage_error;
+ goto vm_fault_error;
if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash))
- goto vm_nopage_error;
+ goto vm_fault_error;
r_list = drm_hash_entry(hash, struct drm_map_list, hash);
map = r_list->map;
if (map && map->type == _DRM_AGP) {
- unsigned long offset = address - vma->vm_start;
+ /*
+ * Using vm_pgoff as a selector forces us to use this unusual
+ * addressing scheme.
+ */
+ unsigned long offset = (unsigned long)vmf->virtual_address -
+ vma->vm_start;
unsigned long baddr = map->offset + offset;
struct drm_agp_mem *agpmem;
struct page *page;
@@ -123,7 +127,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
}
if (!agpmem)
- goto vm_nopage_error;
+ goto vm_fault_error;
/*
* Get the page, inc the use count, and return it
@@ -131,22 +135,21 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
page = virt_to_page(__va(agpmem->memory->memory[offset]));
get_page(page);
+ vmf->page = page;
DRM_DEBUG
("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
baddr, __va(agpmem->memory->memory[offset]), offset,
page_count(page));
-
- return page;
+ return 0;
}
- vm_nopage_error:
- return NOPAGE_SIGBUS; /* Disallow mremap */
+vm_fault_error:
+ return VM_FAULT_SIGBUS; /* Disallow mremap */
}
#else /* __OS_HAS_AGP */
-static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- return NOPAGE_SIGBUS;
+ return VM_FAULT_SIGBUS;
}
#endif /* __OS_HAS_AGP */
@@ -160,28 +163,26 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
* Get the mapping, find the real physical page to map, get the page, and
* return it.
*/
-static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_map *map = (struct drm_map *) vma->vm_private_data;
unsigned long offset;
unsigned long i;
struct page *page;
- if (address > vma->vm_end)
- return NOPAGE_SIGBUS; /* Disallow mremap */
if (!map)
- return NOPAGE_SIGBUS; /* Nothing allocated */
+ return VM_FAULT_SIGBUS; /* Nothing allocated */
- offset = address - vma->vm_start;
+ offset = (unsigned long)vmf->virtual_address - vma->vm_start;
i = (unsigned long)map->handle + offset;
page = vmalloc_to_page((void *)i);
if (!page)
- return NOPAGE_SIGBUS;
+ return VM_FAULT_SIGBUS;
get_page(page);
+ vmf->page = page;
- DRM_DEBUG("0x%lx\n", address);
- return page;
+ DRM_DEBUG("shm_fault 0x%lx\n", offset);
+ return 0;
}
/**
@@ -263,7 +264,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
}
/**
- * \c nopage method for DMA virtual memory.
+ * \c fault method for DMA virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
@@ -271,8 +272,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
*
* Determine the page number from the page offset and get it from drm_device_dma::pagelist.
*/
-static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->head->dev;
@@ -282,24 +282,23 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
struct page *page;
if (!dma)
- return NOPAGE_SIGBUS; /* Error */
- if (address > vma->vm_end)
- return NOPAGE_SIGBUS; /* Disallow mremap */
+ return VM_FAULT_SIGBUS; /* Error */
if (!dma->pagelist)
- return NOPAGE_SIGBUS; /* Nothing allocated */
+ return VM_FAULT_SIGBUS; /* Nothing allocated */
- offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
- page_nr = offset >> PAGE_SHIFT;
+ offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
+ page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */
page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));
get_page(page);
+ vmf->page = page;
- DRM_DEBUG("0x%lx (page %lu)\n", address, page_nr);
- return page;
+ DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr);
+ return 0;
}
/**
- * \c nopage method for scatter-gather virtual memory.
+ * \c fault method for scatter-gather virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
@@ -307,8 +306,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
*
* Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
*/
-static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_map *map = (struct drm_map *) vma->vm_private_data;
struct drm_file *priv = vma->vm_file->private_data;
@@ -320,77 +318,64 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
struct page *page;
if (!entry)
- return NOPAGE_SIGBUS; /* Error */
- if (address > vma->vm_end)
- return NOPAGE_SIGBUS; /* Disallow mremap */
+ return VM_FAULT_SIGBUS; /* Error */
if (!entry->pagelist)
- return NOPAGE_SIGBUS; /* Nothing allocated */
+ return VM_FAULT_SIGBUS; /* Nothing allocated */
- offset = address - vma->vm_start;
+ offset = (unsigned long)vmf->virtual_address - vma->vm_start;
map_offset = map->offset - (unsigned long)dev->sg->virtual;
page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
page = entry->pagelist[page_offset];
get_page(page);
+ vmf->page = page;
- return page;
+ return 0;
}
-static struct page *drm_vm_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_nopage(vma, address);
+ return drm_do_vm_fault(vma, vmf);
}
-static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_shm_nopage(vma, address);
+ return drm_do_vm_shm_fault(vma, vmf);
}
-static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_dma_nopage(vma, address);
+ return drm_do_vm_dma_fault(vma, vmf);
}
-static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_sg_nopage(vma, address);
+ return drm_do_vm_sg_fault(vma, vmf);
}
/** AGP virtual memory operations */
static struct vm_operations_struct drm_vm_ops = {
- .nopage = drm_vm_nopage,
+ .fault = drm_vm_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};
/** Shared virtual memory operations */
static struct vm_operations_struct drm_vm_shm_ops = {
- .nopage = drm_vm_shm_nopage,
+ .fault = drm_vm_shm_fault,
.open = drm_vm_open,
.close = drm_vm_shm_close,
};
/** DMA virtual memory operations */
static struct vm_operations_struct drm_vm_dma_ops = {
- .nopage = drm_vm_dma_nopage,
+ .fault = drm_vm_dma_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};
/** Scatter-gather virtual memory operations */
static struct vm_operations_struct drm_vm_sg_ops = {
- .nopage = drm_vm_sg_nopage,
+ .fault = drm_vm_sg_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};
@@ -604,7 +589,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
/*
* On some platforms we can't talk to bus dma address from the CPU, so for
* memory of type DRM_AGP, we'll deal with sorting out the real physical
- * pages and mappings in nopage()
+ * pages and mappings in fault()
*/
#if defined(__powerpc__)
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
@@ -634,7 +619,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
break;
case _DRM_CONSISTENT:
/* Consistent memory is really like shared memory. But
- * it's allocated in a different way, so avoid nopage */
+ * it's allocated in a different way, so avoid fault */
if (remap_pfn_range(vma, vma->vm_start,
page_to_pfn(virt_to_page(map->handle)),
vma->vm_end - vma->vm_start, vma->vm_page_prot))
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 43986d81ae3..e9d6663bec7 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -171,7 +171,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->allow_batchbuffer = 1;
/* Program Hardware Status Page */
- if (!IS_G33(dev)) {
+ if (!I915_NEED_GFX_HWS(dev)) {
dev_priv->status_page_dmah =
drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
@@ -720,6 +720,9 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_hws_addr_t *hws = data;
+ if (!I915_NEED_GFX_HWS(dev))
+ return -EINVAL;
+
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 52e51033d32..b2b451dc446 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -160,6 +160,7 @@ static void i915_save_vga(struct drm_device *dev)
dev_priv->saveAR[i] = i915_read_ar(st01, i, 0);
inb(st01);
outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX);
+ inb(st01);
/* Graphics controller registers */
for (i = 0; i < 9; i++)
@@ -221,10 +222,12 @@ static void i915_restore_vga(struct drm_device *dev)
dev_priv->saveGR[0x18]);
/* Attribute controller registers */
+ inb(st01);
for (i = 0; i < 20; i++)
i915_write_ar(st01, i, dev_priv->saveAR[i], 0);
inb(st01); /* switch back to index mode */
outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX);
+ inb(st01);
/* VGA color palette registers */
outb(dev_priv->saveDACMASK, VGA_DACMASK);
@@ -236,7 +239,7 @@ static void i915_restore_vga(struct drm_device *dev)
}
-static int i915_suspend(struct drm_device *dev)
+static int i915_suspend(struct drm_device *dev, pm_message_t state)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
@@ -247,6 +250,9 @@ static int i915_suspend(struct drm_device *dev)
return -ENODEV;
}
+ if (state.event == PM_EVENT_PRETHAW)
+ return 0;
+
pci_save_state(dev->pdev);
pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
@@ -276,6 +282,7 @@ static int i915_suspend(struct drm_device *dev)
dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
}
i915_save_palette(dev, PIPE_A);
+ dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT);
/* Pipe & plane B info */
dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
@@ -303,6 +310,7 @@ static int i915_suspend(struct drm_device *dev)
dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
}
i915_save_palette(dev, PIPE_B);
+ dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT);
/* CRT state */
dev_priv->saveADPA = I915_READ(ADPA);
@@ -329,12 +337,26 @@ static int i915_suspend(struct drm_device *dev)
dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
+ /* Interrupt state */
+ dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R);
+ dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R);
+ dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R);
+
/* VGA state */
dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
+ /* Clock gating state */
+ dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
+
+ /* Cache mode state */
+ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
+
+ /* Memory Arbitration state */
+ dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
+
/* Scratch space */
for (i = 0; i < 16; i++) {
dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
@@ -345,9 +367,11 @@ static int i915_suspend(struct drm_device *dev)
i915_save_vga(dev);
- /* Shut down the device */
- pci_disable_device(dev->pdev);
- pci_set_power_state(dev->pdev, PCI_D3hot);
+ if (state.event == PM_EVENT_SUSPEND) {
+ /* Shut down the device */
+ pci_disable_device(dev->pdev);
+ pci_set_power_state(dev->pdev, PCI_D3hot);
+ }
return 0;
}
@@ -400,9 +424,7 @@ static int i915_resume(struct drm_device *dev)
I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
}
- if ((dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) &&
- (dev_priv->saveDPLL_A & DPLL_VGA_MODE_DIS))
- I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
+ I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
i915_restore_palette(dev, PIPE_A);
/* Enable the plane */
@@ -444,10 +466,9 @@ static int i915_resume(struct drm_device *dev)
I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
}
- if ((dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) &&
- (dev_priv->saveDPLL_B & DPLL_VGA_MODE_DIS))
- I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
- i915_restore_palette(dev, PIPE_A);
+ I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
+
+ i915_restore_palette(dev, PIPE_B);
/* Enable the plane */
I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
@@ -485,6 +506,15 @@ static int i915_resume(struct drm_device *dev)
I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
udelay(150);
+ /* Clock gating state */
+ I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
+
+ /* Cache mode state */
+ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
+
+ /* Memory arbitration state */
+ I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
+
for (i = 0; i < 16; i++) {
I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index f8308bfb261..c10d128e34d 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -134,6 +134,7 @@ typedef struct drm_i915_private {
u32 saveVBLANK_A;
u32 saveVSYNC_A;
u32 saveBCLRPAT_A;
+ u32 savePIPEASTAT;
u32 saveDSPASTRIDE;
u32 saveDSPASIZE;
u32 saveDSPAPOS;
@@ -154,6 +155,7 @@ typedef struct drm_i915_private {
u32 saveVBLANK_B;
u32 saveVSYNC_B;
u32 saveBCLRPAT_B;
+ u32 savePIPEBSTAT;
u32 saveDSPBSTRIDE;
u32 saveDSPBSIZE;
u32 saveDSPBPOS;
@@ -182,6 +184,12 @@ typedef struct drm_i915_private {
u32 saveFBC_LL_BASE;
u32 saveFBC_CONTROL;
u32 saveFBC_CONTROL2;
+ u32 saveIER;
+ u32 saveIIR;
+ u32 saveIMR;
+ u32 saveCACHE_MODE_0;
+ u32 saveDSPCLK_GATE_D;
+ u32 saveMI_ARB_STATE;
u32 saveSWF0[16];
u32 saveSWF1[16];
u32 saveSWF2[3];
@@ -450,6 +458,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
*/
#define DMA_FADD_S 0x20d4
+/* Memory Interface Arbitration State
+ */
+#define MI_ARB_STATE 0x20e4
+
/* Cache mode 0 reg.
* - Manipulating render cache behaviour is central
* to the concept of zone rendering, tuning this reg can help avoid
@@ -460,6 +472,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
* bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
*/
#define Cache_Mode_0 0x2120
+#define CACHE_MODE_0 0x2120
#define CM0_MASK_SHIFT 16
#define CM0_IZ_OPT_DISABLE (1<<6)
#define CM0_ZR_OPT_DISABLE (1<<5)
@@ -655,6 +668,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
/** P1 value is 2 greater than this field */
# define VGA0_PD_P1_MASK (0x1f << 0)
+#define DSPCLK_GATE_D 0x6200
+
/* I830 CRTC registers */
#define HTOTAL_A 0x60000
#define HBLANK_A 0x60004
@@ -1101,6 +1116,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
+#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev))
+
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
#endif
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 5dc799ab86b..833abc7e55f 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -825,11 +825,19 @@ static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
return ret;
}
+static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+ RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
+ return RADEON_READ(RS690_MC_DATA);
+}
+
u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
else
@@ -840,6 +848,8 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
else
@@ -850,6 +860,8 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
else
@@ -1362,6 +1374,70 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
}
}
+/* Enable or disable RS690 GART on the chip */
+static void radeon_set_rs690gart(drm_radeon_private_t *dev_priv, int on)
+{
+ u32 temp;
+
+ if (on) {
+ DRM_DEBUG("programming rs690 gart %08X %08lX %08X\n",
+ dev_priv->gart_vm_start,
+ (long)dev_priv->gart_info.bus_addr,
+ dev_priv->gart_size);
+
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_MISC_CNTL);
+ RS690_WRITE_MCIND(RS690_MC_MISC_CNTL, 0x5000);
+
+ RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
+ RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);
+
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_FEATURE_ID);
+ RS690_WRITE_MCIND(RS690_MC_GART_FEATURE_ID, 0x42040800);
+
+ RS690_WRITE_MCIND(RS690_MC_GART_BASE,
+ dev_priv->gart_info.bus_addr);
+
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_MODE_CONTROL);
+ RS690_WRITE_MCIND(RS690_MC_AGP_MODE_CONTROL, 0x01400000);
+
+ RS690_WRITE_MCIND(RS690_MC_AGP_BASE,
+ (unsigned int)dev_priv->gart_vm_start);
+
+ dev_priv->gart_size = 32*1024*1024;
+ temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
+ 0xffff0000) | (dev_priv->gart_vm_start >> 16));
+
+ RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, temp);
+
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_SIZE);
+ RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
+ RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);
+
+ do {
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
+ if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
+ RS690_MC_GART_CLEAR_DONE)
+ break;
+ DRM_UDELAY(1);
+ } while (1);
+
+ RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
+ RS690_MC_GART_CC_CLEAR);
+ do {
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
+ if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
+ RS690_MC_GART_CLEAR_DONE)
+ break;
+ DRM_UDELAY(1);
+ } while (1);
+
+ RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
+ RS690_MC_GART_CC_NO_CHANGE);
+ } else {
+ RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, RS690_MC_GART_DIS);
+ }
+}
+
static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
@@ -1396,6 +1472,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
+ radeon_set_rs690gart(dev_priv, on);
+ return;
+ }
+
if (dev_priv->flags & RADEON_IS_IGPGART) {
radeon_set_igpgart(dev_priv, on);
return;
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 4434332c79b..173ae620223 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -123,6 +123,7 @@ enum radeon_family {
CHIP_R420,
CHIP_RV410,
CHIP_RS400,
+ CHIP_RS690,
CHIP_RV515,
CHIP_R520,
CHIP_RV530,
@@ -467,6 +468,36 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
#define RADEON_IGPGART_ENABLE 0x38
#define RADEON_IGPGART_UNK_39 0x39
+#define RS690_MC_INDEX 0x78
+# define RS690_MC_INDEX_MASK 0x1ff
+# define RS690_MC_INDEX_WR_EN (1 << 9)
+# define RS690_MC_INDEX_WR_ACK 0x7f
+#define RS690_MC_DATA 0x7c
+
+#define RS690_MC_MISC_CNTL 0x18
+#define RS690_MC_GART_FEATURE_ID 0x2b
+#define RS690_MC_GART_BASE 0x2c
+#define RS690_MC_GART_CACHE_CNTL 0x2e
+# define RS690_MC_GART_CC_NO_CHANGE 0x0
+# define RS690_MC_GART_CC_CLEAR 0x1
+# define RS690_MC_GART_CLEAR_STATUS (1 << 1)
+# define RS690_MC_GART_CLEAR_DONE (0 << 1)
+# define RS690_MC_GART_CLEAR_PENDING (1 << 1)
+#define RS690_MC_AGP_SIZE 0x38
+# define RS690_MC_GART_DIS 0x0
+# define RS690_MC_GART_EN 0x1
+# define RS690_MC_AGP_SIZE_32MB (0 << 1)
+# define RS690_MC_AGP_SIZE_64MB (1 << 1)
+# define RS690_MC_AGP_SIZE_128MB (2 << 1)
+# define RS690_MC_AGP_SIZE_256MB (3 << 1)
+# define RS690_MC_AGP_SIZE_512MB (4 << 1)
+# define RS690_MC_AGP_SIZE_1GB (5 << 1)
+# define RS690_MC_AGP_SIZE_2GB (6 << 1)
+#define RS690_MC_AGP_MODE_CONTROL 0x39
+#define RS690_MC_FB_LOCATION 0x100
+#define RS690_MC_AGP_LOCATION 0x101
+#define RS690_MC_AGP_BASE 0x102
+
#define R520_MC_IND_INDEX 0x70
#define R520_MC_IND_WR_EN (1<<24)
#define R520_MC_IND_DATA 0x74
@@ -1076,6 +1107,13 @@ do { \
RADEON_WRITE(R520_MC_IND_INDEX, 0); \
} while (0)
+#define RS690_WRITE_MCIND( addr, val ) \
+do { \
+ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \
+ RADEON_WRITE(RS690_MC_DATA, val); \
+ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \
+} while (0)
+
#define CP_PACKET0( reg, n ) \
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET0_TABLE( reg, n ) \
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index c01e26d9ee5..f3fe6206734 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -2484,6 +2484,7 @@ static int __init espserial_init(void)
return 0;
}
+ spin_lock_init(&info->lock);
/* rx_trigger, tx_trigger are needed by autoconfig */
info->config.rx_trigger = rx_trigger;
info->config.tx_trigger = tx_trigger;
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 85d596a3c18..eba2883b630 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1527,7 +1527,7 @@ static int __devinit reset_card(struct pci_dev *pdev,
msleep(10);
portcount = inw(base + 0x2);
- if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 &&
+ if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
portcount != 8 && portcount != 16)) {
dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
card + 1);
diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c
index ff35230058d..d793e68b3e0 100644
--- a/drivers/char/pcmcia/ipwireless/network.c
+++ b/drivers/char/pcmcia/ipwireless/network.c
@@ -377,13 +377,16 @@ void ipwireless_network_packet_received(struct ipw_network *network,
for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) {
struct ipw_tty *tty = network->associated_ttys[channel_idx][i];
+ if (!tty)
+ continue;
+
/*
* If it's associated with a tty (other than the RAS channel
* when we're online), then send the data to that tty. The RAS
* channel's data is handled above - it always goes through
* ppp_generic.
*/
- if (tty && channel_idx == IPW_CHANNEL_RAS
+ if (channel_idx == IPW_CHANNEL_RAS
&& (network->ras_control_lines &
IPW_CONTROL_LINE_DCD) != 0
&& ipwireless_tty_is_modem(tty)) {
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 78b151c4d20..5c3142b6f1f 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -110,8 +110,8 @@ static int rtc_has_irq = 1;
#define hpet_set_rtc_irq_bit(arg) 0
#define hpet_rtc_timer_init() do { } while (0)
#define hpet_rtc_dropped_irq() 0
-#define hpet_register_irq_handler(h) 0
-#define hpet_unregister_irq_handler(h) 0
+#define hpet_register_irq_handler(h) ({ 0; })
+#define hpet_unregister_irq_handler(h) ({ 0; })
#ifdef RTC_IRQ
static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
{
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index c0e08c7bca2..5ff83df67b4 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -2109,7 +2109,6 @@ static void sx_throttle(struct tty_struct * tty)
sx_out(bp, CD186x_CAR, port_No(port));
spin_unlock_irqrestore(&bp->lock, flags);
if (I_IXOFF(tty)) {
- spin_unlock_irqrestore(&bp->lock, flags);
sx_wait_CCR(bp);
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CCR, CCR_SSCH2);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 367be917506..9b58b894f82 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -702,6 +702,7 @@ void redraw_screen(struct vc_data *vc, int is_switch)
if (is_switch) {
set_leds();
compute_shiftstate();
+ notify_update(vc);
}
}
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.c b/drivers/char/xilinx_hwicap/buffer_icap.c
index dfea2bde162..f577daedb63 100644
--- a/drivers/char/xilinx_hwicap/buffer_icap.c
+++ b/drivers/char/xilinx_hwicap/buffer_icap.c
@@ -73,8 +73,8 @@
#define XHI_BUFFER_START 0
/**
- * buffer_icap_get_status: Get the contents of the status register.
- * @parameter base_address: is the base address of the device
+ * buffer_icap_get_status - Get the contents of the status register.
+ * @base_address: is the base address of the device
*
* The status register contains the ICAP status and the done bit.
*
@@ -94,9 +94,9 @@ static inline u32 buffer_icap_get_status(void __iomem *base_address)
}
/**
- * buffer_icap_get_bram: Reads data from the storage buffer bram.
- * @parameter base_address: contains the base address of the component.
- * @parameter offset: The word offset from which the data should be read.
+ * buffer_icap_get_bram - Reads data from the storage buffer bram.
+ * @base_address: contains the base address of the component.
+ * @offset: The word offset from which the data should be read.
*
* A bram is used as a configuration memory cache. One frame of data can
* be stored in this "storage buffer".
@@ -108,8 +108,8 @@ static inline u32 buffer_icap_get_bram(void __iomem *base_address,
}
/**
- * buffer_icap_busy: Return true if the icap device is busy
- * @parameter base_address: is the base address of the device
+ * buffer_icap_busy - Return true if the icap device is busy
+ * @base_address: is the base address of the device
*
* The queries the low order bit of the status register, which
* indicates whether the current configuration or readback operation
@@ -121,8 +121,8 @@ static inline bool buffer_icap_busy(void __iomem *base_address)
}
/**
- * buffer_icap_busy: Return true if the icap device is not busy
- * @parameter base_address: is the base address of the device
+ * buffer_icap_busy - Return true if the icap device is not busy
+ * @base_address: is the base address of the device
*
* The queries the low order bit of the status register, which
* indicates whether the current configuration or readback operation
@@ -134,9 +134,9 @@ static inline bool buffer_icap_done(void __iomem *base_address)
}
/**
- * buffer_icap_set_size: Set the size register.
- * @parameter base_address: is the base address of the device
- * @parameter data: The size in bytes.
+ * buffer_icap_set_size - Set the size register.
+ * @base_address: is the base address of the device
+ * @data: The size in bytes.
*
* The size register holds the number of 8 bit bytes to transfer between
* bram and the icap (or icap to bram).
@@ -148,9 +148,9 @@ static inline void buffer_icap_set_size(void __iomem *base_address,
}
/**
- * buffer_icap_mSetoffsetReg: Set the bram offset register.
- * @parameter base_address: contains the base address of the device.
- * @parameter data: is the value to be written to the data register.
+ * buffer_icap_set_offset - Set the bram offset register.
+ * @base_address: contains the base address of the device.
+ * @data: is the value to be written to the data register.
*
* The bram offset register holds the starting bram address to transfer
* data from during configuration or write data to during readback.
@@ -162,9 +162,9 @@ static inline void buffer_icap_set_offset(void __iomem *base_address,
}
/**
- * buffer_icap_set_rnc: Set the RNC (Readback not Configure) register.
- * @parameter base_address: contains the base address of the device.
- * @parameter data: is the value to be written to the data register.
+ * buffer_icap_set_rnc - Set the RNC (Readback not Configure) register.
+ * @base_address: contains the base address of the device.
+ * @data: is the value to be written to the data register.
*
* The RNC register determines the direction of the data transfer. It
* controls whether a configuration or readback take place. Writing to
@@ -178,10 +178,10 @@ static inline void buffer_icap_set_rnc(void __iomem *base_address,
}
/**
- * buffer_icap_set_bram: Write data to the storage buffer bram.
- * @parameter base_address: contains the base address of the component.
- * @parameter offset: The word offset at which the data should be written.
- * @parameter data: The value to be written to the bram offset.
+ * buffer_icap_set_bram - Write data to the storage buffer bram.
+ * @base_address: contains the base address of the component.
+ * @offset: The word offset at which the data should be written.
+ * @data: The value to be written to the bram offset.
*
* A bram is used as a configuration memory cache. One frame of data can
* be stored in this "storage buffer".
@@ -193,10 +193,10 @@ static inline void buffer_icap_set_bram(void __iomem *base_address,
}
/**
- * buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter offset: The storage buffer start address.
- * @parameter count: The number of words (32 bit) to read from the
+ * buffer_icap_device_read - Transfer bytes from ICAP to the storage buffer.
+ * @drvdata: a pointer to the drvdata.
+ * @offset: The storage buffer start address.
+ * @count: The number of words (32 bit) to read from the
* device (ICAP).
**/
static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
@@ -227,10 +227,10 @@ static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
};
/**
- * buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter offset: The storage buffer start address.
- * @parameter count: The number of words (32 bit) to read from the
+ * buffer_icap_device_write - Transfer bytes from ICAP to the storage buffer.
+ * @drvdata: a pointer to the drvdata.
+ * @offset: The storage buffer start address.
+ * @count: The number of words (32 bit) to read from the
* device (ICAP).
**/
static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
@@ -261,8 +261,8 @@ static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
};
/**
- * buffer_icap_reset: Reset the logic of the icap device.
- * @parameter drvdata: a pointer to the drvdata.
+ * buffer_icap_reset - Reset the logic of the icap device.
+ * @drvdata: a pointer to the drvdata.
*
* Writing to the status register resets the ICAP logic in an internal
* version of the core. For the version of the core published in EDK,
@@ -274,10 +274,10 @@ void buffer_icap_reset(struct hwicap_drvdata *drvdata)
}
/**
- * buffer_icap_set_configuration: Load a partial bitstream from system memory.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter data: Kernel address of the partial bitstream.
- * @parameter size: the size of the partial bitstream in 32 bit words.
+ * buffer_icap_set_configuration - Load a partial bitstream from system memory.
+ * @drvdata: a pointer to the drvdata.
+ * @data: Kernel address of the partial bitstream.
+ * @size: the size of the partial bitstream in 32 bit words.
**/
int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
u32 size)
@@ -333,10 +333,10 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
};
/**
- * buffer_icap_get_configuration: Read configuration data from the device.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter data: Address of the data representing the partial bitstream
- * @parameter size: the size of the partial bitstream in 32 bit words.
+ * buffer_icap_get_configuration - Read configuration data from the device.
+ * @drvdata: a pointer to the drvdata.
+ * @data: Address of the data representing the partial bitstream
+ * @size: the size of the partial bitstream in 32 bit words.
**/
int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
u32 size)
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.c b/drivers/char/xilinx_hwicap/fifo_icap.c
index 0988314694a..6f45dbd4712 100644
--- a/drivers/char/xilinx_hwicap/fifo_icap.c
+++ b/drivers/char/xilinx_hwicap/fifo_icap.c
@@ -94,9 +94,9 @@
/**
- * fifo_icap_fifo_write: Write data to the write FIFO.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter data: the 32-bit value to be written to the FIFO.
+ * fifo_icap_fifo_write - Write data to the write FIFO.
+ * @drvdata: a pointer to the drvdata.
+ * @data: the 32-bit value to be written to the FIFO.
*
* This function will silently fail if the fifo is full.
**/
@@ -108,8 +108,8 @@ static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata,
}
/**
- * fifo_icap_fifo_read: Read data from the Read FIFO.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_fifo_read - Read data from the Read FIFO.
+ * @drvdata: a pointer to the drvdata.
*
* This function will silently fail if the fifo is empty.
**/
@@ -121,9 +121,9 @@ static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata)
}
/**
- * fifo_icap_set_read_size: Set the the size register.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter data: the size of the following read transaction, in words.
+ * fifo_icap_set_read_size - Set the the size register.
+ * @drvdata: a pointer to the drvdata.
+ * @data: the size of the following read transaction, in words.
**/
static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
u32 data)
@@ -132,8 +132,8 @@ static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
}
/**
- * fifo_icap_start_config: Initiate a configuration (write) to the device.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_start_config - Initiate a configuration (write) to the device.
+ * @drvdata: a pointer to the drvdata.
**/
static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
{
@@ -142,8 +142,8 @@ static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
}
/**
- * fifo_icap_start_readback: Initiate a readback from the device.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_start_readback - Initiate a readback from the device.
+ * @drvdata: a pointer to the drvdata.
**/
static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
{
@@ -152,8 +152,8 @@ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
}
/**
- * fifo_icap_busy: Return true if the ICAP is still processing a transaction.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_busy - Return true if the ICAP is still processing a transaction.
+ * @drvdata: a pointer to the drvdata.
**/
static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
{
@@ -163,8 +163,8 @@ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
}
/**
- * fifo_icap_write_fifo_vacancy: Query the write fifo available space.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_write_fifo_vacancy - Query the write fifo available space.
+ * @drvdata: a pointer to the drvdata.
*
* Return the number of words that can be safely pushed into the write fifo.
**/
@@ -175,8 +175,8 @@ static inline u32 fifo_icap_write_fifo_vacancy(
}
/**
- * fifo_icap_read_fifo_occupancy: Query the read fifo available data.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_read_fifo_occupancy - Query the read fifo available data.
+ * @drvdata: a pointer to the drvdata.
*
* Return the number of words that can be safely read from the read fifo.
**/
@@ -187,11 +187,11 @@ static inline u32 fifo_icap_read_fifo_occupancy(
}
/**
- * fifo_icap_set_configuration: Send configuration data to the ICAP.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter frame_buffer: a pointer to the data to be written to the
+ * fifo_icap_set_configuration - Send configuration data to the ICAP.
+ * @drvdata: a pointer to the drvdata.
+ * @frame_buffer: a pointer to the data to be written to the
* ICAP device.
- * @parameter num_words: the number of words (32 bit) to write to the ICAP
+ * @num_words: the number of words (32 bit) to write to the ICAP
* device.
* This function writes the given user data to the Write FIFO in
@@ -266,10 +266,10 @@ int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata,
}
/**
- * fifo_icap_get_configuration: Read configuration data from the device.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter data: Address of the data representing the partial bitstream
- * @parameter size: the size of the partial bitstream in 32 bit words.
+ * fifo_icap_get_configuration - Read configuration data from the device.
+ * @drvdata: a pointer to the drvdata.
+ * @data: Address of the data representing the partial bitstream
+ * @size: the size of the partial bitstream in 32 bit words.
*
* This function reads the specified number of words from the ICAP device in
* the polled mode.
@@ -335,8 +335,8 @@ int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata,
}
/**
- * buffer_icap_reset: Reset the logic of the icap device.
- * @parameter drvdata: a pointer to the drvdata.
+ * buffer_icap_reset - Reset the logic of the icap device.
+ * @drvdata: a pointer to the drvdata.
*
* This function forces the software reset of the complete HWICAP device.
* All the registers will return to the default value and the FIFO is also
@@ -360,8 +360,8 @@ void fifo_icap_reset(struct hwicap_drvdata *drvdata)
}
/**
- * fifo_icap_flush_fifo: This function flushes the FIFOs in the device.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_flush_fifo - This function flushes the FIFOs in the device.
+ * @drvdata: a pointer to the drvdata.
*/
void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata)
{
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 24f6aef0fd3..2284fa2a5a5 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -84,7 +84,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
#include <linux/sysctl.h>
#include <linux/version.h>
#include <linux/fs.h>
@@ -119,6 +119,7 @@ module_param(xhwicap_minor, int, S_IRUGO);
/* An array, which is set to true when the device is registered. */
static bool probed_devices[HWICAP_DEVICES];
+static struct mutex icap_sem;
static struct class *icap_class;
@@ -199,14 +200,14 @@ static const struct config_registers v5_config_registers = {
};
/**
- * hwicap_command_desync: Send a DESYNC command to the ICAP port.
- * @parameter drvdata: a pointer to the drvdata.
+ * hwicap_command_desync - Send a DESYNC command to the ICAP port.
+ * @drvdata: a pointer to the drvdata.
*
* This command desynchronizes the ICAP After this command, a
* bitstream containing a NULL packet, followed by a SYNCH packet is
* required before the ICAP will recognize commands.
*/
-int hwicap_command_desync(struct hwicap_drvdata *drvdata)
+static int hwicap_command_desync(struct hwicap_drvdata *drvdata)
{
u32 buffer[4];
u32 index = 0;
@@ -228,51 +229,18 @@ int hwicap_command_desync(struct hwicap_drvdata *drvdata)
}
/**
- * hwicap_command_capture: Send a CAPTURE command to the ICAP port.
- * @parameter drvdata: a pointer to the drvdata.
- *
- * This command captures all of the flip flop states so they will be
- * available during readback. One can use this command instead of
- * enabling the CAPTURE block in the design.
- */
-int hwicap_command_capture(struct hwicap_drvdata *drvdata)
-{
- u32 buffer[7];
- u32 index = 0;
-
- /*
- * Create the data to be written to the ICAP.
- */
- buffer[index++] = XHI_DUMMY_PACKET;
- buffer[index++] = XHI_SYNC_PACKET;
- buffer[index++] = XHI_NOOP_PACKET;
- buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1;
- buffer[index++] = XHI_CMD_GCAPTURE;
- buffer[index++] = XHI_DUMMY_PACKET;
- buffer[index++] = XHI_DUMMY_PACKET;
-
- /*
- * Write the data to the FIFO and intiate the transfer of data
- * present in the FIFO to the ICAP device.
- */
- return drvdata->config->set_configuration(drvdata,
- &buffer[0], index);
-
-}
-
-/**
- * hwicap_get_configuration_register: Query a configuration register.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter reg: a constant which represents the configuration
+ * hwicap_get_configuration_register - Query a configuration register.
+ * @drvdata: a pointer to the drvdata.
+ * @reg: a constant which represents the configuration
* register value to be returned.
* Examples: XHI_IDCODE, XHI_FLR.
- * @parameter RegData: returns the value of the register.
+ * @reg_data: returns the value of the register.
*
* Sends a query packet to the ICAP and then receives the response.
* The icap is left in Synched state.
*/
-int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
- u32 reg, u32 *RegData)
+static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
+ u32 reg, u32 *reg_data)
{
int status;
u32 buffer[6];
@@ -300,14 +268,14 @@ int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
/*
* Read the configuration register
*/
- status = drvdata->config->get_configuration(drvdata, RegData, 1);
+ status = drvdata->config->get_configuration(drvdata, reg_data, 1);
if (status)
return status;
return 0;
}
-int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
+static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
{
int status;
u32 idcode;
@@ -344,7 +312,7 @@ int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
}
static ssize_t
-hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
struct hwicap_drvdata *drvdata = file->private_data;
ssize_t bytes_to_read = 0;
@@ -353,8 +321,9 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
u32 bytes_remaining;
int status;
- if (down_interruptible(&drvdata->sem))
- return -ERESTARTSYS;
+ status = mutex_lock_interruptible(&drvdata->sem);
+ if (status)
+ return status;
if (drvdata->read_buffer_in_use) {
/* If there are leftover bytes in the buffer, just */
@@ -370,8 +339,9 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
goto error;
}
drvdata->read_buffer_in_use -= bytes_to_read;
- memcpy(drvdata->read_buffer + bytes_to_read,
- drvdata->read_buffer, 4 - bytes_to_read);
+ memmove(drvdata->read_buffer,
+ drvdata->read_buffer + bytes_to_read,
+ 4 - bytes_to_read);
} else {
/* Get new data from the ICAP, and return was was requested. */
kbuf = (u32 *) get_zeroed_page(GFP_KERNEL);
@@ -414,18 +384,20 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
status = -EFAULT;
goto error;
}
- memcpy(kbuf, drvdata->read_buffer, bytes_remaining);
+ memcpy(drvdata->read_buffer,
+ kbuf,
+ bytes_remaining);
drvdata->read_buffer_in_use = bytes_remaining;
free_page((unsigned long)kbuf);
}
status = bytes_to_read;
error:
- up(&drvdata->sem);
+ mutex_unlock(&drvdata->sem);
return status;
}
static ssize_t
-hwicap_write(struct file *file, const char *buf,
+hwicap_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct hwicap_drvdata *drvdata = file->private_data;
@@ -435,8 +407,9 @@ hwicap_write(struct file *file, const char *buf,
ssize_t len;
ssize_t status;
- if (down_interruptible(&drvdata->sem))
- return -ERESTARTSYS;
+ status = mutex_lock_interruptible(&drvdata->sem);
+ if (status)
+ return status;
left += drvdata->write_buffer_in_use;
@@ -465,7 +438,7 @@ hwicap_write(struct file *file, const char *buf,
memcpy(kbuf, drvdata->write_buffer,
drvdata->write_buffer_in_use);
if (copy_from_user(
- (((char *)kbuf) + (drvdata->write_buffer_in_use)),
+ (((char *)kbuf) + drvdata->write_buffer_in_use),
buf + written,
len - (drvdata->write_buffer_in_use))) {
free_page((unsigned long)kbuf);
@@ -508,7 +481,7 @@ hwicap_write(struct file *file, const char *buf,
free_page((unsigned long)kbuf);
status = written;
error:
- up(&drvdata->sem);
+ mutex_unlock(&drvdata->sem);
return status;
}
@@ -519,8 +492,9 @@ static int hwicap_open(struct inode *inode, struct file *file)
drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
- if (down_interruptible(&drvdata->sem))
- return -ERESTARTSYS;
+ status = mutex_lock_interruptible(&drvdata->sem);
+ if (status)
+ return status;
if (drvdata->is_open) {
status = -EBUSY;
@@ -539,7 +513,7 @@ static int hwicap_open(struct inode *inode, struct file *file)
drvdata->is_open = 1;
error:
- up(&drvdata->sem);
+ mutex_unlock(&drvdata->sem);
return status;
}
@@ -549,8 +523,7 @@ static int hwicap_release(struct inode *inode, struct file *file)
int i;
int status = 0;
- if (down_interruptible(&drvdata->sem))
- return -ERESTARTSYS;
+ mutex_lock(&drvdata->sem);
if (drvdata->write_buffer_in_use) {
/* Flush write buffer. */
@@ -569,7 +542,7 @@ static int hwicap_release(struct inode *inode, struct file *file)
error:
drvdata->is_open = 0;
- up(&drvdata->sem);
+ mutex_unlock(&drvdata->sem);
return status;
}
@@ -592,31 +565,36 @@ static int __devinit hwicap_setup(struct device *dev, int id,
dev_info(dev, "Xilinx icap port driver\n");
+ mutex_lock(&icap_sem);
+
if (id < 0) {
for (id = 0; id < HWICAP_DEVICES; id++)
if (!probed_devices[id])
break;
}
if (id < 0 || id >= HWICAP_DEVICES) {
+ mutex_unlock(&icap_sem);
dev_err(dev, "%s%i too large\n", DRIVER_NAME, id);
return -EINVAL;
}
if (probed_devices[id]) {
+ mutex_unlock(&icap_sem);
dev_err(dev, "cannot assign to %s%i; it is already in use\n",
DRIVER_NAME, id);
return -EBUSY;
}
probed_devices[id] = 1;
+ mutex_unlock(&icap_sem);
devt = MKDEV(xhwicap_major, xhwicap_minor + id);
- drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
+ drvdata = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
if (!drvdata) {
dev_err(dev, "Couldn't allocate device private record\n");
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto failed0;
}
- memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata));
dev_set_drvdata(dev, (void *)drvdata);
if (!regs_res) {
@@ -648,7 +626,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
drvdata->config = config;
drvdata->config_regs = config_regs;
- init_MUTEX(&drvdata->sem);
+ mutex_init(&drvdata->sem);
drvdata->is_open = 0;
dev_info(dev, "ioremap %lx to %p with size %x\n",
@@ -663,7 +641,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
goto failed3;
}
/* devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */
- class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME);
+ device_create(icap_class, dev, devt, "%s%d", DRIVER_NAME, id);
return 0; /* success */
failed3:
@@ -675,6 +653,11 @@ static int __devinit hwicap_setup(struct device *dev, int id,
failed1:
kfree(drvdata);
+ failed0:
+ mutex_lock(&icap_sem);
+ probed_devices[id] = 0;
+ mutex_unlock(&icap_sem);
+
return retval;
}
@@ -699,14 +682,16 @@ static int __devexit hwicap_remove(struct device *dev)
if (!drvdata)
return 0;
- class_device_destroy(icap_class, drvdata->devt);
+ device_destroy(icap_class, drvdata->devt);
cdev_del(&drvdata->cdev);
iounmap(drvdata->base_address);
release_mem_region(drvdata->mem_start, drvdata->mem_size);
kfree(drvdata);
dev_set_drvdata(dev, NULL);
- probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0;
+ mutex_lock(&icap_sem);
+ probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0;
+ mutex_unlock(&icap_sem);
return 0; /* success */
}
@@ -821,28 +806,29 @@ static struct of_platform_driver hwicap_of_driver = {
};
/* Registration helpers to keep the number of #ifdefs to a minimum */
-static inline int __devinit hwicap_of_register(void)
+static inline int __init hwicap_of_register(void)
{
pr_debug("hwicap: calling of_register_platform_driver()\n");
return of_register_platform_driver(&hwicap_of_driver);
}
-static inline void __devexit hwicap_of_unregister(void)
+static inline void __exit hwicap_of_unregister(void)
{
of_unregister_platform_driver(&hwicap_of_driver);
}
#else /* CONFIG_OF */
/* CONFIG_OF not enabled; do nothing helpers */
-static inline int __devinit hwicap_of_register(void) { return 0; }
-static inline void __devexit hwicap_of_unregister(void) { }
+static inline int __init hwicap_of_register(void) { return 0; }
+static inline void __exit hwicap_of_unregister(void) { }
#endif /* CONFIG_OF */
-static int __devinit hwicap_module_init(void)
+static int __init hwicap_module_init(void)
{
dev_t devt;
int retval;
icap_class = class_create(THIS_MODULE, "xilinx_config");
+ mutex_init(&icap_sem);
if (xhwicap_major) {
devt = MKDEV(xhwicap_major, xhwicap_minor);
@@ -883,7 +869,7 @@ static int __devinit hwicap_module_init(void)
return retval;
}
-static void __devexit hwicap_module_cleanup(void)
+static void __exit hwicap_module_cleanup(void)
{
dev_t devt = MKDEV(xhwicap_major, xhwicap_minor);
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
index ae771cac162..405fee7e189 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.h
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
@@ -48,9 +48,9 @@ struct hwicap_drvdata {
u8 write_buffer[4];
u32 read_buffer_in_use; /* Always in [0,3] */
u8 read_buffer[4];
- u32 mem_start; /* phys. address of the control registers */
- u32 mem_end; /* phys. address of the control registers */
- u32 mem_size;
+ resource_size_t mem_start;/* phys. address of the control registers */
+ resource_size_t mem_end; /* phys. address of the control registers */
+ resource_size_t mem_size;
void __iomem *base_address;/* virt. address of the control registers */
struct device *dev;
@@ -61,7 +61,7 @@ struct hwicap_drvdata {
const struct config_registers *config_regs;
void *private_data;
bool is_open;
- struct semaphore sem;
+ struct mutex sem;
};
struct hwicap_driver_config {
@@ -164,29 +164,29 @@ struct config_registers {
#define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL
/**
- * hwicap_type_1_read: Generates a Type 1 read packet header.
- * @parameter: Register is the address of the register to be read back.
+ * hwicap_type_1_read - Generates a Type 1 read packet header.
+ * @reg: is the address of the register to be read back.
*
* Generates a Type 1 read packet header, which is used to indirectly
* read registers in the configuration logic. This packet must then
* be sent through the icap device, and a return packet received with
* the information.
**/
-static inline u32 hwicap_type_1_read(u32 Register)
+static inline u32 hwicap_type_1_read(u32 reg)
{
return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
- (Register << XHI_REGISTER_SHIFT) |
+ (reg << XHI_REGISTER_SHIFT) |
(XHI_OP_READ << XHI_OP_SHIFT);
}
/**
- * hwicap_type_1_write: Generates a Type 1 write packet header
- * @parameter: Register is the address of the register to be read back.
+ * hwicap_type_1_write - Generates a Type 1 write packet header
+ * @reg: is the address of the register to be read back.
**/
-static inline u32 hwicap_type_1_write(u32 Register)
+static inline u32 hwicap_type_1_write(u32 reg)
{
return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
- (Register << XHI_REGISTER_SHIFT) |
+ (reg << XHI_REGISTER_SHIFT) |
(XHI_OP_WRITE << XHI_OP_SHIFT);
}
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index fea2d3ed9cb..85e2ba7fcfb 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -47,7 +47,7 @@ static LIST_HEAD(notify_list);
static struct cn_dev cdev;
-int cn_already_initialized = 0;
+static int cn_already_initialized;
/*
* msg->seq and msg->ack are used to determine message genealogy.
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 64926aa990d..35a26a3e5f6 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -671,13 +671,13 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
{
struct cpufreq_policy * policy = to_policy(kobj);
struct freq_attr * fattr = to_attr(attr);
- ssize_t ret;
+ ssize_t ret = -EINVAL;
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
- return -EINVAL;
+ goto no_policy;
if (lock_policy_rwsem_read(policy->cpu) < 0)
- return -EINVAL;
+ goto fail;
if (fattr->show)
ret = fattr->show(policy, buf);
@@ -685,8 +685,9 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
ret = -EIO;
unlock_policy_rwsem_read(policy->cpu);
-
+fail:
cpufreq_cpu_put(policy);
+no_policy:
return ret;
}
@@ -695,13 +696,13 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr,
{
struct cpufreq_policy * policy = to_policy(kobj);
struct freq_attr * fattr = to_attr(attr);
- ssize_t ret;
+ ssize_t ret = -EINVAL;
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
- return -EINVAL;
+ goto no_policy;
if (lock_policy_rwsem_write(policy->cpu) < 0)
- return -EINVAL;
+ goto fail;
if (fattr->store)
ret = fattr->store(policy, buf, count);
@@ -709,8 +710,9 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr,
ret = -EIO;
unlock_policy_rwsem_write(policy->cpu);
-
+fail:
cpufreq_cpu_put(policy);
+no_policy:
return ret;
}
@@ -1006,14 +1008,6 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev)
}
#endif
-
- if (!kobject_get(&data->kobj)) {
- spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
- cpufreq_debug_enable_ratelimit();
- unlock_policy_rwsem_write(cpu);
- return -EFAULT;
- }
-
#ifdef CONFIG_SMP
#ifdef CONFIG_HOTPLUG_CPU
@@ -1783,7 +1777,7 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
return NOTIFY_OK;
}
-static struct notifier_block __cpuinitdata cpufreq_cpu_notifier =
+static struct notifier_block __refdata cpufreq_cpu_notifier =
{
.notifier_call = cpufreq_cpu_callback,
};
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 1b8312b0200..070421a5480 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -323,7 +323,7 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb,
return NOTIFY_OK;
}
-static struct notifier_block cpufreq_stat_cpu_notifier __cpuinitdata =
+static struct notifier_block cpufreq_stat_cpu_notifier __refdata =
{
.notifier_call = cpufreq_stat_cpu_callback,
};
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index a703deffb79..27340a7b19d 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -4,7 +4,7 @@
menuconfig DMADEVICES
bool "DMA Engine support"
- depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
+ depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX || PPC
depends on !HIGHMEM64G
help
DMA engines can do asynchronous data transfers without
@@ -37,6 +37,23 @@ config INTEL_IOP_ADMA
help
Enable support for the Intel(R) IOP Series RAID engines.
+config FSL_DMA
+ bool "Freescale MPC85xx/MPC83xx DMA support"
+ depends on PPC
+ select DMA_ENGINE
+ ---help---
+ Enable support for the Freescale DMA engine. Now, it support
+ MPC8560/40, MPC8555, MPC8548 and MPC8641 processors.
+ The MPC8349, MPC8360 is also supported.
+
+config FSL_DMA_SELFTEST
+ bool "Enable the self test for each DMA channel"
+ depends on FSL_DMA
+ default y
+ ---help---
+ Enable the self test for each DMA channel. A self test will be
+ performed after the channel probed to ensure the DMA works well.
+
config DMA_ENGINE
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index b152cd84e12..c8036d94590 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_NET_DMA) += iovlock.o
obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o
obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
+obj-$(CONFIG_FSL_DMA) += fsldma.o
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
new file mode 100644
index 00000000000..cc9a68158d9
--- /dev/null
+++ b/drivers/dma/fsldma.c
@@ -0,0 +1,1067 @@
+/*
+ * Freescale MPC85xx, MPC83xx DMA Engine support
+ *
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author:
+ * Zhang Wei <wei.zhang@freescale.com>, Jul 2007
+ * Ebony Zhu <ebony.zhu@freescale.com>, May 2007
+ *
+ * Description:
+ * DMA engine driver for Freescale MPC8540 DMA controller, which is
+ * also fit for MPC8560, MPC8555, MPC8548, MPC8641, and etc.
+ * The support for MPC8349 DMA contorller is also added.
+ *
+ * This 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/dmaengine.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/of_platform.h>
+
+#include "fsldma.h"
+
+static void dma_init(struct fsl_dma_chan *fsl_chan)
+{
+ /* Reset the channel */
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, 0, 32);
+
+ switch (fsl_chan->feature & FSL_DMA_IP_MASK) {
+ case FSL_DMA_IP_85XX:
+ /* Set the channel to below modes:
+ * EIE - Error interrupt enable
+ * EOSIE - End of segments interrupt enable (basic mode)
+ * EOLNIE - End of links interrupt enable
+ */
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EIE
+ | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32);
+ break;
+ case FSL_DMA_IP_83XX:
+ /* Set the channel to below modes:
+ * EOTIE - End-of-transfer interrupt enable
+ */
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EOTIE,
+ 32);
+ break;
+ }
+
+}
+
+static void set_sr(struct fsl_dma_chan *fsl_chan, dma_addr_t val)
+{
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->sr, val, 32);
+}
+
+static dma_addr_t get_sr(struct fsl_dma_chan *fsl_chan)
+{
+ return DMA_IN(fsl_chan, &fsl_chan->reg_base->sr, 32);
+}
+
+static void set_desc_cnt(struct fsl_dma_chan *fsl_chan,
+ struct fsl_dma_ld_hw *hw, u32 count)
+{
+ hw->count = CPU_TO_DMA(fsl_chan, count, 32);
+}
+
+static void set_desc_src(struct fsl_dma_chan *fsl_chan,
+ struct fsl_dma_ld_hw *hw, dma_addr_t src)
+{
+ u64 snoop_bits;
+
+ snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX)
+ ? ((u64)FSL_DMA_SATR_SREADTYPE_SNOOP_READ << 32) : 0;
+ hw->src_addr = CPU_TO_DMA(fsl_chan, snoop_bits | src, 64);
+}
+
+static void set_desc_dest(struct fsl_dma_chan *fsl_chan,
+ struct fsl_dma_ld_hw *hw, dma_addr_t dest)
+{
+ u64 snoop_bits;
+
+ snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX)
+ ? ((u64)FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE << 32) : 0;
+ hw->dst_addr = CPU_TO_DMA(fsl_chan, snoop_bits | dest, 64);
+}
+
+static void set_desc_next(struct fsl_dma_chan *fsl_chan,
+ struct fsl_dma_ld_hw *hw, dma_addr_t next)
+{
+ u64 snoop_bits;
+
+ snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX)
+ ? FSL_DMA_SNEN : 0;
+ hw->next_ln_addr = CPU_TO_DMA(fsl_chan, snoop_bits | next, 64);
+}
+
+static void set_cdar(struct fsl_dma_chan *fsl_chan, dma_addr_t addr)
+{
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->cdar, addr | FSL_DMA_SNEN, 64);
+}
+
+static dma_addr_t get_cdar(struct fsl_dma_chan *fsl_chan)
+{
+ return DMA_IN(fsl_chan, &fsl_chan->reg_base->cdar, 64) & ~FSL_DMA_SNEN;
+}
+
+static void set_ndar(struct fsl_dma_chan *fsl_chan, dma_addr_t addr)
+{
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->ndar, addr, 64);
+}
+
+static dma_addr_t get_ndar(struct fsl_dma_chan *fsl_chan)
+{
+ return DMA_IN(fsl_chan, &fsl_chan->reg_base->ndar, 64);
+}
+
+static int dma_is_idle(struct fsl_dma_chan *fsl_chan)
+{
+ u32 sr = get_sr(fsl_chan);
+ return (!(sr & FSL_DMA_SR_CB)) || (sr & FSL_DMA_SR_CH);
+}
+
+static void dma_start(struct fsl_dma_chan *fsl_chan)
+{
+ u32 mr_set = 0;;
+
+ if (fsl_chan->feature & FSL_DMA_CHAN_PAUSE_EXT) {
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->bcr, 0, 32);
+ mr_set |= FSL_DMA_MR_EMP_EN;
+ } else
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32)
+ & ~FSL_DMA_MR_EMP_EN, 32);
+
+ if (fsl_chan->feature & FSL_DMA_CHAN_START_EXT)
+ mr_set |= FSL_DMA_MR_EMS_EN;
+ else
+ mr_set |= FSL_DMA_MR_CS;
+
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32)
+ | mr_set, 32);
+}
+
+static void dma_halt(struct fsl_dma_chan *fsl_chan)
+{
+ int i = 0;
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) | FSL_DMA_MR_CA,
+ 32);
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) & ~(FSL_DMA_MR_CS
+ | FSL_DMA_MR_EMS_EN | FSL_DMA_MR_CA), 32);
+
+ while (!dma_is_idle(fsl_chan) && (i++ < 100))
+ udelay(10);
+ if (i >= 100 && !dma_is_idle(fsl_chan))
+ dev_err(fsl_chan->dev, "DMA halt timeout!\n");
+}
+
+static void set_ld_eol(struct fsl_dma_chan *fsl_chan,
+ struct fsl_desc_sw *desc)
+{
+ desc->hw.next_ln_addr = CPU_TO_DMA(fsl_chan,
+ DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL,
+ 64);
+}
+
+static void append_ld_queue(struct fsl_dma_chan *fsl_chan,
+ struct fsl_desc_sw *new_desc)
+{
+ struct fsl_desc_sw *queue_tail = to_fsl_desc(fsl_chan->ld_queue.prev);
+
+ if (list_empty(&fsl_chan->ld_queue))
+ return;
+
+ /* Link to the new descriptor physical address and
+ * Enable End-of-segment interrupt for
+ * the last link descriptor.
+ * (the previous node's next link descriptor)
+ *
+ * For FSL_DMA_IP_83xx, the snoop enable bit need be set.
+ */
+ queue_tail->hw.next_ln_addr = CPU_TO_DMA(fsl_chan,
+ new_desc->async_tx.phys | FSL_DMA_EOSIE |
+ (((fsl_chan->feature & FSL_DMA_IP_MASK)
+ == FSL_DMA_IP_83XX) ? FSL_DMA_SNEN : 0), 64);
+}
+
+/**
+ * fsl_chan_set_src_loop_size - Set source address hold transfer size
+ * @fsl_chan : Freescale DMA channel
+ * @size : Address loop size, 0 for disable loop
+ *
+ * The set source address hold transfer size. The source
+ * address hold or loop transfer size is when the DMA transfer
+ * data from source address (SA), if the loop size is 4, the DMA will
+ * read data from SA, SA + 1, SA + 2, SA + 3, then loop back to SA,
+ * SA + 1 ... and so on.
+ */
+static void fsl_chan_set_src_loop_size(struct fsl_dma_chan *fsl_chan, int size)
+{
+ switch (size) {
+ case 0:
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) &
+ (~FSL_DMA_MR_SAHE), 32);
+ break;
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) |
+ FSL_DMA_MR_SAHE | (__ilog2(size) << 14),
+ 32);
+ break;
+ }
+}
+
+/**
+ * fsl_chan_set_dest_loop_size - Set destination address hold transfer size
+ * @fsl_chan : Freescale DMA channel
+ * @size : Address loop size, 0 for disable loop
+ *
+ * The set destination address hold transfer size. The destination
+ * address hold or loop transfer size is when the DMA transfer
+ * data to destination address (TA), if the loop size is 4, the DMA will
+ * write data to TA, TA + 1, TA + 2, TA + 3, then loop back to TA,
+ * TA + 1 ... and so on.
+ */
+static void fsl_chan_set_dest_loop_size(struct fsl_dma_chan *fsl_chan, int size)
+{
+ switch (size) {
+ case 0:
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) &
+ (~FSL_DMA_MR_DAHE), 32);
+ break;
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) |
+ FSL_DMA_MR_DAHE | (__ilog2(size) << 16),
+ 32);
+ break;
+ }
+}
+
+/**
+ * fsl_chan_toggle_ext_pause - Toggle channel external pause status
+ * @fsl_chan : Freescale DMA channel
+ * @size : Pause control size, 0 for disable external pause control.
+ * The maximum is 1024.
+ *
+ * The Freescale DMA channel can be controlled by the external
+ * signal DREQ#. The pause control size is how many bytes are allowed
+ * to transfer before pausing the channel, after which a new assertion
+ * of DREQ# resumes channel operation.
+ */
+static void fsl_chan_toggle_ext_pause(struct fsl_dma_chan *fsl_chan, int size)
+{
+ if (size > 1024)
+ return;
+
+ if (size) {
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32)
+ | ((__ilog2(size) << 24) & 0x0f000000),
+ 32);
+ fsl_chan->feature |= FSL_DMA_CHAN_PAUSE_EXT;
+ } else
+ fsl_chan->feature &= ~FSL_DMA_CHAN_PAUSE_EXT;
+}
+
+/**
+ * fsl_chan_toggle_ext_start - Toggle channel external start status
+ * @fsl_chan : Freescale DMA channel
+ * @enable : 0 is disabled, 1 is enabled.
+ *
+ * If enable the external start, the channel can be started by an
+ * external DMA start pin. So the dma_start() does not start the
+ * transfer immediately. The DMA channel will wait for the
+ * control pin asserted.
+ */
+static void fsl_chan_toggle_ext_start(struct fsl_dma_chan *fsl_chan, int enable)
+{
+ if (enable)
+ fsl_chan->feature |= FSL_DMA_CHAN_START_EXT;
+ else
+ fsl_chan->feature &= ~FSL_DMA_CHAN_START_EXT;
+}
+
+static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct fsl_desc_sw *desc = tx_to_fsl_desc(tx);
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(tx->chan);
+ unsigned long flags;
+ dma_cookie_t cookie;
+
+ /* cookie increment and adding to ld_queue must be atomic */
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
+ cookie = fsl_chan->common.cookie;
+ cookie++;
+ if (cookie < 0)
+ cookie = 1;
+ desc->async_tx.cookie = cookie;
+ fsl_chan->common.cookie = desc->async_tx.cookie;
+
+ append_ld_queue(fsl_chan, desc);
+ list_splice_init(&desc->async_tx.tx_list, fsl_chan->ld_queue.prev);
+
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+
+ return cookie;
+}
+
+/**
+ * fsl_dma_alloc_descriptor - Allocate descriptor from channel's DMA pool.
+ * @fsl_chan : Freescale DMA channel
+ *
+ * Return - The descriptor allocated. NULL for failed.
+ */
+static struct fsl_desc_sw *fsl_dma_alloc_descriptor(
+ struct fsl_dma_chan *fsl_chan)
+{
+ dma_addr_t pdesc;
+ struct fsl_desc_sw *desc_sw;
+
+ desc_sw = dma_pool_alloc(fsl_chan->desc_pool, GFP_ATOMIC, &pdesc);
+ if (desc_sw) {
+ memset(desc_sw, 0, sizeof(struct fsl_desc_sw));
+ dma_async_tx_descriptor_init(&desc_sw->async_tx,
+ &fsl_chan->common);
+ desc_sw->async_tx.tx_submit = fsl_dma_tx_submit;
+ INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
+ desc_sw->async_tx.phys = pdesc;
+ }
+
+ return desc_sw;
+}
+
+
+/**
+ * fsl_dma_alloc_chan_resources - Allocate resources for DMA channel.
+ * @fsl_chan : Freescale DMA channel
+ *
+ * This function will create a dma pool for descriptor allocation.
+ *
+ * Return - The number of descriptors allocated.
+ */
+static int fsl_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ LIST_HEAD(tmp_list);
+
+ /* We need the descriptor to be aligned to 32bytes
+ * for meeting FSL DMA specification requirement.
+ */
+ fsl_chan->desc_pool = dma_pool_create("fsl_dma_engine_desc_pool",
+ fsl_chan->dev, sizeof(struct fsl_desc_sw),
+ 32, 0);
+ if (!fsl_chan->desc_pool) {
+ dev_err(fsl_chan->dev, "No memory for channel %d "
+ "descriptor dma pool.\n", fsl_chan->id);
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * fsl_dma_free_chan_resources - Free all resources of the channel.
+ * @fsl_chan : Freescale DMA channel
+ */
+static void fsl_dma_free_chan_resources(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ struct fsl_desc_sw *desc, *_desc;
+ unsigned long flags;
+
+ dev_dbg(fsl_chan->dev, "Free all channel resources.\n");
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+ list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) {
+#ifdef FSL_DMA_LD_DEBUG
+ dev_dbg(fsl_chan->dev,
+ "LD %p will be released.\n", desc);
+#endif
+ list_del(&desc->node);
+ /* free link descriptor */
+ dma_pool_free(fsl_chan->desc_pool, desc, desc->async_tx.phys);
+ }
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+ dma_pool_destroy(fsl_chan->desc_pool);
+}
+
+static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
+ struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src,
+ size_t len, unsigned long flags)
+{
+ struct fsl_dma_chan *fsl_chan;
+ struct fsl_desc_sw *first = NULL, *prev = NULL, *new;
+ size_t copy;
+ LIST_HEAD(link_chain);
+
+ if (!chan)
+ return NULL;
+
+ if (!len)
+ return NULL;
+
+ fsl_chan = to_fsl_chan(chan);
+
+ do {
+
+ /* Allocate the link descriptor from DMA pool */
+ new = fsl_dma_alloc_descriptor(fsl_chan);
+ if (!new) {
+ dev_err(fsl_chan->dev,
+ "No free memory for link descriptor\n");
+ return NULL;
+ }
+#ifdef FSL_DMA_LD_DEBUG
+ dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new);
+#endif
+
+ copy = min(len, FSL_DMA_BCR_MAX_CNT);
+
+ set_desc_cnt(fsl_chan, &new->hw, copy);
+ set_desc_src(fsl_chan, &new->hw, dma_src);
+ set_desc_dest(fsl_chan, &new->hw, dma_dest);
+
+ if (!first)
+ first = new;
+ else
+ set_desc_next(fsl_chan, &prev->hw, new->async_tx.phys);
+
+ new->async_tx.cookie = 0;
+ new->async_tx.ack = 1;
+
+ prev = new;
+ len -= copy;
+ dma_src += copy;
+ dma_dest += copy;
+
+ /* Insert the link descriptor to the LD ring */
+ list_add_tail(&new->node, &first->async_tx.tx_list);
+ } while (len);
+
+ new->async_tx.ack = 0; /* client is in control of this ack */
+ new->async_tx.cookie = -EBUSY;
+
+ /* Set End-of-link to the last link descriptor of new list*/
+ set_ld_eol(fsl_chan, new);
+
+ return first ? &first->async_tx : NULL;
+}
+
+/**
+ * fsl_dma_update_completed_cookie - Update the completed cookie.
+ * @fsl_chan : Freescale DMA channel
+ */
+static void fsl_dma_update_completed_cookie(struct fsl_dma_chan *fsl_chan)
+{
+ struct fsl_desc_sw *cur_desc, *desc;
+ dma_addr_t ld_phy;
+
+ ld_phy = get_cdar(fsl_chan) & FSL_DMA_NLDA_MASK;
+
+ if (ld_phy) {
+ cur_desc = NULL;
+ list_for_each_entry(desc, &fsl_chan->ld_queue, node)
+ if (desc->async_tx.phys == ld_phy) {
+ cur_desc = desc;
+ break;
+ }
+
+ if (cur_desc && cur_desc->async_tx.cookie) {
+ if (dma_is_idle(fsl_chan))
+ fsl_chan->completed_cookie =
+ cur_desc->async_tx.cookie;
+ else
+ fsl_chan->completed_cookie =
+ cur_desc->async_tx.cookie - 1;
+ }
+ }
+}
+
+/**
+ * fsl_chan_ld_cleanup - Clean up link descriptors
+ * @fsl_chan : Freescale DMA channel
+ *
+ * This function clean up the ld_queue of DMA channel.
+ * If 'in_intr' is set, the function will move the link descriptor to
+ * the recycle list. Otherwise, free it directly.
+ */
+static void fsl_chan_ld_cleanup(struct fsl_dma_chan *fsl_chan)
+{
+ struct fsl_desc_sw *desc, *_desc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
+ fsl_dma_update_completed_cookie(fsl_chan);
+ dev_dbg(fsl_chan->dev, "chan completed_cookie = %d\n",
+ fsl_chan->completed_cookie);
+ list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) {
+ dma_async_tx_callback callback;
+ void *callback_param;
+
+ if (dma_async_is_complete(desc->async_tx.cookie,
+ fsl_chan->completed_cookie, fsl_chan->common.cookie)
+ == DMA_IN_PROGRESS)
+ break;
+
+ callback = desc->async_tx.callback;
+ callback_param = desc->async_tx.callback_param;
+
+ /* Remove from ld_queue list */
+ list_del(&desc->node);
+
+ dev_dbg(fsl_chan->dev, "link descriptor %p will be recycle.\n",
+ desc);
+ dma_pool_free(fsl_chan->desc_pool, desc, desc->async_tx.phys);
+
+ /* Run the link descriptor callback function */
+ if (callback) {
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+ dev_dbg(fsl_chan->dev, "link descriptor %p callback\n",
+ desc);
+ callback(callback_param);
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+ }
+ }
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+}
+
+/**
+ * fsl_chan_xfer_ld_queue - Transfer link descriptors in channel ld_queue.
+ * @fsl_chan : Freescale DMA channel
+ */
+static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan)
+{
+ struct list_head *ld_node;
+ dma_addr_t next_dest_addr;
+ unsigned long flags;
+
+ if (!dma_is_idle(fsl_chan))
+ return;
+
+ dma_halt(fsl_chan);
+
+ /* If there are some link descriptors
+ * not transfered in queue. We need to start it.
+ */
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
+ /* Find the first un-transfer desciptor */
+ for (ld_node = fsl_chan->ld_queue.next;
+ (ld_node != &fsl_chan->ld_queue)
+ && (dma_async_is_complete(
+ to_fsl_desc(ld_node)->async_tx.cookie,
+ fsl_chan->completed_cookie,
+ fsl_chan->common.cookie) == DMA_SUCCESS);
+ ld_node = ld_node->next);
+
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+
+ if (ld_node != &fsl_chan->ld_queue) {
+ /* Get the ld start address from ld_queue */
+ next_dest_addr = to_fsl_desc(ld_node)->async_tx.phys;
+ dev_dbg(fsl_chan->dev, "xfer LDs staring from 0x%016llx\n",
+ (u64)next_dest_addr);
+ set_cdar(fsl_chan, next_dest_addr);
+ dma_start(fsl_chan);
+ } else {
+ set_cdar(fsl_chan, 0);
+ set_ndar(fsl_chan, 0);
+ }
+}
+
+/**
+ * fsl_dma_memcpy_issue_pending - Issue the DMA start command
+ * @fsl_chan : Freescale DMA channel
+ */
+static void fsl_dma_memcpy_issue_pending(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+
+#ifdef FSL_DMA_LD_DEBUG
+ struct fsl_desc_sw *ld;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+ if (list_empty(&fsl_chan->ld_queue)) {
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+ return;
+ }
+
+ dev_dbg(fsl_chan->dev, "--memcpy issue--\n");
+ list_for_each_entry(ld, &fsl_chan->ld_queue, node) {
+ int i;
+ dev_dbg(fsl_chan->dev, "Ch %d, LD %08x\n",
+ fsl_chan->id, ld->async_tx.phys);
+ for (i = 0; i < 8; i++)
+ dev_dbg(fsl_chan->dev, "LD offset %d: %08x\n",
+ i, *(((u32 *)&ld->hw) + i));
+ }
+ dev_dbg(fsl_chan->dev, "----------------\n");
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+#endif
+
+ fsl_chan_xfer_ld_queue(fsl_chan);
+}
+
+static void fsl_dma_dependency_added(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+
+ fsl_chan_ld_cleanup(fsl_chan);
+}
+
+/**
+ * fsl_dma_is_complete - Determine the DMA status
+ * @fsl_chan : Freescale DMA channel
+ */
+static enum dma_status fsl_dma_is_complete(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ dma_cookie_t *done,
+ dma_cookie_t *used)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ dma_cookie_t last_used;
+ dma_cookie_t last_complete;
+
+ fsl_chan_ld_cleanup(fsl_chan);
+
+ last_used = chan->cookie;
+ last_complete = fsl_chan->completed_cookie;
+
+ if (done)
+ *done = last_complete;
+
+ if (used)
+ *used = last_used;
+
+ return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data)
+{
+ struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data;
+ dma_addr_t stat;
+
+ stat = get_sr(fsl_chan);
+ dev_dbg(fsl_chan->dev, "event: channel %d, stat = 0x%x\n",
+ fsl_chan->id, stat);
+ set_sr(fsl_chan, stat); /* Clear the event register */
+
+ stat &= ~(FSL_DMA_SR_CB | FSL_DMA_SR_CH);
+ if (!stat)
+ return IRQ_NONE;
+
+ if (stat & FSL_DMA_SR_TE)
+ dev_err(fsl_chan->dev, "Transfer Error!\n");
+
+ /* If the link descriptor segment transfer finishes,
+ * we will recycle the used descriptor.
+ */
+ if (stat & FSL_DMA_SR_EOSI) {
+ dev_dbg(fsl_chan->dev, "event: End-of-segments INT\n");
+ dev_dbg(fsl_chan->dev, "event: clndar 0x%016llx, "
+ "nlndar 0x%016llx\n", (u64)get_cdar(fsl_chan),
+ (u64)get_ndar(fsl_chan));
+ stat &= ~FSL_DMA_SR_EOSI;
+ }
+
+ /* If it current transfer is the end-of-transfer,
+ * we should clear the Channel Start bit for
+ * prepare next transfer.
+ */
+ if (stat & (FSL_DMA_SR_EOLNI | FSL_DMA_SR_EOCDI)) {
+ dev_dbg(fsl_chan->dev, "event: End-of-link INT\n");
+ stat &= ~FSL_DMA_SR_EOLNI;
+ fsl_chan_xfer_ld_queue(fsl_chan);
+ }
+
+ if (stat)
+ dev_dbg(fsl_chan->dev, "event: unhandled sr 0x%02x\n",
+ stat);
+
+ dev_dbg(fsl_chan->dev, "event: Exit\n");
+ tasklet_schedule(&fsl_chan->tasklet);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t fsl_dma_do_interrupt(int irq, void *data)
+{
+ struct fsl_dma_device *fdev = (struct fsl_dma_device *)data;
+ u32 gsr;
+ int ch_nr;
+
+ gsr = (fdev->feature & FSL_DMA_BIG_ENDIAN) ? in_be32(fdev->reg_base)
+ : in_le32(fdev->reg_base);
+ ch_nr = (32 - ffs(gsr)) / 8;
+
+ return fdev->chan[ch_nr] ? fsl_dma_chan_do_interrupt(irq,
+ fdev->chan[ch_nr]) : IRQ_NONE;
+}
+
+static void dma_do_tasklet(unsigned long data)
+{
+ struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data;
+ fsl_chan_ld_cleanup(fsl_chan);
+}
+
+static void fsl_dma_callback_test(struct fsl_dma_chan *fsl_chan)
+{
+ if (fsl_chan)
+ dev_info(fsl_chan->dev, "selftest: callback is ok!\n");
+}
+
+static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
+{
+ struct dma_chan *chan;
+ int err = 0;
+ dma_addr_t dma_dest, dma_src;
+ dma_cookie_t cookie;
+ u8 *src, *dest;
+ int i;
+ size_t test_size;
+ struct dma_async_tx_descriptor *tx1, *tx2, *tx3;
+
+ test_size = 4096;
+
+ src = kmalloc(test_size * 2, GFP_KERNEL);
+ if (!src) {
+ dev_err(fsl_chan->dev,
+ "selftest: Cannot alloc memory for test!\n");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ dest = src + test_size;
+
+ for (i = 0; i < test_size; i++)
+ src[i] = (u8) i;
+
+ chan = &fsl_chan->common;
+
+ if (fsl_dma_alloc_chan_resources(chan) < 1) {
+ dev_err(fsl_chan->dev,
+ "selftest: Cannot alloc resources for DMA\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ /* TX 1 */
+ dma_src = dma_map_single(fsl_chan->dev, src, test_size / 2,
+ DMA_TO_DEVICE);
+ dma_dest = dma_map_single(fsl_chan->dev, dest, test_size / 2,
+ DMA_FROM_DEVICE);
+ tx1 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 2, 0);
+ async_tx_ack(tx1);
+
+ cookie = fsl_dma_tx_submit(tx1);
+ fsl_dma_memcpy_issue_pending(chan);
+ msleep(2);
+
+ if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) {
+ dev_err(fsl_chan->dev, "selftest: Time out!\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ /* Test free and re-alloc channel resources */
+ fsl_dma_free_chan_resources(chan);
+
+ if (fsl_dma_alloc_chan_resources(chan) < 1) {
+ dev_err(fsl_chan->dev,
+ "selftest: Cannot alloc resources for DMA\n");
+ err = -ENODEV;
+ goto free_resources;
+ }
+
+ /* Continue to test
+ * TX 2
+ */
+ dma_src = dma_map_single(fsl_chan->dev, src + test_size / 2,
+ test_size / 4, DMA_TO_DEVICE);
+ dma_dest = dma_map_single(fsl_chan->dev, dest + test_size / 2,
+ test_size / 4, DMA_FROM_DEVICE);
+ tx2 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0);
+ async_tx_ack(tx2);
+
+ /* TX 3 */
+ dma_src = dma_map_single(fsl_chan->dev, src + test_size * 3 / 4,
+ test_size / 4, DMA_TO_DEVICE);
+ dma_dest = dma_map_single(fsl_chan->dev, dest + test_size * 3 / 4,
+ test_size / 4, DMA_FROM_DEVICE);
+ tx3 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0);
+ async_tx_ack(tx3);
+
+ /* Test exchanging the prepared tx sort */
+ cookie = fsl_dma_tx_submit(tx3);
+ cookie = fsl_dma_tx_submit(tx2);
+
+#ifdef FSL_DMA_CALLBACKTEST
+ if (dma_has_cap(DMA_INTERRUPT, ((struct fsl_dma_device *)
+ dev_get_drvdata(fsl_chan->dev->parent))->common.cap_mask)) {
+ tx3->callback = fsl_dma_callback_test;
+ tx3->callback_param = fsl_chan;
+ }
+#endif
+ fsl_dma_memcpy_issue_pending(chan);
+ msleep(2);
+
+ if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) {
+ dev_err(fsl_chan->dev, "selftest: Time out!\n");
+ err = -ENODEV;
+ goto free_resources;
+ }
+
+ err = memcmp(src, dest, test_size);
+ if (err) {
+ for (i = 0; (*(src + i) == *(dest + i)) && (i < test_size);
+ i++);
+ dev_err(fsl_chan->dev, "selftest: Test failed, data %d/%d is "
+ "error! src 0x%x, dest 0x%x\n",
+ i, test_size, *(src + i), *(dest + i));
+ }
+
+free_resources:
+ fsl_dma_free_chan_resources(chan);
+out:
+ kfree(src);
+ return err;
+}
+
+static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
+ const struct of_device_id *match)
+{
+ struct fsl_dma_device *fdev;
+ struct fsl_dma_chan *new_fsl_chan;
+ int err;
+
+ fdev = dev_get_drvdata(dev->dev.parent);
+ BUG_ON(!fdev);
+
+ /* alloc channel */
+ new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL);
+ if (!new_fsl_chan) {
+ dev_err(&dev->dev, "No free memory for allocating "
+ "dma channels!\n");
+ err = -ENOMEM;
+ goto err;
+ }
+
+ /* get dma channel register base */
+ err = of_address_to_resource(dev->node, 0, &new_fsl_chan->reg);
+ if (err) {
+ dev_err(&dev->dev, "Can't get %s property 'reg'\n",
+ dev->node->full_name);
+ goto err;
+ }
+
+ new_fsl_chan->feature = *(u32 *)match->data;
+
+ if (!fdev->feature)
+ fdev->feature = new_fsl_chan->feature;
+
+ /* If the DMA device's feature is different than its channels',
+ * report the bug.
+ */
+ WARN_ON(fdev->feature != new_fsl_chan->feature);
+
+ new_fsl_chan->dev = &dev->dev;
+ new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start,
+ new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);
+
+ new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7;
+ if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) {
+ dev_err(&dev->dev, "There is no %d channel!\n",
+ new_fsl_chan->id);
+ err = -EINVAL;
+ goto err;
+ }
+ fdev->chan[new_fsl_chan->id] = new_fsl_chan;
+ tasklet_init(&new_fsl_chan->tasklet, dma_do_tasklet,
+ (unsigned long)new_fsl_chan);
+
+ /* Init the channel */
+ dma_init(new_fsl_chan);
+
+ /* Clear cdar registers */
+ set_cdar(new_fsl_chan, 0);
+
+ switch (new_fsl_chan->feature & FSL_DMA_IP_MASK) {
+ case FSL_DMA_IP_85XX:
+ new_fsl_chan->toggle_ext_start = fsl_chan_toggle_ext_start;
+ new_fsl_chan->toggle_ext_pause = fsl_chan_toggle_ext_pause;
+ case FSL_DMA_IP_83XX:
+ new_fsl_chan->set_src_loop_size = fsl_chan_set_src_loop_size;
+ new_fsl_chan->set_dest_loop_size = fsl_chan_set_dest_loop_size;
+ }
+
+ spin_lock_init(&new_fsl_chan->desc_lock);
+ INIT_LIST_HEAD(&new_fsl_chan->ld_queue);
+
+ new_fsl_chan->common.device = &fdev->common;
+
+ /* Add the channel to DMA device channel list */
+ list_add_tail(&new_fsl_chan->common.device_node,
+ &fdev->common.channels);
+ fdev->common.chancnt++;
+
+ new_fsl_chan->irq = irq_of_parse_and_map(dev->node, 0);
+ if (new_fsl_chan->irq != NO_IRQ) {
+ err = request_irq(new_fsl_chan->irq,
+ &fsl_dma_chan_do_interrupt, IRQF_SHARED,
+ "fsldma-channel", new_fsl_chan);
+ if (err) {
+ dev_err(&dev->dev, "DMA channel %s request_irq error "
+ "with return %d\n", dev->node->full_name, err);
+ goto err;
+ }
+ }
+
+#ifdef CONFIG_FSL_DMA_SELFTEST
+ err = fsl_dma_self_test(new_fsl_chan);
+ if (err)
+ goto err;
+#endif
+
+ dev_info(&dev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
+ match->compatible, new_fsl_chan->irq);
+
+ return 0;
+err:
+ dma_halt(new_fsl_chan);
+ iounmap(new_fsl_chan->reg_base);
+ free_irq(new_fsl_chan->irq, new_fsl_chan);
+ list_del(&new_fsl_chan->common.device_node);
+ kfree(new_fsl_chan);
+ return err;
+}
+
+const u32 mpc8540_dma_ip_feature = FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN;
+const u32 mpc8349_dma_ip_feature = FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN;
+
+static struct of_device_id of_fsl_dma_chan_ids[] = {
+ {
+ .compatible = "fsl,mpc8540-dma-channel",
+ .data = (void *)&mpc8540_dma_ip_feature,
+ },
+ {
+ .compatible = "fsl,mpc8349-dma-channel",
+ .data = (void *)&mpc8349_dma_ip_feature,
+ },
+ {}
+};
+
+static struct of_platform_driver of_fsl_dma_chan_driver = {
+ .name = "of-fsl-dma-channel",
+ .match_table = of_fsl_dma_chan_ids,
+ .probe = of_fsl_dma_chan_probe,
+};
+
+static __init int of_fsl_dma_chan_init(void)
+{
+ return of_register_platform_driver(&of_fsl_dma_chan_driver);
+}
+
+static int __devinit of_fsl_dma_probe(struct of_device *dev,
+ const struct of_device_id *match)
+{
+ int err;
+ unsigned int irq;
+ struct fsl_dma_device *fdev;
+
+ fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL);
+ if (!fdev) {
+ dev_err(&dev->dev, "No enough memory for 'priv'\n");
+ err = -ENOMEM;
+ goto err;
+ }
+ fdev->dev = &dev->dev;
+ INIT_LIST_HEAD(&fdev->common.channels);
+
+ /* get DMA controller register base */
+ err = of_address_to_resource(dev->node, 0, &fdev->reg);
+ if (err) {
+ dev_err(&dev->dev, "Can't get %s property 'reg'\n",
+ dev->node->full_name);
+ goto err;
+ }
+
+ dev_info(&dev->dev, "Probe the Freescale DMA driver for %s "
+ "controller at 0x%08x...\n",
+ match->compatible, fdev->reg.start);
+ fdev->reg_base = ioremap(fdev->reg.start, fdev->reg.end
+ - fdev->reg.start + 1);
+
+ dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask);
+ dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask);
+ fdev->common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources;
+ fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources;
+ fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy;
+ fdev->common.device_is_tx_complete = fsl_dma_is_complete;
+ fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;
+ fdev->common.device_dependency_added = fsl_dma_dependency_added;
+ fdev->common.dev = &dev->dev;
+
+ irq = irq_of_parse_and_map(dev->node, 0);
+ if (irq != NO_IRQ) {
+ err = request_irq(irq, &fsl_dma_do_interrupt, IRQF_SHARED,
+ "fsldma-device", fdev);
+ if (err) {
+ dev_err(&dev->dev, "DMA device request_irq error "
+ "with return %d\n", err);
+ goto err;
+ }
+ }
+
+ dev_set_drvdata(&(dev->dev), fdev);
+ of_platform_bus_probe(dev->node, of_fsl_dma_chan_ids, &dev->dev);
+
+ dma_async_device_register(&fdev->common);
+ return 0;
+
+err:
+ iounmap(fdev->reg_base);
+ kfree(fdev);
+ return err;
+}
+
+static struct of_device_id of_fsl_dma_ids[] = {
+ { .compatible = "fsl,mpc8540-dma", },
+ { .compatible = "fsl,mpc8349-dma", },
+ {}
+};
+
+static struct of_platform_driver of_fsl_dma_driver = {
+ .name = "of-fsl-dma",
+ .match_table = of_fsl_dma_ids,
+ .probe = of_fsl_dma_probe,
+};
+
+static __init int of_fsl_dma_init(void)
+{
+ return of_register_platform_driver(&of_fsl_dma_driver);
+}
+
+subsys_initcall(of_fsl_dma_chan_init);
+subsys_initcall(of_fsl_dma_init);
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
new file mode 100644
index 00000000000..ba78c42121b
--- /dev/null
+++ b/drivers/dma/fsldma.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author:
+ * Zhang Wei <wei.zhang@freescale.com>, Jul 2007
+ * Ebony Zhu <ebony.zhu@freescale.com>, May 2007
+ *
+ * This 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 __DMA_FSLDMA_H
+#define __DMA_FSLDMA_H
+
+#include <linux/device.h>
+#include <linux/dmapool.h>
+#include <linux/dmaengine.h>
+
+/* Define data structures needed by Freescale
+ * MPC8540 and MPC8349 DMA controller.
+ */
+#define FSL_DMA_MR_CS 0x00000001
+#define FSL_DMA_MR_CC 0x00000002
+#define FSL_DMA_MR_CA 0x00000008
+#define FSL_DMA_MR_EIE 0x00000040
+#define FSL_DMA_MR_XFE 0x00000020
+#define FSL_DMA_MR_EOLNIE 0x00000100
+#define FSL_DMA_MR_EOLSIE 0x00000080
+#define FSL_DMA_MR_EOSIE 0x00000200
+#define FSL_DMA_MR_CDSM 0x00000010
+#define FSL_DMA_MR_CTM 0x00000004
+#define FSL_DMA_MR_EMP_EN 0x00200000
+#define FSL_DMA_MR_EMS_EN 0x00040000
+#define FSL_DMA_MR_DAHE 0x00002000
+#define FSL_DMA_MR_SAHE 0x00001000
+
+/* Special MR definition for MPC8349 */
+#define FSL_DMA_MR_EOTIE 0x00000080
+
+#define FSL_DMA_SR_CH 0x00000020
+#define FSL_DMA_SR_CB 0x00000004
+#define FSL_DMA_SR_TE 0x00000080
+#define FSL_DMA_SR_EOSI 0x00000002
+#define FSL_DMA_SR_EOLSI 0x00000001
+#define FSL_DMA_SR_EOCDI 0x00000001
+#define FSL_DMA_SR_EOLNI 0x00000008
+
+#define FSL_DMA_SATR_SBPATMU 0x20000000
+#define FSL_DMA_SATR_STRANSINT_RIO 0x00c00000
+#define FSL_DMA_SATR_SREADTYPE_SNOOP_READ 0x00050000
+#define FSL_DMA_SATR_SREADTYPE_BP_IORH 0x00020000
+#define FSL_DMA_SATR_SREADTYPE_BP_NREAD 0x00040000
+#define FSL_DMA_SATR_SREADTYPE_BP_MREAD 0x00070000
+
+#define FSL_DMA_DATR_DBPATMU 0x20000000
+#define FSL_DMA_DATR_DTRANSINT_RIO 0x00c00000
+#define FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE 0x00050000
+#define FSL_DMA_DATR_DWRITETYPE_BP_FLUSH 0x00010000
+
+#define FSL_DMA_EOL ((u64)0x1)
+#define FSL_DMA_SNEN ((u64)0x10)
+#define FSL_DMA_EOSIE 0x8
+#define FSL_DMA_NLDA_MASK (~(u64)0x1f)
+
+#define FSL_DMA_BCR_MAX_CNT 0x03ffffffu
+
+#define FSL_DMA_DGSR_TE 0x80
+#define FSL_DMA_DGSR_CH 0x20
+#define FSL_DMA_DGSR_PE 0x10
+#define FSL_DMA_DGSR_EOLNI 0x08
+#define FSL_DMA_DGSR_CB 0x04
+#define FSL_DMA_DGSR_EOSI 0x02
+#define FSL_DMA_DGSR_EOLSI 0x01
+
+struct fsl_dma_ld_hw {
+ u64 __bitwise src_addr;
+ u64 __bitwise dst_addr;
+ u64 __bitwise next_ln_addr;
+ u32 __bitwise count;
+ u32 __bitwise reserve;
+} __attribute__((aligned(32)));
+
+struct fsl_desc_sw {
+ struct fsl_dma_ld_hw hw;
+ struct list_head node;
+ struct dma_async_tx_descriptor async_tx;
+ struct list_head *ld;
+ void *priv;
+} __attribute__((aligned(32)));
+
+struct fsl_dma_chan_regs {
+ u32 __bitwise mr; /* 0x00 - Mode Register */
+ u32 __bitwise sr; /* 0x04 - Status Register */
+ u64 __bitwise cdar; /* 0x08 - Current descriptor address register */
+ u64 __bitwise sar; /* 0x10 - Source Address Register */
+ u64 __bitwise dar; /* 0x18 - Destination Address Register */
+ u32 __bitwise bcr; /* 0x20 - Byte Count Register */
+ u64 __bitwise ndar; /* 0x24 - Next Descriptor Address Register */
+};
+
+struct fsl_dma_chan;
+#define FSL_DMA_MAX_CHANS_PER_DEVICE 4
+
+struct fsl_dma_device {
+ void __iomem *reg_base; /* DGSR register base */
+ struct resource reg; /* Resource for register */
+ struct device *dev;
+ struct dma_device common;
+ struct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE];
+ u32 feature; /* The same as DMA channels */
+};
+
+/* Define macros for fsl_dma_chan->feature property */
+#define FSL_DMA_LITTLE_ENDIAN 0x00000000
+#define FSL_DMA_BIG_ENDIAN 0x00000001
+
+#define FSL_DMA_IP_MASK 0x00000ff0
+#define FSL_DMA_IP_85XX 0x00000010
+#define FSL_DMA_IP_83XX 0x00000020
+
+#define FSL_DMA_CHAN_PAUSE_EXT 0x00001000
+#define FSL_DMA_CHAN_START_EXT 0x00002000
+
+struct fsl_dma_chan {
+ struct fsl_dma_chan_regs __iomem *reg_base;
+ dma_cookie_t completed_cookie; /* The maximum cookie completed */
+ spinlock_t desc_lock; /* Descriptor operation lock */
+ struct list_head ld_queue; /* Link descriptors queue */
+ struct dma_chan common; /* DMA common channel */
+ struct dma_pool *desc_pool; /* Descriptors pool */
+ struct device *dev; /* Channel device */
+ struct resource reg; /* Resource for register */
+ int irq; /* Channel IRQ */
+ int id; /* Raw id of this channel */
+ struct tasklet_struct tasklet;
+ u32 feature;
+
+ void (*toggle_ext_pause)(struct fsl_dma_chan *fsl_chan, int size);
+ void (*toggle_ext_start)(struct fsl_dma_chan *fsl_chan, int enable);
+ void (*set_src_loop_size)(struct fsl_dma_chan *fsl_chan, int size);
+ void (*set_dest_loop_size)(struct fsl_dma_chan *fsl_chan, int size);
+};
+
+#define to_fsl_chan(chan) container_of(chan, struct fsl_dma_chan, common)
+#define to_fsl_desc(lh) container_of(lh, struct fsl_desc_sw, node)
+#define tx_to_fsl_desc(tx) container_of(tx, struct fsl_desc_sw, async_tx)
+
+#ifndef __powerpc64__
+static u64 in_be64(const u64 __iomem *addr)
+{
+ return ((u64)in_be32((u32 *)addr) << 32) | (in_be32((u32 *)addr + 1));
+}
+
+static void out_be64(u64 __iomem *addr, u64 val)
+{
+ out_be32((u32 *)addr, val >> 32);
+ out_be32((u32 *)addr + 1, (u32)val);
+}
+
+/* There is no asm instructions for 64 bits reverse loads and stores */
+static u64 in_le64(const u64 __iomem *addr)
+{
+ return ((u64)in_le32((u32 *)addr + 1) << 32) | (in_le32((u32 *)addr));
+}
+
+static void out_le64(u64 __iomem *addr, u64 val)
+{
+ out_le32((u32 *)addr + 1, val >> 32);
+ out_le32((u32 *)addr, (u32)val);
+}
+#endif
+
+#define DMA_IN(fsl_chan, addr, width) \
+ (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
+ in_be##width(addr) : in_le##width(addr))
+#define DMA_OUT(fsl_chan, addr, val, width) \
+ (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
+ out_be##width(addr, val) : out_le##width(addr, val))
+
+#define DMA_TO_CPU(fsl_chan, d, width) \
+ (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
+ be##width##_to_cpu(d) : le##width##_to_cpu(d))
+#define CPU_TO_DMA(fsl_chan, c, width) \
+ (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
+ cpu_to_be##width(c) : cpu_to_le##width(c))
+
+#endif /* __DMA_FSLDMA_H */
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index dff38accc5c..4017d9e7acd 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -714,6 +714,7 @@ static struct dma_async_tx_descriptor *ioat1_dma_prep_memcpy(
new->len = len;
new->dst = dma_dest;
new->src = dma_src;
+ new->async_tx.ack = 0;
return &new->async_tx;
} else
return NULL;
@@ -741,6 +742,7 @@ static struct dma_async_tx_descriptor *ioat2_dma_prep_memcpy(
new->len = len;
new->dst = dma_dest;
new->src = dma_src;
+ new->async_tx.ack = 0;
return &new->async_tx;
} else
return NULL;
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index 3e9719948a8..a03462750b9 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/errno.h>
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/crc-itu-t.h>
@@ -214,17 +215,29 @@ static void
fw_card_bm_work(struct work_struct *work)
{
struct fw_card *card = container_of(work, struct fw_card, work.work);
- struct fw_device *root;
+ struct fw_device *root_device;
+ struct fw_node *root_node, *local_node;
struct bm_data bmd;
unsigned long flags;
int root_id, new_root_id, irm_id, gap_count, generation, grace;
int do_reset = 0;
spin_lock_irqsave(&card->lock, flags);
+ local_node = card->local_node;
+ root_node = card->root_node;
+
+ if (local_node == NULL) {
+ spin_unlock_irqrestore(&card->lock, flags);
+ return;
+ }
+ fw_node_get(local_node);
+ fw_node_get(root_node);
generation = card->generation;
- root = card->root_node->data;
- root_id = card->root_node->node_id;
+ root_device = root_node->data;
+ if (root_device)
+ fw_device_get(root_device);
+ root_id = root_node->node_id;
grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));
if (card->bm_generation + 1 == generation ||
@@ -243,14 +256,14 @@ fw_card_bm_work(struct work_struct *work)
irm_id = card->irm_node->node_id;
if (!card->irm_node->link_on) {
- new_root_id = card->local_node->node_id;
+ new_root_id = local_node->node_id;
fw_notify("IRM has link off, making local node (%02x) root.\n",
new_root_id);
goto pick_me;
}
bmd.lock.arg = cpu_to_be32(0x3f);
- bmd.lock.data = cpu_to_be32(card->local_node->node_id);
+ bmd.lock.data = cpu_to_be32(local_node->node_id);
spin_unlock_irqrestore(&card->lock, flags);
@@ -267,12 +280,12 @@ fw_card_bm_work(struct work_struct *work)
* Another bus reset happened. Just return,
* the BM work has been rescheduled.
*/
- return;
+ goto out;
}
if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f)
/* Somebody else is BM, let them do the work. */
- return;
+ goto out;
spin_lock_irqsave(&card->lock, flags);
if (bmd.rcode != RCODE_COMPLETE) {
@@ -282,7 +295,7 @@ fw_card_bm_work(struct work_struct *work)
* do a bus reset and pick the local node as
* root, and thus, IRM.
*/
- new_root_id = card->local_node->node_id;
+ new_root_id = local_node->node_id;
fw_notify("BM lock failed, making local node (%02x) root.\n",
new_root_id);
goto pick_me;
@@ -295,7 +308,7 @@ fw_card_bm_work(struct work_struct *work)
*/
spin_unlock_irqrestore(&card->lock, flags);
schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10));
- return;
+ goto out;
}
/*
@@ -305,20 +318,20 @@ fw_card_bm_work(struct work_struct *work)
*/
card->bm_generation = generation;
- if (root == NULL) {
+ if (root_device == NULL) {
/*
* Either link_on is false, or we failed to read the
* config rom. In either case, pick another root.
*/
- new_root_id = card->local_node->node_id;
- } else if (atomic_read(&root->state) != FW_DEVICE_RUNNING) {
+ new_root_id = local_node->node_id;
+ } else if (atomic_read(&root_device->state) != FW_DEVICE_RUNNING) {
/*
* If we haven't probed this device yet, bail out now
* and let's try again once that's done.
*/
spin_unlock_irqrestore(&card->lock, flags);
- return;
- } else if (root->config_rom[2] & BIB_CMC) {
+ goto out;
+ } else if (root_device->config_rom[2] & BIB_CMC) {
/*
* FIXME: I suppose we should set the cmstr bit in the
* STATE_CLEAR register of this node, as described in
@@ -332,7 +345,7 @@ fw_card_bm_work(struct work_struct *work)
* successfully read the config rom, but it's not
* cycle master capable.
*/
- new_root_id = card->local_node->node_id;
+ new_root_id = local_node->node_id;
}
pick_me:
@@ -341,8 +354,8 @@ fw_card_bm_work(struct work_struct *work)
* the typically much larger 1394b beta repeater delays though.
*/
if (!card->beta_repeaters_present &&
- card->root_node->max_hops < ARRAY_SIZE(gap_count_table))
- gap_count = gap_count_table[card->root_node->max_hops];
+ root_node->max_hops < ARRAY_SIZE(gap_count_table))
+ gap_count = gap_count_table[root_node->max_hops];
else
gap_count = 63;
@@ -364,6 +377,11 @@ fw_card_bm_work(struct work_struct *work)
fw_send_phy_config(card, new_root_id, generation, gap_count);
fw_core_initiate_bus_reset(card, 1);
}
+ out:
+ if (root_device)
+ fw_device_put(root_device);
+ fw_node_put(root_node);
+ fw_node_put(local_node);
}
static void
@@ -381,6 +399,7 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
static atomic_t index = ATOMIC_INIT(-1);
kref_init(&card->kref);
+ atomic_set(&card->device_count, 0);
card->index = atomic_inc_return(&index);
card->driver = driver;
card->device = device;
@@ -511,8 +530,14 @@ fw_core_remove_card(struct fw_card *card)
card->driver = &dummy_driver;
fw_destroy_nodes(card);
- flush_scheduled_work();
+ /*
+ * Wait for all device workqueue jobs to finish. Otherwise the
+ * firewire-core module could be unloaded before the jobs ran.
+ */
+ while (atomic_read(&card->device_count) > 0)
+ msleep(100);
+ cancel_delayed_work_sync(&card->work);
fw_flush_transactions(card);
del_timer_sync(&card->flush_timer);
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index 7e73cbaa412..46bc197a047 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -109,15 +109,17 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
struct client *client;
unsigned long flags;
- device = fw_device_from_devt(inode->i_rdev);
+ device = fw_device_get_by_devt(inode->i_rdev);
if (device == NULL)
return -ENODEV;
client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (client == NULL)
+ if (client == NULL) {
+ fw_device_put(device);
return -ENOMEM;
+ }
- client->device = fw_device_get(device);
+ client->device = device;
INIT_LIST_HEAD(&client->event_list);
INIT_LIST_HEAD(&client->resource_list);
spin_lock_init(&client->lock);
@@ -644,6 +646,10 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
struct fw_cdev_create_iso_context *request = buffer;
struct fw_iso_context *context;
+ /* We only support one context at this time. */
+ if (client->iso_context != NULL)
+ return -EBUSY;
+
if (request->channel > 63)
return -EINVAL;
@@ -790,8 +796,9 @@ static int ioctl_start_iso(struct client *client, void *buffer)
{
struct fw_cdev_start_iso *request = buffer;
- if (request->handle != 0)
+ if (client->iso_context == NULL || request->handle != 0)
return -EINVAL;
+
if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE) {
if (request->tags == 0 || request->tags > 15)
return -EINVAL;
@@ -808,7 +815,7 @@ static int ioctl_stop_iso(struct client *client, void *buffer)
{
struct fw_cdev_stop_iso *request = buffer;
- if (request->handle != 0)
+ if (client->iso_context == NULL || request->handle != 0)
return -EINVAL;
return fw_iso_context_stop(client->iso_context);
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index de9066e69ad..870125a3638 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -150,21 +150,10 @@ struct bus_type fw_bus_type = {
};
EXPORT_SYMBOL(fw_bus_type);
-struct fw_device *fw_device_get(struct fw_device *device)
-{
- get_device(&device->device);
-
- return device;
-}
-
-void fw_device_put(struct fw_device *device)
-{
- put_device(&device->device);
-}
-
static void fw_device_release(struct device *dev)
{
struct fw_device *device = fw_device(dev);
+ struct fw_card *card = device->card;
unsigned long flags;
/*
@@ -176,9 +165,9 @@ static void fw_device_release(struct device *dev)
spin_unlock_irqrestore(&device->card->lock, flags);
fw_node_put(device->node);
- fw_card_put(device->card);
kfree(device->config_rom);
kfree(device);
+ atomic_dec(&card->device_count);
}
int fw_device_enable_phys_dma(struct fw_device *device)
@@ -358,12 +347,9 @@ static ssize_t
guid_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct fw_device *device = fw_device(dev);
- u64 guid;
-
- guid = ((u64)device->config_rom[3] << 32) | device->config_rom[4];
- return snprintf(buf, PAGE_SIZE, "0x%016llx\n",
- (unsigned long long)guid);
+ return snprintf(buf, PAGE_SIZE, "0x%08x%08x\n",
+ device->config_rom[3], device->config_rom[4]);
}
static struct device_attribute fw_device_attributes[] = {
@@ -610,12 +596,14 @@ static DECLARE_RWSEM(idr_rwsem);
static DEFINE_IDR(fw_device_idr);
int fw_cdev_major;
-struct fw_device *fw_device_from_devt(dev_t devt)
+struct fw_device *fw_device_get_by_devt(dev_t devt)
{
struct fw_device *device;
down_read(&idr_rwsem);
device = idr_find(&fw_device_idr, MINOR(devt));
+ if (device)
+ fw_device_get(device);
up_read(&idr_rwsem);
return device;
@@ -627,13 +615,14 @@ static void fw_device_shutdown(struct work_struct *work)
container_of(work, struct fw_device, work.work);
int minor = MINOR(device->device.devt);
- down_write(&idr_rwsem);
- idr_remove(&fw_device_idr, minor);
- up_write(&idr_rwsem);
-
fw_device_cdev_remove(device);
device_for_each_child(&device->device, NULL, shutdown_unit);
device_unregister(&device->device);
+
+ down_write(&idr_rwsem);
+ idr_remove(&fw_device_idr, minor);
+ up_write(&idr_rwsem);
+ fw_device_put(device);
}
static struct device_type fw_device_type = {
@@ -668,7 +657,8 @@ static void fw_device_init(struct work_struct *work)
*/
if (read_bus_info_block(device, device->generation) < 0) {
- if (device->config_rom_retries < MAX_RETRIES) {
+ if (device->config_rom_retries < MAX_RETRIES &&
+ atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
device->config_rom_retries++;
schedule_delayed_work(&device->work, RETRY_DELAY);
} else {
@@ -682,10 +672,13 @@ static void fw_device_init(struct work_struct *work)
}
err = -ENOMEM;
+
+ fw_device_get(device);
down_write(&idr_rwsem);
if (idr_pre_get(&fw_device_idr, GFP_KERNEL))
err = idr_get_new(&fw_device_idr, device, &minor);
up_write(&idr_rwsem);
+
if (err < 0)
goto error;
@@ -717,13 +710,22 @@ static void fw_device_init(struct work_struct *work)
*/
if (atomic_cmpxchg(&device->state,
FW_DEVICE_INITIALIZING,
- FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
+ FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) {
fw_device_shutdown(&device->work.work);
- else
- fw_notify("created new fw device %s "
- "(%d config rom retries, S%d00)\n",
- device->device.bus_id, device->config_rom_retries,
- 1 << device->max_speed);
+ } else {
+ if (device->config_rom_retries)
+ fw_notify("created device %s: GUID %08x%08x, S%d00, "
+ "%d config ROM retries\n",
+ device->device.bus_id,
+ device->config_rom[3], device->config_rom[4],
+ 1 << device->max_speed,
+ device->config_rom_retries);
+ else
+ fw_notify("created device %s: GUID %08x%08x, S%d00\n",
+ device->device.bus_id,
+ device->config_rom[3], device->config_rom[4],
+ 1 << device->max_speed);
+ }
/*
* Reschedule the IRM work if we just finished reading the
@@ -741,7 +743,9 @@ static void fw_device_init(struct work_struct *work)
idr_remove(&fw_device_idr, minor);
up_write(&idr_rwsem);
error:
- put_device(&device->device);
+ fw_device_put(device); /* fw_device_idr's reference */
+
+ put_device(&device->device); /* our reference */
}
static int update_unit(struct device *dev, void *data)
@@ -791,7 +795,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
*/
device_initialize(&device->device);
atomic_set(&device->state, FW_DEVICE_INITIALIZING);
- device->card = fw_card_get(card);
+ atomic_inc(&card->device_count);
+ device->card = card;
device->node = fw_node_get(node);
device->node_id = node->node_id;
device->generation = card->generation;
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index 0854fe2bc11..78ecd3991b7 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -76,14 +76,26 @@ fw_device_is_shutdown(struct fw_device *device)
return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN;
}
-struct fw_device *fw_device_get(struct fw_device *device);
-void fw_device_put(struct fw_device *device);
+static inline struct fw_device *
+fw_device_get(struct fw_device *device)
+{
+ get_device(&device->device);
+
+ return device;
+}
+
+static inline void
+fw_device_put(struct fw_device *device)
+{
+ put_device(&device->device);
+}
+
+struct fw_device *fw_device_get_by_devt(dev_t devt);
int fw_device_enable_phys_dma(struct fw_device *device);
void fw_device_cdev_update(struct fw_device *device);
void fw_device_cdev_remove(struct fw_device *device);
-struct fw_device *fw_device_from_devt(dev_t devt);
extern int fw_cdev_major;
struct fw_unit {
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 19ece9b6d74..03069a454c0 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -28,14 +28,15 @@
* and many others.
*/
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/mod_devicetable.h>
-#include <linux/device.h>
#include <linux/scatterlist.h>
-#include <linux/dma-mapping.h>
-#include <linux/blkdev.h>
#include <linux/string.h>
#include <linux/stringify.h>
#include <linux/timer.h>
@@ -47,9 +48,9 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
-#include "fw-transaction.h"
-#include "fw-topology.h"
#include "fw-device.h"
+#include "fw-topology.h"
+#include "fw-transaction.h"
/*
* So far only bridges from Oxford Semiconductor are known to support
@@ -82,6 +83,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
* Avoids access beyond actual disk limits on devices with an off-by-one bug.
* Don't use this with devices which don't have this bug.
*
+ * - delay inquiry
+ * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
+ *
* - override internal blacklist
* Instead of adding to the built-in blacklist, use only the workarounds
* specified in the module load parameter.
@@ -91,6 +95,8 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
#define SBP2_WORKAROUND_INQUIRY_36 0x2
#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
+#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10
+#define SBP2_INQUIRY_DELAY 12
#define SBP2_WORKAROUND_OVERRIDE 0x100
static int sbp2_param_workarounds;
@@ -100,6 +106,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36)
", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
+ ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
", or a combination)");
@@ -115,7 +122,6 @@ static const char sbp2_driver_name[] = "sbp2";
struct sbp2_logical_unit {
struct sbp2_target *tgt;
struct list_head link;
- struct scsi_device *sdev;
struct fw_address_handler address_handler;
struct list_head orb_list;
@@ -132,6 +138,8 @@ struct sbp2_logical_unit {
int generation;
int retries;
struct delayed_work work;
+ bool has_sdev;
+ bool blocked;
};
/*
@@ -141,16 +149,18 @@ struct sbp2_logical_unit {
struct sbp2_target {
struct kref kref;
struct fw_unit *unit;
+ const char *bus_id;
+ struct list_head lu_list;
u64 management_agent_address;
int directory_id;
int node_id;
int address_high;
-
- unsigned workarounds;
- struct list_head lu_list;
-
+ unsigned int workarounds;
unsigned int mgt_orb_timeout;
+
+ int dont_block; /* counter for each logical unit */
+ int blocked; /* ditto */
};
/*
@@ -160,7 +170,7 @@ struct sbp2_target {
*/
#define SBP2_MIN_LOGIN_ORB_TIMEOUT 5000U /* Timeout in ms */
#define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */
-#define SBP2_ORB_TIMEOUT 2000 /* Timeout in ms */
+#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
#define SBP2_ORB_NULL 0x80000000
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
@@ -297,7 +307,7 @@ struct sbp2_command_orb {
static const struct {
u32 firmware_revision;
u32 model;
- unsigned workarounds;
+ unsigned int workarounds;
} sbp2_workarounds_table[] = {
/* DViCO Momobay CX-1 with TSB42AA9 bridge */ {
.firmware_revision = 0x002800,
@@ -305,6 +315,11 @@ static const struct {
.workarounds = SBP2_WORKAROUND_INQUIRY_36 |
SBP2_WORKAROUND_MODE_SENSE_8,
},
+ /* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
+ .firmware_revision = 0x002800,
+ .model = 0x000000,
+ .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY,
+ },
/* Initio bridges, actually only needed for some older ones */ {
.firmware_revision = 0x000200,
.model = ~0,
@@ -501,6 +516,9 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
unsigned int timeout;
int retval = -ENOMEM;
+ if (function == SBP2_LOGOUT_REQUEST && fw_device_is_shutdown(device))
+ return 0;
+
orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
if (orb == NULL)
return -ENOMEM;
@@ -553,20 +571,20 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
retval = -EIO;
if (sbp2_cancel_orbs(lu) == 0) {
- fw_error("orb reply timed out, rcode=0x%02x\n",
- orb->base.rcode);
+ fw_error("%s: orb reply timed out, rcode=0x%02x\n",
+ lu->tgt->bus_id, orb->base.rcode);
goto out;
}
if (orb->base.rcode != RCODE_COMPLETE) {
- fw_error("management write failed, rcode 0x%02x\n",
- orb->base.rcode);
+ fw_error("%s: management write failed, rcode 0x%02x\n",
+ lu->tgt->bus_id, orb->base.rcode);
goto out;
}
if (STATUS_GET_RESPONSE(orb->status) != 0 ||
STATUS_GET_SBP_STATUS(orb->status) != 0) {
- fw_error("error status: %d:%d\n",
+ fw_error("%s: error status: %d:%d\n", lu->tgt->bus_id,
STATUS_GET_RESPONSE(orb->status),
STATUS_GET_SBP_STATUS(orb->status));
goto out;
@@ -590,29 +608,158 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
static void
complete_agent_reset_write(struct fw_card *card, int rcode,
- void *payload, size_t length, void *data)
+ void *payload, size_t length, void *done)
{
- struct fw_transaction *t = data;
+ complete(done);
+}
- kfree(t);
+static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
+{
+ struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
+ DECLARE_COMPLETION_ONSTACK(done);
+ struct fw_transaction t;
+ static u32 z;
+
+ fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
+ lu->tgt->node_id, lu->generation, device->max_speed,
+ lu->command_block_agent_address + SBP2_AGENT_RESET,
+ &z, sizeof(z), complete_agent_reset_write, &done);
+ wait_for_completion(&done);
+}
+
+static void
+complete_agent_reset_write_no_wait(struct fw_card *card, int rcode,
+ void *payload, size_t length, void *data)
+{
+ kfree(data);
}
-static int sbp2_agent_reset(struct sbp2_logical_unit *lu)
+static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_transaction *t;
- static u32 zero;
+ static u32 z;
- t = kzalloc(sizeof(*t), GFP_ATOMIC);
+ t = kmalloc(sizeof(*t), GFP_ATOMIC);
if (t == NULL)
- return -ENOMEM;
+ return;
fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
lu->tgt->node_id, lu->generation, device->max_speed,
lu->command_block_agent_address + SBP2_AGENT_RESET,
- &zero, sizeof(zero), complete_agent_reset_write, t);
+ &z, sizeof(z), complete_agent_reset_write_no_wait, t);
+}
- return 0;
+static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation)
+{
+ struct fw_card *card = fw_device(lu->tgt->unit->device.parent)->card;
+ unsigned long flags;
+
+ /* serialize with comparisons of lu->generation and card->generation */
+ spin_lock_irqsave(&card->lock, flags);
+ lu->generation = generation;
+ spin_unlock_irqrestore(&card->lock, flags);
+}
+
+static inline void sbp2_allow_block(struct sbp2_logical_unit *lu)
+{
+ /*
+ * We may access dont_block without taking card->lock here:
+ * All callers of sbp2_allow_block() and all callers of sbp2_unblock()
+ * are currently serialized against each other.
+ * And a wrong result in sbp2_conditionally_block()'s access of
+ * dont_block is rather harmless, it simply misses its first chance.
+ */
+ --lu->tgt->dont_block;
+}
+
+/*
+ * Blocks lu->tgt if all of the following conditions are met:
+ * - Login, INQUIRY, and high-level SCSI setup of all of the target's
+ * logical units have been finished (indicated by dont_block == 0).
+ * - lu->generation is stale.
+ *
+ * Note, scsi_block_requests() must be called while holding card->lock,
+ * otherwise it might foil sbp2_[conditionally_]unblock()'s attempt to
+ * unblock the target.
+ */
+static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
+{
+ struct sbp2_target *tgt = lu->tgt;
+ struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
+ struct Scsi_Host *shost =
+ container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
+ unsigned long flags;
+
+ spin_lock_irqsave(&card->lock, flags);
+ if (!tgt->dont_block && !lu->blocked &&
+ lu->generation != card->generation) {
+ lu->blocked = true;
+ if (++tgt->blocked == 1) {
+ scsi_block_requests(shost);
+ fw_notify("blocked %s\n", lu->tgt->bus_id);
+ }
+ }
+ spin_unlock_irqrestore(&card->lock, flags);
+}
+
+/*
+ * Unblocks lu->tgt as soon as all its logical units can be unblocked.
+ * Note, it is harmless to run scsi_unblock_requests() outside the
+ * card->lock protected section. On the other hand, running it inside
+ * the section might clash with shost->host_lock.
+ */
+static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
+{
+ struct sbp2_target *tgt = lu->tgt;
+ struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
+ struct Scsi_Host *shost =
+ container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
+ unsigned long flags;
+ bool unblock = false;
+
+ spin_lock_irqsave(&card->lock, flags);
+ if (lu->blocked && lu->generation == card->generation) {
+ lu->blocked = false;
+ unblock = --tgt->blocked == 0;
+ }
+ spin_unlock_irqrestore(&card->lock, flags);
+
+ if (unblock) {
+ scsi_unblock_requests(shost);
+ fw_notify("unblocked %s\n", lu->tgt->bus_id);
+ }
+}
+
+/*
+ * Prevents future blocking of tgt and unblocks it.
+ * Note, it is harmless to run scsi_unblock_requests() outside the
+ * card->lock protected section. On the other hand, running it inside
+ * the section might clash with shost->host_lock.
+ */
+static void sbp2_unblock(struct sbp2_target *tgt)
+{
+ struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
+ struct Scsi_Host *shost =
+ container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
+ unsigned long flags;
+
+ spin_lock_irqsave(&card->lock, flags);
+ ++tgt->dont_block;
+ spin_unlock_irqrestore(&card->lock, flags);
+
+ scsi_unblock_requests(shost);
+}
+
+static int sbp2_lun2int(u16 lun)
+{
+ struct scsi_lun eight_bytes_lun;
+
+ memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
+ eight_bytes_lun.scsi_lun[0] = (lun >> 8) & 0xff;
+ eight_bytes_lun.scsi_lun[1] = lun & 0xff;
+
+ return scsilun_to_int(&eight_bytes_lun);
}
static void sbp2_release_target(struct kref *kref)
@@ -621,26 +768,31 @@ static void sbp2_release_target(struct kref *kref)
struct sbp2_logical_unit *lu, *next;
struct Scsi_Host *shost =
container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
+ struct scsi_device *sdev;
struct fw_device *device = fw_device(tgt->unit->device.parent);
- list_for_each_entry_safe(lu, next, &tgt->lu_list, link) {
- if (lu->sdev)
- scsi_remove_device(lu->sdev);
+ /* prevent deadlocks */
+ sbp2_unblock(tgt);
- if (!fw_device_is_shutdown(device))
- sbp2_send_management_orb(lu, tgt->node_id,
- lu->generation, SBP2_LOGOUT_REQUEST,
- lu->login_id, NULL);
+ list_for_each_entry_safe(lu, next, &tgt->lu_list, link) {
+ sdev = scsi_device_lookup(shost, 0, 0, sbp2_lun2int(lu->lun));
+ if (sdev) {
+ scsi_remove_device(sdev);
+ scsi_device_put(sdev);
+ }
+ sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
+ SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
fw_core_remove_address_handler(&lu->address_handler);
list_del(&lu->link);
kfree(lu);
}
scsi_remove_host(shost);
- fw_notify("released %s\n", tgt->unit->device.bus_id);
+ fw_notify("released %s\n", tgt->bus_id);
put_device(&tgt->unit->device);
scsi_host_put(shost);
+ fw_device_put(device);
}
static struct workqueue_struct *sbp2_wq;
@@ -666,33 +818,42 @@ static void sbp2_login(struct work_struct *work)
{
struct sbp2_logical_unit *lu =
container_of(work, struct sbp2_logical_unit, work.work);
- struct Scsi_Host *shost =
- container_of((void *)lu->tgt, struct Scsi_Host, hostdata[0]);
+ struct sbp2_target *tgt = lu->tgt;
+ struct fw_device *device = fw_device(tgt->unit->device.parent);
+ struct Scsi_Host *shost;
struct scsi_device *sdev;
- struct scsi_lun eight_bytes_lun;
- struct fw_unit *unit = lu->tgt->unit;
- struct fw_device *device = fw_device(unit->device.parent);
struct sbp2_login_response response;
int generation, node_id, local_node_id;
+ if (fw_device_is_shutdown(device))
+ goto out;
+
generation = device->generation;
smp_rmb(); /* node_id must not be older than generation */
node_id = device->node_id;
local_node_id = device->card->node_id;
+ /* If this is a re-login attempt, log out, or we might be rejected. */
+ if (lu->has_sdev)
+ sbp2_send_management_orb(lu, device->node_id, generation,
+ SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
+
if (sbp2_send_management_orb(lu, node_id, generation,
SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) {
- if (lu->retries++ < 5)
+ if (lu->retries++ < 5) {
sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5));
- else
- fw_error("failed to login to %s LUN %04x\n",
- unit->device.bus_id, lu->lun);
+ } else {
+ fw_error("%s: failed to login to LUN %04x\n",
+ tgt->bus_id, lu->lun);
+ /* Let any waiting I/O fail from now on. */
+ sbp2_unblock(lu->tgt);
+ }
goto out;
}
- lu->generation = generation;
- lu->tgt->node_id = node_id;
- lu->tgt->address_high = local_node_id << 16;
+ tgt->node_id = node_id;
+ tgt->address_high = local_node_id << 16;
+ sbp2_set_generation(lu, generation);
/* Get command block agent offset and login id. */
lu->command_block_agent_address =
@@ -700,8 +861,8 @@ static void sbp2_login(struct work_struct *work)
response.command_block_agent.low;
lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
- fw_notify("logged in to %s LUN %04x (%d retries)\n",
- unit->device.bus_id, lu->lun, lu->retries);
+ fw_notify("%s: logged in to LUN %04x (%d retries)\n",
+ tgt->bus_id, lu->lun, lu->retries);
#if 0
/* FIXME: The linux1394 sbp2 does this last step. */
@@ -711,26 +872,58 @@ static void sbp2_login(struct work_struct *work)
PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
sbp2_agent_reset(lu);
- memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
- eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff;
- eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff;
+ /* This was a re-login. */
+ if (lu->has_sdev) {
+ sbp2_cancel_orbs(lu);
+ sbp2_conditionally_unblock(lu);
+ goto out;
+ }
- sdev = __scsi_add_device(shost, 0, 0,
- scsilun_to_int(&eight_bytes_lun), lu);
- if (IS_ERR(sdev)) {
- sbp2_send_management_orb(lu, node_id, generation,
- SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
- /*
- * Set this back to sbp2_login so we fall back and
- * retry login on bus reset.
- */
- PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
- } else {
- lu->sdev = sdev;
+ if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY)
+ ssleep(SBP2_INQUIRY_DELAY);
+
+ shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
+ sdev = __scsi_add_device(shost, 0, 0, sbp2_lun2int(lu->lun), lu);
+ /*
+ * FIXME: We are unable to perform reconnects while in sbp2_login().
+ * Therefore __scsi_add_device() will get into trouble if a bus reset
+ * happens in parallel. It will either fail or leave us with an
+ * unusable sdev. As a workaround we check for this and retry the
+ * whole login and SCSI probing.
+ */
+
+ /* Reported error during __scsi_add_device() */
+ if (IS_ERR(sdev))
+ goto out_logout_login;
+
+ /* Unreported error during __scsi_add_device() */
+ smp_rmb(); /* get current card generation */
+ if (generation != device->card->generation) {
+ scsi_remove_device(sdev);
scsi_device_put(sdev);
+ goto out_logout_login;
}
+
+ /* No error during __scsi_add_device() */
+ lu->has_sdev = true;
+ scsi_device_put(sdev);
+ sbp2_allow_block(lu);
+ goto out;
+
+ out_logout_login:
+ smp_rmb(); /* generation may have changed */
+ generation = device->generation;
+ smp_rmb(); /* node_id must not be older than generation */
+
+ sbp2_send_management_orb(lu, device->node_id, generation,
+ SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
+ /*
+ * If a bus reset happened, sbp2_update will have requeued
+ * lu->work already. Reset the work from reconnect to login.
+ */
+ PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
out:
- sbp2_target_put(lu->tgt);
+ sbp2_target_put(tgt);
}
static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
@@ -751,10 +944,12 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
return -ENOMEM;
}
- lu->tgt = tgt;
- lu->sdev = NULL;
- lu->lun = lun_entry & 0xffff;
- lu->retries = 0;
+ lu->tgt = tgt;
+ lu->lun = lun_entry & 0xffff;
+ lu->retries = 0;
+ lu->has_sdev = false;
+ lu->blocked = false;
+ ++tgt->dont_block;
INIT_LIST_HEAD(&lu->orb_list);
INIT_DELAYED_WORK(&lu->work, sbp2_login);
@@ -813,7 +1008,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
if (timeout > tgt->mgt_orb_timeout)
fw_notify("%s: config rom contains %ds "
"management ORB timeout, limiting "
- "to %ds\n", tgt->unit->device.bus_id,
+ "to %ds\n", tgt->bus_id,
timeout / 1000,
tgt->mgt_orb_timeout / 1000);
break;
@@ -836,12 +1031,12 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
u32 firmware_revision)
{
int i;
- unsigned w = sbp2_param_workarounds;
+ unsigned int w = sbp2_param_workarounds;
if (w)
fw_notify("Please notify linux1394-devel@lists.sourceforge.net "
"if you need the workarounds parameter for %s\n",
- tgt->unit->device.bus_id);
+ tgt->bus_id);
if (w & SBP2_WORKAROUND_OVERRIDE)
goto out;
@@ -863,8 +1058,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
if (w)
fw_notify("Workarounds for %s: 0x%x "
"(firmware_revision 0x%06x, model_id 0x%06x)\n",
- tgt->unit->device.bus_id,
- w, firmware_revision, model);
+ tgt->bus_id, w, firmware_revision, model);
tgt->workarounds = w;
}
@@ -888,6 +1082,7 @@ static int sbp2_probe(struct device *dev)
tgt->unit = unit;
kref_init(&tgt->kref);
INIT_LIST_HEAD(&tgt->lu_list);
+ tgt->bus_id = unit->device.bus_id;
if (fw_device_enable_phys_dma(device) < 0)
goto fail_shost_put;
@@ -895,6 +1090,8 @@ static int sbp2_probe(struct device *dev)
if (scsi_add_host(shost, &unit->device) < 0)
goto fail_shost_put;
+ fw_device_get(device);
+
/* Initialize to values that won't match anything in our table. */
firmware_revision = 0xff000000;
model = 0xff000000;
@@ -938,10 +1135,13 @@ static void sbp2_reconnect(struct work_struct *work)
{
struct sbp2_logical_unit *lu =
container_of(work, struct sbp2_logical_unit, work.work);
- struct fw_unit *unit = lu->tgt->unit;
- struct fw_device *device = fw_device(unit->device.parent);
+ struct sbp2_target *tgt = lu->tgt;
+ struct fw_device *device = fw_device(tgt->unit->device.parent);
int generation, node_id, local_node_id;
+ if (fw_device_is_shutdown(device))
+ goto out;
+
generation = device->generation;
smp_rmb(); /* node_id must not be older than generation */
node_id = device->node_id;
@@ -950,10 +1150,17 @@ static void sbp2_reconnect(struct work_struct *work)
if (sbp2_send_management_orb(lu, node_id, generation,
SBP2_RECONNECT_REQUEST,
lu->login_id, NULL) < 0) {
- if (lu->retries++ >= 5) {
- fw_error("failed to reconnect to %s\n",
- unit->device.bus_id);
- /* Fall back and try to log in again. */
+ /*
+ * If reconnect was impossible even though we are in the
+ * current generation, fall back and try to log in again.
+ *
+ * We could check for "Function rejected" status, but
+ * looking at the bus generation as simpler and more general.
+ */
+ smp_rmb(); /* get current card generation */
+ if (generation == device->card->generation ||
+ lu->retries++ >= 5) {
+ fw_error("%s: failed to reconnect\n", tgt->bus_id);
lu->retries = 0;
PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
}
@@ -961,17 +1168,18 @@ static void sbp2_reconnect(struct work_struct *work)
goto out;
}
- lu->generation = generation;
- lu->tgt->node_id = node_id;
- lu->tgt->address_high = local_node_id << 16;
+ tgt->node_id = node_id;
+ tgt->address_high = local_node_id << 16;
+ sbp2_set_generation(lu, generation);
- fw_notify("reconnected to %s LUN %04x (%d retries)\n",
- unit->device.bus_id, lu->lun, lu->retries);
+ fw_notify("%s: reconnected to LUN %04x (%d retries)\n",
+ tgt->bus_id, lu->lun, lu->retries);
sbp2_agent_reset(lu);
sbp2_cancel_orbs(lu);
+ sbp2_conditionally_unblock(lu);
out:
- sbp2_target_put(lu->tgt);
+ sbp2_target_put(tgt);
}
static void sbp2_update(struct fw_unit *unit)
@@ -986,6 +1194,7 @@ static void sbp2_update(struct fw_unit *unit)
* Iteration over tgt->lu_list is therefore safe here.
*/
list_for_each_entry(lu, &tgt->lu_list, link) {
+ sbp2_conditionally_block(lu);
lu->retries = 0;
sbp2_queue_work(lu, 0);
}
@@ -1063,7 +1272,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
if (status != NULL) {
if (STATUS_GET_DEAD(*status))
- sbp2_agent_reset(orb->lu);
+ sbp2_agent_reset_no_wait(orb->lu);
switch (STATUS_GET_RESPONSE(*status)) {
case SBP2_STATUS_REQUEST_COMPLETE:
@@ -1089,6 +1298,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
* or when sending the write (less likely).
*/
result = DID_BUS_BUSY << 16;
+ sbp2_conditionally_block(orb->lu);
}
dma_unmap_single(device->card->device, orb->base.request_bus,
@@ -1197,7 +1407,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
struct sbp2_logical_unit *lu = cmd->device->hostdata;
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct sbp2_command_orb *orb;
- unsigned max_payload;
+ unsigned int max_payload;
int retval = SCSI_MLQUEUE_HOST_BUSY;
/*
@@ -1275,6 +1485,10 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
{
struct sbp2_logical_unit *lu = sdev->hostdata;
+ /* (Re-)Adding logical units via the SCSI stack is not supported. */
+ if (!lu)
+ return -ENOSYS;
+
sdev->allow_restart = 1;
/*
@@ -1319,7 +1533,7 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
{
struct sbp2_logical_unit *lu = cmd->device->hostdata;
- fw_notify("sbp2_scsi_abort\n");
+ fw_notify("%s: sbp2_scsi_abort\n", lu->tgt->bus_id);
sbp2_agent_reset(lu);
sbp2_cancel_orbs(lu);
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index 172c1867e9a..e47bb040197 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -383,6 +383,7 @@ void fw_destroy_nodes(struct fw_card *card)
card->color++;
if (card->local_node != NULL)
for_each_fw_node(card, card->local_node, report_lost_node);
+ card->local_node = NULL;
spin_unlock_irqrestore(&card->lock, flags);
}
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index fa7967b5740..09cb7287045 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -26,6 +26,7 @@
#include <linux/fs.h>
#include <linux/dma-mapping.h>
#include <linux/firewire-constants.h>
+#include <asm/atomic.h>
#define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4)
#define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0)
@@ -219,6 +220,7 @@ extern struct bus_type fw_bus_type;
struct fw_card {
const struct fw_card_driver *driver;
struct device *device;
+ atomic_t device_count;
struct kref kref;
int node_id;
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 653265a40b7..4072449ad1c 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -10,10 +10,9 @@
static char dmi_empty_string[] = " ";
-static char * __init dmi_string(const struct dmi_header *dm, u8 s)
+static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s)
{
const u8 *bp = ((u8 *) dm) + dm->length;
- char *str = "";
if (s) {
s--;
@@ -28,14 +27,29 @@ static char * __init dmi_string(const struct dmi_header *dm, u8 s)
if (!memcmp(bp, dmi_empty_string, cmp_len))
return dmi_empty_string;
- str = dmi_alloc(len);
- if (str != NULL)
- strcpy(str, bp);
- else
- printk(KERN_ERR "dmi_string: cannot allocate %Zu bytes.\n", len);
+ return bp;
}
}
+ return "";
+}
+
+static char * __init dmi_string(const struct dmi_header *dm, u8 s)
+{
+ const char *bp = dmi_string_nosave(dm, s);
+ char *str;
+ size_t len;
+
+ if (bp == dmi_empty_string)
+ return dmi_empty_string;
+
+ len = strlen(bp) + 1;
+ str = dmi_alloc(len);
+ if (str != NULL)
+ strcpy(str, bp);
+ else
+ printk(KERN_ERR "dmi_string: cannot allocate %Zu bytes.\n", len);
+
return str;
}
@@ -167,10 +181,30 @@ static void __init dmi_save_type(const struct dmi_header *dm, int slot, int inde
dmi_ident[slot] = s;
}
+static void __init dmi_save_one_device(int type, const char *name)
+{
+ struct dmi_device *dev;
+
+ /* No duplicate device */
+ if (dmi_find_device(type, name, NULL))
+ return;
+
+ dev = dmi_alloc(sizeof(*dev) + strlen(name) + 1);
+ if (!dev) {
+ printk(KERN_ERR "dmi_save_one_device: out of memory.\n");
+ return;
+ }
+
+ dev->type = type;
+ strcpy((char *)(dev + 1), name);
+ dev->name = (char *)(dev + 1);
+ dev->device_data = NULL;
+ list_add(&dev->list, &dmi_devices);
+}
+
static void __init dmi_save_devices(const struct dmi_header *dm)
{
int i, count = (dm->length - sizeof(struct dmi_header)) / 2;
- struct dmi_device *dev;
for (i = 0; i < count; i++) {
const char *d = (char *)(dm + 1) + (i * 2);
@@ -179,23 +213,10 @@ static void __init dmi_save_devices(const struct dmi_header *dm)
if ((*d & 0x80) == 0)
continue;
- dev = dmi_alloc(sizeof(*dev));
- if (!dev) {
- printk(KERN_ERR "dmi_save_devices: out of memory.\n");
- break;
- }
-
- dev->type = *d++ & 0x7f;
- dev->name = dmi_string(dm, *d);
- dev->device_data = NULL;
- list_add(&dev->list, &dmi_devices);
+ dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d + 1)));
}
}
-static struct dmi_device empty_oem_string_dev = {
- .name = dmi_empty_string,
-};
-
static void __init dmi_save_oem_strings_devices(const struct dmi_header *dm)
{
int i, count = *(u8 *)(dm + 1);
@@ -204,10 +225,8 @@ static void __init dmi_save_oem_strings_devices(const struct dmi_header *dm)
for (i = 1; i <= count; i++) {
char *devname = dmi_string(dm, i);
- if (!strcmp(devname, dmi_empty_string)) {
- list_add(&empty_oem_string_dev.list, &dmi_devices);
+ if (devname == dmi_empty_string)
continue;
- }
dev = dmi_alloc(sizeof(*dev));
if (!dev) {
@@ -253,23 +272,12 @@ static void __init dmi_save_ipmi_device(const struct dmi_header *dm)
static void __init dmi_save_extended_devices(const struct dmi_header *dm)
{
const u8 *d = (u8*) dm + 5;
- struct dmi_device *dev;
/* Skip disabled device */
if ((*d & 0x80) == 0)
return;
- dev = dmi_alloc(sizeof(*dev));
- if (!dev) {
- printk(KERN_ERR "dmi_save_extended_devices: out of memory.\n");
- return;
- }
-
- dev->type = *d-- & 0x7f;
- dev->name = dmi_string(dm, *d);
- dev->device_data = NULL;
-
- list_add(&dev->list, &dmi_devices);
+ dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
}
/*
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 410ffe4e9d8..368879ff5d8 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -143,6 +143,16 @@ config SENSORS_ADT7470
This driver can also be built as a module. If so, the module
will be called adt7470.
+config SENSORS_ADT7473
+ tristate "Analog Devices ADT7473"
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for the Analog Devices
+ ADT7473 temperature monitoring chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called adt7473.
+
config SENSORS_K8TEMP
tristate "AMD Athlon64/FX or Opteron temperature sensor"
depends on X86 && PCI && EXPERIMENTAL
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 824161337f1..3bdb05a5cbd 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o
obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o
+obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o
obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
obj-$(CONFIG_SENSORS_AMS) += ams/
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c
index fcd7fe78f3f..466b9ee9279 100644
--- a/drivers/hwmon/ad7418.c
+++ b/drivers/hwmon/ad7418.c
@@ -26,7 +26,7 @@
#define DRV_VERSION "0.3"
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x28, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x28, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_3(ad7416, ad7417, ad7418);
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index b96be772e49..ecbf69484bf 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -31,10 +31,8 @@
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
- 0x29, 0x2a, 0x2b,
- 0x4c, 0x4d, 0x4e,
- I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = {
+ 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm,
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c
index e96c3725203..1d76de7d75c 100644
--- a/drivers/hwmon/adm1025.c
+++ b/drivers/hwmon/adm1025.c
@@ -62,7 +62,7 @@
* NE1619 has two possible addresses: 0x2c and 0x2d.
*/
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
/*
* Insmod parameters
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index 8002f68240c..904c6ce9d83 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -35,7 +35,7 @@
#include <linux/mutex.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(adm1026);
@@ -1624,6 +1624,7 @@ static struct attribute *adm1026_attributes_temp3[] = {
&dev_attr_temp3_crit_enable.attr,
&dev_attr_temp3_auto_point1_pwm.attr,
&dev_attr_temp3_auto_point2_pwm.attr,
+ NULL
};
static const struct attribute_group adm1026_group_temp3 = {
@@ -1639,6 +1640,7 @@ static struct attribute *adm1026_attributes_in8_9[] = {
&sensor_dev_attr_in9_max.dev_attr.attr,
&sensor_dev_attr_in9_min.dev_attr.attr,
&sensor_dev_attr_in9_alarm.dev_attr.attr,
+ NULL
};
static const struct attribute_group adm1026_group_in8_9 = {
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c
index 0bc897dffa2..2c6608d453c 100644
--- a/drivers/hwmon/adm1029.c
+++ b/drivers/hwmon/adm1029.c
@@ -39,10 +39,8 @@
* Addresses to scan
*/
-static unsigned short normal_i2c[] = {
- 0x28, 0x29, 0x2a,
- 0x2b, 0x2c, 0x2d,
- 0x2e, 0x2f, I2C_CLIENT_END
+static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
+ 0x2e, 0x2f, I2C_CLIENT_END
};
/*
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
index 5aaad3636c9..2bffcab7dc9 100644
--- a/drivers/hwmon/adm1031.c
+++ b/drivers/hwmon/adm1031.c
@@ -61,7 +61,7 @@
#define ADM1031_CONF2_TEMP_ENABLE(chan) (0x10 << (chan))
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_2(adm1030, adm1031);
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
index 7671d2bf780..149ef25252e 100644
--- a/drivers/hwmon/adm9240.c
+++ b/drivers/hwmon/adm9240.c
@@ -52,7 +52,7 @@
#include <linux/mutex.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
I2C_CLIENT_END };
/* Insmod parameters */
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c
index 6b8a73ef404..ed71a8bc70d 100644
--- a/drivers/hwmon/ads7828.c
+++ b/drivers/hwmon/ads7828.c
@@ -44,7 +44,7 @@
#define ADS7828_INT_VREF_MV 2500 /* Internal vref is 2.5V, 2500mV */
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
I2C_CLIENT_END };
/* Insmod parameters */
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index 747693ab2ff..6b5325f33a2 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -30,7 +30,7 @@
#include <linux/log2.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(adt7470);
diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c
new file mode 100644
index 00000000000..9587869bdba
--- /dev/null
+++ b/drivers/hwmon/adt7473.c
@@ -0,0 +1,1157 @@
+/*
+ * A hwmon driver for the Analog Devices ADT7473
+ * Copyright (C) 2007 IBM
+ *
+ * Author: Darrick J. Wong <djwong@us.ibm.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 Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/log2.h>
+
+/* Addresses to scan */
+static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(adt7473);
+
+/* ADT7473 registers */
+#define ADT7473_REG_BASE_ADDR 0x20
+
+#define ADT7473_REG_VOLT_BASE_ADDR 0x21
+#define ADT7473_REG_VOLT_MAX_ADDR 0x22
+#define ADT7473_REG_VOLT_MIN_BASE_ADDR 0x46
+#define ADT7473_REG_VOLT_MIN_MAX_ADDR 0x49
+
+#define ADT7473_REG_TEMP_BASE_ADDR 0x25
+#define ADT7473_REG_TEMP_MAX_ADDR 0x27
+#define ADT7473_REG_TEMP_LIMITS_BASE_ADDR 0x4E
+#define ADT7473_REG_TEMP_LIMITS_MAX_ADDR 0x53
+#define ADT7473_REG_TEMP_TMIN_BASE_ADDR 0x67
+#define ADT7473_REG_TEMP_TMIN_MAX_ADDR 0x69
+#define ADT7473_REG_TEMP_TMAX_BASE_ADDR 0x6A
+#define ADT7473_REG_TEMP_TMAX_MAX_ADDR 0x6C
+
+#define ADT7473_REG_FAN_BASE_ADDR 0x28
+#define ADT7473_REG_FAN_MAX_ADDR 0x2F
+#define ADT7473_REG_FAN_MIN_BASE_ADDR 0x54
+#define ADT7473_REG_FAN_MIN_MAX_ADDR 0x5B
+
+#define ADT7473_REG_PWM_BASE_ADDR 0x30
+#define ADT7473_REG_PWM_MAX_ADDR 0x32
+#define ADT7473_REG_PWM_MIN_BASE_ADDR 0x64
+#define ADT7473_REG_PWM_MIN_MAX_ADDR 0x66
+#define ADT7473_REG_PWM_MAX_BASE_ADDR 0x38
+#define ADT7473_REG_PWM_MAX_MAX_ADDR 0x3A
+#define ADT7473_REG_PWM_BHVR_BASE_ADDR 0x5C
+#define ADT7473_REG_PWM_BHVR_MAX_ADDR 0x5E
+#define ADT7473_PWM_BHVR_MASK 0xE0
+#define ADT7473_PWM_BHVR_SHIFT 5
+
+#define ADT7473_REG_CFG1 0x40
+#define ADT7473_CFG1_START 0x01
+#define ADT7473_CFG1_READY 0x04
+#define ADT7473_REG_CFG2 0x73
+#define ADT7473_REG_CFG3 0x78
+#define ADT7473_REG_CFG4 0x7D
+#define ADT7473_CFG4_MAX_DUTY_AT_OVT 0x08
+#define ADT7473_REG_CFG5 0x7C
+#define ADT7473_CFG5_TEMP_TWOS 0x01
+#define ADT7473_CFG5_TEMP_OFFSET 0x02
+
+#define ADT7473_REG_DEVICE 0x3D
+#define ADT7473_VENDOR 0x41
+#define ADT7473_REG_VENDOR 0x3E
+#define ADT7473_DEVICE 0x73
+#define ADT7473_REG_REVISION 0x3F
+#define ADT7473_REV_68 0x68
+#define ADT7473_REV_69 0x69
+
+#define ADT7473_REG_ALARM1 0x41
+#define ADT7473_VCCP_ALARM 0x02
+#define ADT7473_VCC_ALARM 0x04
+#define ADT7473_R1T_ALARM 0x10
+#define ADT7473_LT_ALARM 0x20
+#define ADT7473_R2T_ALARM 0x40
+#define ADT7473_OOL 0x80
+#define ADT7473_REG_ALARM2 0x42
+#define ADT7473_OVT_ALARM 0x02
+#define ADT7473_FAN1_ALARM 0x04
+#define ADT7473_FAN2_ALARM 0x08
+#define ADT7473_FAN3_ALARM 0x10
+#define ADT7473_FAN4_ALARM 0x20
+#define ADT7473_R1T_SHORT 0x40
+#define ADT7473_R2T_SHORT 0x80
+#define ADT7473_REG_MAX_ADDR 0x80
+
+#define ALARM2(x) ((x) << 8)
+
+#define ADT7473_VOLT_COUNT 2
+#define ADT7473_REG_VOLT(x) (ADT7473_REG_VOLT_BASE_ADDR + (x))
+#define ADT7473_REG_VOLT_MIN(x) (ADT7473_REG_VOLT_MIN_BASE_ADDR + ((x) * 2))
+#define ADT7473_REG_VOLT_MAX(x) (ADT7473_REG_VOLT_MIN_BASE_ADDR + \
+ ((x) * 2) + 1)
+
+#define ADT7473_TEMP_COUNT 3
+#define ADT7473_REG_TEMP(x) (ADT7473_REG_TEMP_BASE_ADDR + (x))
+#define ADT7473_REG_TEMP_MIN(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + ((x) * 2))
+#define ADT7473_REG_TEMP_MAX(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + \
+ ((x) * 2) + 1)
+#define ADT7473_REG_TEMP_TMIN(x) (ADT7473_REG_TEMP_TMIN_BASE_ADDR + (x))
+#define ADT7473_REG_TEMP_TMAX(x) (ADT7473_REG_TEMP_TMAX_BASE_ADDR + (x))
+
+#define ADT7473_FAN_COUNT 4
+#define ADT7473_REG_FAN(x) (ADT7473_REG_FAN_BASE_ADDR + ((x) * 2))
+#define ADT7473_REG_FAN_MIN(x) (ADT7473_REG_FAN_MIN_BASE_ADDR + ((x) * 2))
+
+#define ADT7473_PWM_COUNT 3
+#define ADT7473_REG_PWM(x) (ADT7473_REG_PWM_BASE_ADDR + (x))
+#define ADT7473_REG_PWM_MAX(x) (ADT7473_REG_PWM_MAX_BASE_ADDR + (x))
+#define ADT7473_REG_PWM_MIN(x) (ADT7473_REG_PWM_MIN_BASE_ADDR + (x))
+#define ADT7473_REG_PWM_BHVR(x) (ADT7473_REG_PWM_BHVR_BASE_ADDR + (x))
+
+/* How often do we reread sensors values? (In jiffies) */
+#define SENSOR_REFRESH_INTERVAL (2 * HZ)
+
+/* How often do we reread sensor limit values? (In jiffies) */
+#define LIMIT_REFRESH_INTERVAL (60 * HZ)
+
+/* datasheet says to divide this number by the fan reading to get fan rpm */
+#define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x))
+#define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM
+#define FAN_PERIOD_INVALID 65535
+#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID)
+
+struct adt7473_data {
+ struct i2c_client client;
+ struct device *hwmon_dev;
+ struct attribute_group attrs;
+ struct mutex lock;
+ char sensors_valid;
+ char limits_valid;
+ unsigned long sensors_last_updated; /* In jiffies */
+ unsigned long limits_last_updated; /* In jiffies */
+
+ u8 volt[ADT7473_VOLT_COUNT];
+ s8 volt_min[ADT7473_VOLT_COUNT];
+ s8 volt_max[ADT7473_VOLT_COUNT];
+
+ s8 temp[ADT7473_TEMP_COUNT];
+ s8 temp_min[ADT7473_TEMP_COUNT];
+ s8 temp_max[ADT7473_TEMP_COUNT];
+ s8 temp_tmin[ADT7473_TEMP_COUNT];
+ /* This is called the !THERM limit in the datasheet */
+ s8 temp_tmax[ADT7473_TEMP_COUNT];
+
+ u16 fan[ADT7473_FAN_COUNT];
+ u16 fan_min[ADT7473_FAN_COUNT];
+
+ u8 pwm[ADT7473_PWM_COUNT];
+ u8 pwm_max[ADT7473_PWM_COUNT];
+ u8 pwm_min[ADT7473_PWM_COUNT];
+ u8 pwm_behavior[ADT7473_PWM_COUNT];
+
+ u8 temp_twos_complement;
+ u8 temp_offset;
+
+ u16 alarm;
+ u8 max_duty_at_overheat;
+};
+
+static int adt7473_attach_adapter(struct i2c_adapter *adapter);
+static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind);
+static int adt7473_detach_client(struct i2c_client *client);
+
+static struct i2c_driver adt7473_driver = {
+ .driver = {
+ .name = "adt7473",
+ },
+ .attach_adapter = adt7473_attach_adapter,
+ .detach_client = adt7473_detach_client,
+};
+
+/*
+ * 16-bit registers on the ADT7473 are low-byte first. The data sheet says
+ * that the low byte must be read before the high byte.
+ */
+static inline int adt7473_read_word_data(struct i2c_client *client, u8 reg)
+{
+ u16 foo;
+ foo = i2c_smbus_read_byte_data(client, reg);
+ foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8);
+ return foo;
+}
+
+static inline int adt7473_write_word_data(struct i2c_client *client, u8 reg,
+ u16 value)
+{
+ return i2c_smbus_write_byte_data(client, reg, value & 0xFF)
+ && i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
+}
+
+static void adt7473_init_client(struct i2c_client *client)
+{
+ int reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG1);
+
+ if (!(reg & ADT7473_CFG1_READY)) {
+ dev_err(&client->dev, "Chip not ready.\n");
+ } else {
+ /* start monitoring */
+ i2c_smbus_write_byte_data(client, ADT7473_REG_CFG1,
+ reg | ADT7473_CFG1_START);
+ }
+}
+
+static struct adt7473_data *adt7473_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ unsigned long local_jiffies = jiffies;
+ u8 cfg;
+ int i;
+
+ mutex_lock(&data->lock);
+ if (time_before(local_jiffies, data->sensors_last_updated +
+ SENSOR_REFRESH_INTERVAL)
+ && data->sensors_valid)
+ goto no_sensor_update;
+
+ for (i = 0; i < ADT7473_VOLT_COUNT; i++)
+ data->volt[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_VOLT(i));
+
+ /* Determine temperature encoding */
+ cfg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG5);
+ data->temp_twos_complement = (cfg & ADT7473_CFG5_TEMP_TWOS);
+
+ /*
+ * What does this do? it implies a variable temperature sensor
+ * offset, but the datasheet doesn't say anything about this bit
+ * and other parts of the datasheet imply that "offset64" mode
+ * means that you shift temp values by -64 if the above bit was set.
+ */
+ data->temp_offset = (cfg & ADT7473_CFG5_TEMP_OFFSET);
+
+ for (i = 0; i < ADT7473_TEMP_COUNT; i++)
+ data->temp[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_TEMP(i));
+
+ for (i = 0; i < ADT7473_FAN_COUNT; i++)
+ data->fan[i] = adt7473_read_word_data(client,
+ ADT7473_REG_FAN(i));
+
+ for (i = 0; i < ADT7473_PWM_COUNT; i++)
+ data->pwm[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_PWM(i));
+
+ data->alarm = i2c_smbus_read_byte_data(client, ADT7473_REG_ALARM1);
+ if (data->alarm & ADT7473_OOL)
+ data->alarm |= ALARM2(i2c_smbus_read_byte_data(client,
+ ADT7473_REG_ALARM2));
+
+ data->sensors_last_updated = local_jiffies;
+ data->sensors_valid = 1;
+
+no_sensor_update:
+ if (time_before(local_jiffies, data->limits_last_updated +
+ LIMIT_REFRESH_INTERVAL)
+ && data->limits_valid)
+ goto out;
+
+ for (i = 0; i < ADT7473_VOLT_COUNT; i++) {
+ data->volt_min[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_VOLT_MIN(i));
+ data->volt_max[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_VOLT_MAX(i));
+ }
+
+ for (i = 0; i < ADT7473_TEMP_COUNT; i++) {
+ data->temp_min[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_TEMP_MIN(i));
+ data->temp_max[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_TEMP_MAX(i));
+ data->temp_tmin[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_TEMP_TMIN(i));
+ data->temp_tmax[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_TEMP_TMAX(i));
+ }
+
+ for (i = 0; i < ADT7473_FAN_COUNT; i++)
+ data->fan_min[i] = adt7473_read_word_data(client,
+ ADT7473_REG_FAN_MIN(i));
+
+ for (i = 0; i < ADT7473_PWM_COUNT; i++) {
+ data->pwm_max[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_PWM_MAX(i));
+ data->pwm_min[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_PWM_MIN(i));
+ data->pwm_behavior[i] = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_PWM_BHVR(i));
+ }
+
+ data->limits_last_updated = local_jiffies;
+ data->limits_valid = 1;
+
+out:
+ mutex_unlock(&data->lock);
+ return data;
+}
+
+/*
+ * On this chip, voltages are given as a count of steps between a minimum
+ * and maximum voltage, not a direct voltage.
+ */
+static const int volt_convert_table[][2] = {
+ {2997, 3},
+ {4395, 4},
+};
+
+static int decode_volt(int volt_index, u8 raw)
+{
+ int cmax = volt_convert_table[volt_index][0];
+ int cmin = volt_convert_table[volt_index][1];
+ return ((raw * (cmax - cmin)) / 255) + cmin;
+}
+
+static u8 encode_volt(int volt_index, int cooked)
+{
+ int cmax = volt_convert_table[volt_index][0];
+ int cmin = volt_convert_table[volt_index][1];
+ u8 x;
+
+ if (cooked > cmax)
+ cooked = cmax;
+ else if (cooked < cmin)
+ cooked = cmin;
+
+ x = ((cooked - cmin) * 255) / (cmax - cmin);
+
+ return x;
+}
+
+static ssize_t show_volt_min(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n",
+ decode_volt(attr->index, data->volt_min[attr->index]));
+}
+
+static ssize_t set_volt_min(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int volt = encode_volt(attr->index, simple_strtol(buf, NULL, 10));
+
+ mutex_lock(&data->lock);
+ data->volt_min[attr->index] = volt;
+ i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MIN(attr->index),
+ volt);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_volt_max(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n",
+ decode_volt(attr->index, data->volt_max[attr->index]));
+}
+
+static ssize_t set_volt_max(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int volt = encode_volt(attr->index, simple_strtol(buf, NULL, 10));
+
+ mutex_lock(&data->lock);
+ data->volt_max[attr->index] = volt;
+ i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MAX(attr->index),
+ volt);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_volt(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+
+ return sprintf(buf, "%d\n",
+ decode_volt(attr->index, data->volt[attr->index]));
+}
+
+/*
+ * This chip can report temperature data either as a two's complement
+ * number in the range -128 to 127, or as an unsigned number that must
+ * be offset by 64.
+ */
+static int decode_temp(struct adt7473_data *data, u8 raw)
+{
+ if (data->temp_twos_complement)
+ return (s8)raw;
+ return raw - 64;
+}
+
+static u8 encode_temp(struct adt7473_data *data, int cooked)
+{
+ if (data->temp_twos_complement)
+ return (cooked & 0xFF);
+ return cooked + 64;
+}
+
+static ssize_t show_temp_min(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n",
+ 1000 * decode_temp(data, data->temp_min[attr->index]));
+}
+
+static ssize_t set_temp_min(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10) / 1000;
+ temp = encode_temp(data, temp);
+
+ mutex_lock(&data->lock);
+ data->temp_min[attr->index] = temp;
+ i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MIN(attr->index),
+ temp);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_temp_max(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n",
+ 1000 * decode_temp(data, data->temp_max[attr->index]));
+}
+
+static ssize_t set_temp_max(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10) / 1000;
+ temp = encode_temp(data, temp);
+
+ mutex_lock(&data->lock);
+ data->temp_max[attr->index] = temp;
+ i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MAX(attr->index),
+ temp);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n",
+ 1000 * decode_temp(data, data->temp[attr->index]));
+}
+
+static ssize_t show_fan_min(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+
+ if (FAN_DATA_VALID(data->fan_min[attr->index]))
+ return sprintf(buf, "%d\n",
+ FAN_PERIOD_TO_RPM(data->fan_min[attr->index]));
+ else
+ return sprintf(buf, "0\n");
+}
+
+static ssize_t set_fan_min(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10);
+
+ if (!temp)
+ return -EINVAL;
+ temp = FAN_RPM_TO_PERIOD(temp);
+
+ mutex_lock(&data->lock);
+ data->fan_min[attr->index] = temp;
+ adt7473_write_word_data(client, ADT7473_REG_FAN_MIN(attr->index), temp);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+
+ if (FAN_DATA_VALID(data->fan[attr->index]))
+ return sprintf(buf, "%d\n",
+ FAN_PERIOD_TO_RPM(data->fan[attr->index]));
+ else
+ return sprintf(buf, "0\n");
+}
+
+static ssize_t show_max_duty_at_crit(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n", data->max_duty_at_overheat);
+}
+
+static ssize_t set_max_duty_at_crit(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ u8 reg;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10);
+ temp = temp && 0xFF;
+
+ mutex_lock(&data->lock);
+ data->max_duty_at_overheat = temp;
+ reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
+ if (temp)
+ reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT;
+ else
+ reg &= ~ADT7473_CFG4_MAX_DUTY_AT_OVT;
+ i2c_smbus_write_byte_data(client, ADT7473_REG_CFG4, reg);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n", data->pwm[attr->index]);
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10);
+
+ mutex_lock(&data->lock);
+ data->pwm[attr->index] = temp;
+ i2c_smbus_write_byte_data(client, ADT7473_REG_PWM(attr->index), temp);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_pwm_max(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n", data->pwm_max[attr->index]);
+}
+
+static ssize_t set_pwm_max(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10);
+
+ mutex_lock(&data->lock);
+ data->pwm_max[attr->index] = temp;
+ i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MAX(attr->index),
+ temp);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_pwm_min(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n", data->pwm_min[attr->index]);
+}
+
+static ssize_t set_pwm_min(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10);
+
+ mutex_lock(&data->lock);
+ data->pwm_min[attr->index] = temp;
+ i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MIN(attr->index),
+ temp);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_temp_tmax(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n",
+ 1000 * decode_temp(data, data->temp_tmax[attr->index]));
+}
+
+static ssize_t set_temp_tmax(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10) / 1000;
+ temp = encode_temp(data, temp);
+
+ mutex_lock(&data->lock);
+ data->temp_tmax[attr->index] = temp;
+ i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMAX(attr->index),
+ temp);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_temp_tmin(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ return sprintf(buf, "%d\n",
+ 1000 * decode_temp(data, data->temp_tmin[attr->index]));
+}
+
+static ssize_t set_temp_tmin(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10) / 1000;
+ temp = encode_temp(data, temp);
+
+ mutex_lock(&data->lock);
+ data->temp_tmin[attr->index] = temp;
+ i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMIN(attr->index),
+ temp);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_pwm_enable(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+
+ switch (data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT) {
+ case 3:
+ return sprintf(buf, "0\n");
+ case 7:
+ return sprintf(buf, "1\n");
+ default:
+ return sprintf(buf, "2\n");
+ }
+}
+
+static ssize_t set_pwm_enable(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ u8 reg;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10);
+
+ switch (temp) {
+ case 0:
+ temp = 3;
+ break;
+ case 1:
+ temp = 7;
+ break;
+ case 2:
+ /* Enter automatic mode with fans off */
+ temp = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ mutex_lock(&data->lock);
+ reg = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_PWM_BHVR(attr->index));
+ reg = (temp << ADT7473_PWM_BHVR_SHIFT) |
+ (reg & ~ADT7473_PWM_BHVR_MASK);
+ i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index),
+ reg);
+ data->pwm_behavior[attr->index] = reg;
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_pwm_auto_temp(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+ int bhvr = data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT;
+
+ switch (bhvr) {
+ case 3:
+ case 4:
+ case 7:
+ return sprintf(buf, "0\n");
+ case 0:
+ case 1:
+ case 5:
+ case 6:
+ return sprintf(buf, "%d\n", bhvr + 1);
+ case 2:
+ return sprintf(buf, "4\n");
+ }
+ /* shouldn't ever get here */
+ BUG();
+}
+
+static ssize_t set_pwm_auto_temp(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ u8 reg;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7473_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10);
+
+ switch (temp) {
+ case 1:
+ case 2:
+ case 6:
+ case 7:
+ temp--;
+ break;
+ case 0:
+ temp = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ mutex_lock(&data->lock);
+ reg = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_PWM_BHVR(attr->index));
+ reg = (temp << ADT7473_PWM_BHVR_SHIFT) |
+ (reg & ~ADT7473_PWM_BHVR_MASK);
+ i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index),
+ reg);
+ data->pwm_behavior[attr->index] = reg;
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_alarm(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adt7473_data *data = adt7473_update_device(dev);
+
+ if (data->alarm & attr->index)
+ return sprintf(buf, "1\n");
+ else
+ return sprintf(buf, "0\n");
+}
+
+
+static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max,
+ set_volt_max, 0);
+static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max,
+ set_volt_max, 1);
+
+static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min,
+ set_volt_min, 0);
+static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min,
+ set_volt_min, 1);
+
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_volt, NULL, 0);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_volt, NULL, 1);
+
+static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL,
+ ADT7473_VCCP_ALARM);
+static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL,
+ ADT7473_VCC_ALARM);
+
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
+ set_temp_max, 0);
+static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
+ set_temp_max, 1);
+static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max,
+ set_temp_max, 2);
+
+static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min,
+ set_temp_min, 0);
+static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min,
+ set_temp_min, 1);
+static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min,
+ set_temp_min, 2);
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
+
+static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL,
+ ADT7473_R1T_ALARM | ALARM2(ADT7473_R1T_SHORT));
+static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL,
+ ADT7473_LT_ALARM);
+static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL,
+ ADT7473_R2T_ALARM | ALARM2(ADT7473_R2T_SHORT));
+
+static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
+ set_fan_min, 0);
+static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
+ set_fan_min, 1);
+static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
+ set_fan_min, 2);
+static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
+ set_fan_min, 3);
+
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3);
+
+static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL,
+ ALARM2(ADT7473_FAN1_ALARM));
+static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL,
+ ALARM2(ADT7473_FAN2_ALARM));
+static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL,
+ ALARM2(ADT7473_FAN3_ALARM));
+static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL,
+ ALARM2(ADT7473_FAN4_ALARM));
+
+static SENSOR_DEVICE_ATTR(pwm_use_point2_pwm_at_crit, S_IWUSR | S_IRUGO,
+ show_max_duty_at_crit, set_max_duty_at_crit, 0);
+
+static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0);
+static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1);
+static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2);
+
+static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
+ show_pwm_min, set_pwm_min, 0);
+static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO,
+ show_pwm_min, set_pwm_min, 1);
+static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO,
+ show_pwm_min, set_pwm_min, 2);
+
+static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
+ show_pwm_max, set_pwm_max, 0);
+static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO,
+ show_pwm_max, set_pwm_max, 1);
+static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO,
+ show_pwm_max, set_pwm_max, 2);
+
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO,
+ show_temp_tmin, set_temp_tmin, 0);
+static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO,
+ show_temp_tmin, set_temp_tmin, 1);
+static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO,
+ show_temp_tmin, set_temp_tmin, 2);
+
+static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO,
+ show_temp_tmax, set_temp_tmax, 0);
+static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO,
+ show_temp_tmax, set_temp_tmax, 1);
+static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO,
+ show_temp_tmax, set_temp_tmax, 2);
+
+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+ set_pwm_enable, 0);
+static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+ set_pwm_enable, 1);
+static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+ set_pwm_enable, 2);
+
+static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO,
+ show_pwm_auto_temp, set_pwm_auto_temp, 0);
+static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO,
+ show_pwm_auto_temp, set_pwm_auto_temp, 1);
+static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
+ show_pwm_auto_temp, set_pwm_auto_temp, 2);
+
+static struct attribute *adt7473_attr[] =
+{
+ &sensor_dev_attr_in1_max.dev_attr.attr,
+ &sensor_dev_attr_in2_max.dev_attr.attr,
+ &sensor_dev_attr_in1_min.dev_attr.attr,
+ &sensor_dev_attr_in2_min.dev_attr.attr,
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ &sensor_dev_attr_in2_input.dev_attr.attr,
+ &sensor_dev_attr_in1_alarm.dev_attr.attr,
+ &sensor_dev_attr_in2_alarm.dev_attr.attr,
+
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ &sensor_dev_attr_temp2_max.dev_attr.attr,
+ &sensor_dev_attr_temp3_max.dev_attr.attr,
+ &sensor_dev_attr_temp1_min.dev_attr.attr,
+ &sensor_dev_attr_temp2_min.dev_attr.attr,
+ &sensor_dev_attr_temp3_min.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp2_input.dev_attr.attr,
+ &sensor_dev_attr_temp3_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp2_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp3_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+ &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr,
+ &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr,
+ &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
+ &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
+ &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_min.dev_attr.attr,
+ &sensor_dev_attr_fan2_min.dev_attr.attr,
+ &sensor_dev_attr_fan3_min.dev_attr.attr,
+ &sensor_dev_attr_fan4_min.dev_attr.attr,
+ &sensor_dev_attr_fan1_input.dev_attr.attr,
+ &sensor_dev_attr_fan2_input.dev_attr.attr,
+ &sensor_dev_attr_fan3_input.dev_attr.attr,
+ &sensor_dev_attr_fan4_input.dev_attr.attr,
+ &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan2_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan3_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan4_alarm.dev_attr.attr,
+
+ &sensor_dev_attr_pwm_use_point2_pwm_at_crit.dev_attr.attr,
+
+ &sensor_dev_attr_pwm1.dev_attr.attr,
+ &sensor_dev_attr_pwm2.dev_attr.attr,
+ &sensor_dev_attr_pwm3.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
+
+ &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm2_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm3_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
+
+ NULL
+};
+
+static int adt7473_attach_adapter(struct i2c_adapter *adapter)
+{
+ if (!(adapter->class & I2C_CLASS_HWMON))
+ return 0;
+ return i2c_probe(adapter, &addr_data, adt7473_detect);
+}
+
+static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *client;
+ struct adt7473_data *data;
+ int err = 0;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ goto exit;
+
+ data = kzalloc(sizeof(struct adt7473_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ client = &data->client;
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &adt7473_driver;
+
+ i2c_set_clientdata(client, data);
+
+ mutex_init(&data->lock);
+
+ if (kind <= 0) {
+ int vendor, device, revision;
+
+ vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR);
+ if (vendor != ADT7473_VENDOR) {
+ err = -ENODEV;
+ goto exit_free;
+ }
+
+ device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE);
+ if (device != ADT7473_DEVICE) {
+ err = -ENODEV;
+ goto exit_free;
+ }
+
+ revision = i2c_smbus_read_byte_data(client,
+ ADT7473_REG_REVISION);
+ if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69) {
+ err = -ENODEV;
+ goto exit_free;
+ }
+ } else
+ dev_dbg(&adapter->dev, "detection forced\n");
+
+ strlcpy(client->name, "adt7473", I2C_NAME_SIZE);
+
+ err = i2c_attach_client(client);
+ if (err)
+ goto exit_free;
+
+ dev_info(&client->dev, "%s chip found\n", client->name);
+
+ /* Initialize the ADT7473 chip */
+ adt7473_init_client(client);
+
+ /* Register sysfs hooks */
+ data->attrs.attrs = adt7473_attr;
+ err = sysfs_create_group(&client->dev.kobj, &data->attrs);
+ if (err)
+ goto exit_detach;
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &data->attrs);
+exit_detach:
+ i2c_detach_client(client);
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int adt7473_detach_client(struct i2c_client *client)
+{
+ struct adt7473_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &data->attrs);
+ i2c_detach_client(client);
+ kfree(data);
+ return 0;
+}
+
+static int __init adt7473_init(void)
+{
+ return i2c_add_driver(&adt7473_driver);
+}
+
+static void __exit adt7473_exit(void)
+{
+ i2c_del_driver(&adt7473_driver);
+}
+
+MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
+MODULE_DESCRIPTION("ADT7473 driver");
+MODULE_LICENSE("GPL");
+
+module_init(adt7473_init);
+module_exit(adt7473_exit);
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 0c94770b7f8..aacc0c4b809 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -84,12 +84,15 @@ static const char* temperature_sensors_sets[][36] = {
/* Set 0: Macbook Pro */
{ "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
"Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
-/* Set 1: Macbook set */
+/* Set 1: Macbook2 set */
+ { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H",
+ "Th0S", "Th1H", NULL },
+/* Set 2: Macbook set */
{ "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S",
"Th1H", "Ts0P", NULL },
-/* Set 2: Macmini set */
+/* Set 3: Macmini set */
{ "TC0D", "TC0P", NULL },
-/* Set 3: Mac Pro (2 x Quad-Core) */
+/* Set 4: Mac Pro (2 x Quad-Core) */
{ "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
"TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P",
"TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S",
@@ -1212,12 +1215,14 @@ static void applesmc_release_accelerometer(void)
static __initdata struct dmi_match_data applesmc_dmi_data[] = {
/* MacBook Pro: accelerometer, backlight and temperature set 0 */
{ .accelerometer = 1, .light = 1, .temperature_set = 0 },
-/* MacBook: accelerometer and temperature set 1 */
+/* MacBook2: accelerometer and temperature set 1 */
{ .accelerometer = 1, .light = 0, .temperature_set = 1 },
-/* MacMini: temperature set 2 */
- { .accelerometer = 0, .light = 0, .temperature_set = 2 },
-/* MacPro: temperature set 3 */
+/* MacBook: accelerometer and temperature set 2 */
+ { .accelerometer = 1, .light = 0, .temperature_set = 2 },
+/* MacMini: temperature set 3 */
{ .accelerometer = 0, .light = 0, .temperature_set = 3 },
+/* MacPro: temperature set 4 */
+ { .accelerometer = 0, .light = 0, .temperature_set = 4 },
};
/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
@@ -1229,16 +1234,20 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
(void*)&applesmc_dmi_data[0]},
{ applesmc_dmi_match, "Apple MacBook", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
+ DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
(void*)&applesmc_dmi_data[1]},
+ { applesmc_dmi_match, "Apple MacBook", {
+ DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
+ (void*)&applesmc_dmi_data[2]},
{ applesmc_dmi_match, "Apple Macmini", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
- (void*)&applesmc_dmi_data[2]},
+ (void*)&applesmc_dmi_data[3]},
{ applesmc_dmi_match, "Apple MacPro2", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
- (void*)&applesmc_dmi_data[3]},
+ (void*)&applesmc_dmi_data[4]},
{ .ident = NULL }
};
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index 950cea8d1d6..84712a22ace 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -49,7 +49,7 @@
#include "lm75.h"
/* I2C addresses to scan */
-static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(asb100);
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c
index cce3350e539..01c17e387f0 100644
--- a/drivers/hwmon/atxp1.c
+++ b/drivers/hwmon/atxp1.c
@@ -42,7 +42,7 @@ MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
#define ATXP1_VIDMASK 0x1f
#define ATXP1_GPIO1MASK 0x0f
-static unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
I2C_CLIENT_INSMOD_1(atxp1);
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 3ee60d26e3a..70239acecc8 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -38,7 +38,8 @@
#define DRVNAME "coretemp"
-typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW;
+typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL,
+ SHOW_NAME } SHOW;
/*
* Functions declaration
@@ -55,6 +56,7 @@ struct coretemp_data {
unsigned long last_updated; /* in jiffies */
int temp;
int tjmax;
+ int ttarget;
u8 alarm;
};
@@ -93,9 +95,10 @@ static ssize_t show_temp(struct device *dev,
if (attr->index == SHOW_TEMP)
err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
- else
+ else if (attr->index == SHOW_TJMAX)
err = sprintf(buf, "%d\n", data->tjmax);
-
+ else
+ err = sprintf(buf, "%d\n", data->ttarget);
return err;
}
@@ -103,6 +106,8 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
SHOW_TEMP);
static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
SHOW_TJMAX);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL,
+ SHOW_TTARGET);
static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
@@ -147,6 +152,56 @@ static struct coretemp_data *coretemp_update_device(struct device *dev)
return data;
}
+static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
+{
+ /* The 100C is default for both mobile and non mobile CPUs */
+
+ int tjmax = 100000;
+ int ismobile = 1;
+ int err;
+ u32 eax, edx;
+
+ /* Early chips have no MSR for TjMax */
+
+ if ((c->x86_model == 0xf) && (c->x86_mask < 4)) {
+ ismobile = 0;
+ }
+
+ if ((c->x86_model > 0xe) && (ismobile)) {
+
+ /* Now we can detect the mobile CPU using Intel provided table
+ http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
+ For Core2 cores, check MSR 0x17, bit 28 1 = Mobile CPU
+ */
+
+ err = rdmsr_safe_on_cpu(id, 0x17, &eax, &edx);
+ if (err) {
+ dev_warn(dev,
+ "Unable to access MSR 0x17, assuming desktop"
+ " CPU\n");
+ ismobile = 0;
+ } else if (!(eax & 0x10000000)) {
+ ismobile = 0;
+ }
+ }
+
+ if (ismobile) {
+
+ err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx);
+ if (err) {
+ dev_warn(dev,
+ "Unable to access MSR 0xEE, for Tjmax, left"
+ " at default");
+ } else if (eax & 0x40000000) {
+ tjmax = 85000;
+ }
+ } else {
+ dev_warn(dev, "Using relative temperature scale!\n");
+ }
+
+ return tjmax;
+}
+
static int __devinit coretemp_probe(struct platform_device *pdev)
{
struct coretemp_data *data;
@@ -163,8 +218,6 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
data->id = pdev->id;
data->name = "coretemp";
mutex_init(&data->update_lock);
- /* Tjmax default is 100 degrees C */
- data->tjmax = 100000;
/* test if we can access the THERM_STATUS MSR */
err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
@@ -191,40 +244,29 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
}
}
- /* Some processors have Tjmax 85 following magic should detect it
- Intel won't disclose the information without signed NDA, but
- individuals cannot sign it. Catch(ed) 22.
- */
+ data->tjmax = adjust_tjmax(c, data->id, &pdev->dev);
+ platform_set_drvdata(pdev, data);
- if (((c->x86_model == 0xf) && (c->x86_mask > 3)) ||
- (c->x86_model == 0xe)) {
- err = rdmsr_safe_on_cpu(data->id, 0xee, &eax, &edx);
+ /* read the still undocumented IA32_TEMPERATURE_TARGET it exists
+ on older CPUs but not in this register */
+
+ if (c->x86_model > 0xe) {
+ err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx);
if (err) {
- dev_warn(&pdev->dev,
- "Unable to access MSR 0xEE, Tjmax left at %d "
- "degrees C\n", data->tjmax/1000);
- } else if (eax & 0x40000000) {
- data->tjmax = 85000;
+ dev_warn(&pdev->dev, "Unable to read"
+ " IA32_TEMPERATURE_TARGET MSR\n");
+ } else {
+ data->ttarget = data->tjmax -
+ (((eax >> 8) & 0xff) * 1000);
+ err = device_create_file(&pdev->dev,
+ &sensor_dev_attr_temp1_max.dev_attr);
+ if (err)
+ goto exit_free;
}
}
- /* Intel says that above should not work for desktop Core2 processors,
- but it seems to work. There is no other way how get the absolute
- readings. Warn the user about this. First check if are desktop,
- bit 50 of MSR_IA32_PLATFORM_ID should be 0.
- */
-
- rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx);
-
- if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) {
- dev_warn(&pdev->dev, "Using undocumented features, absolute "
- "temperature might be wrong!\n");
- }
-
- platform_set_drvdata(pdev, data);
-
if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
- goto exit_free;
+ goto exit_dev;
data->hwmon_dev = hwmon_device_register(&pdev->dev);
if (IS_ERR(data->hwmon_dev)) {
@@ -238,6 +280,8 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
exit_class:
sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
+exit_dev:
+ device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
exit_free:
kfree(data);
exit:
@@ -250,6 +294,7 @@ static int __devexit coretemp_remove(struct platform_device *pdev)
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
+ device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
platform_set_drvdata(pdev, NULL);
kfree(data);
return 0;
@@ -330,7 +375,7 @@ static void coretemp_device_remove(unsigned int cpu)
mutex_unlock(&pdev_list_mutex);
}
-static int coretemp_cpu_callback(struct notifier_block *nfb,
+static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned long) hcpu;
@@ -347,7 +392,7 @@ static int coretemp_cpu_callback(struct notifier_block *nfb,
return NOTIFY_OK;
}
-static struct notifier_block coretemp_cpu_notifier = {
+static struct notifier_block coretemp_cpu_notifier __refdata = {
.notifier_call = coretemp_cpu_callback,
};
#endif /* !CONFIG_HOTPLUG_CPU */
@@ -368,10 +413,10 @@ static int __init coretemp_init(void)
for_each_online_cpu(i) {
struct cpuinfo_x86 *c = &cpu_data(i);
- /* check if family 6, models e, f, 16 */
+ /* check if family 6, models 0xe, 0xf, 0x16, 0x17 */
if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
!((c->x86_model == 0xe) || (c->x86_model == 0xf) ||
- (c->x86_model == 0x16))) {
+ (c->x86_model == 0x16) || (c->x86_model == 0x17))) {
/* supported CPU not found, but report the unknown
family 6 CPU */
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index ddddd9f34c1..7673f65877e 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -49,7 +49,7 @@ module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
/* Addresses to scan */
-static unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
+static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(dme1737);
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index 3f5163de13c..5f300ffed65 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -34,7 +34,7 @@
#include "lm75.h"
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
/* Insmod parameters */
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 6892f76fc18..1464338e4e1 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -37,7 +37,7 @@
#include <linux/f75375s.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_2(f75373, f75375);
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c
index 721c70177b1..ed26b66e083 100644
--- a/drivers/hwmon/fscher.c
+++ b/drivers/hwmon/fscher.c
@@ -40,7 +40,7 @@
* Addresses to scan
*/
-static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
/*
* Insmod parameters
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index b7c9eef0f92..bd89d270a5e 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -44,7 +44,7 @@
#include <linux/dmi.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c
index 2f1075323a1..00f48484e54 100644
--- a/drivers/hwmon/fscpos.c
+++ b/drivers/hwmon/fscpos.c
@@ -43,7 +43,7 @@
/*
* Addresses to scan
*/
-static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
/*
* Insmod parameters
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
index 3b1ac48fce2..33e9e8a8d1c 100644
--- a/drivers/hwmon/gl518sm.c
+++ b/drivers/hwmon/gl518sm.c
@@ -44,7 +44,7 @@
#include <linux/sysfs.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_2(gl518sm_r00, gl518sm_r80);
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index 03ecdc33476..8984ef14162 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -39,7 +39,7 @@ module_param(extra_sensor_type, ushort, 0);
MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=temperature, 2=voltage)");
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(gl520sm);
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 650b07d5b90..11628700808 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -53,7 +53,7 @@
* Address is fully defined internally and cannot be changed.
*/
-static unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
/*
* Insmod parameters
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index e5c35a355a5..115f4090b98 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -31,7 +31,7 @@
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
/* Insmod parameters */
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index 459b70ad6be..36d5a8c3ad8 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -36,7 +36,8 @@
#include <linux/mutex.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
+ I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(lm77);
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index 0a9eb1f6f4e..ed7859f0e16 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -37,8 +37,8 @@
static struct platform_device *pdev;
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
- 0x2e, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
+ 0x2e, 0x2f, I2C_CLIENT_END };
static unsigned short isa_address = 0x290;
/* Insmod parameters */
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c
index a2ca055f392..26c91c9d476 100644
--- a/drivers/hwmon/lm80.c
+++ b/drivers/hwmon/lm80.c
@@ -32,8 +32,8 @@
#include <linux/mutex.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c,
- 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
+ 0x2e, 0x2f, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(lm80);
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c
index 6e8903a6e90..6a8642fa25f 100644
--- a/drivers/hwmon/lm83.c
+++ b/drivers/hwmon/lm83.c
@@ -48,10 +48,8 @@
* addresses.
*/
-static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
- 0x29, 0x2a, 0x2b,
- 0x4c, 0x4d, 0x4e,
- I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = {
+ 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
/*
* Insmod parameters
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index 4bb0f291a6b..182fe6a5605 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -35,7 +35,7 @@
#include <linux/mutex.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102);
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
index 8ee07c5c97a..e1c183f0aae 100644
--- a/drivers/hwmon/lm87.c
+++ b/drivers/hwmon/lm87.c
@@ -73,7 +73,7 @@
* LM87 has three possible addresses: 0x2c, 0x2d and 0x2e.
*/
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
/*
* Insmod parameters
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index f7ec95bedbf..d1a3da3dd8e 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -101,10 +101,8 @@
* 0x4c, 0x4d or 0x4e.
*/
-static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
- 0x29, 0x2a, 0x2b,
- 0x4c, 0x4d, 0x4e,
- I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = {
+ 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
/*
* Insmod parameters
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c
index af5c77d568f..c31942e0824 100644
--- a/drivers/hwmon/lm92.c
+++ b/drivers/hwmon/lm92.c
@@ -45,13 +45,14 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* The LM92 and MAX6635 have 2 two-state pins for address selection,
resulting in 4 possible addresses. */
-static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
- I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
+ I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(lm92);
@@ -209,6 +210,14 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch
return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input));
}
+static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ int bitnr = to_sensor_dev_attr(attr)->index;
+ struct lm92_data *data = lm92_update_device(dev);
+ return sprintf(buf, "%d\n", (data->temp1_input >> bitnr) & 1);
+}
+
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL);
static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp1_crit,
set_temp1_crit);
@@ -221,6 +230,9 @@ static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp1_max,
set_temp1_max);
static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp1_max_hyst, NULL);
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1);
/*
@@ -297,7 +309,9 @@ static struct attribute *lm92_attributes[] = {
&dev_attr_temp1_max.attr,
&dev_attr_temp1_max_hyst.attr,
&dev_attr_alarms.attr,
-
+ &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
NULL
};
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c
index ea61946a4bf..5e678f5c883 100644
--- a/drivers/hwmon/lm93.c
+++ b/drivers/hwmon/lm93.c
@@ -142,7 +142,7 @@
I2C_FUNC_SMBUS_WORD_DATA)
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(lm93);
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 38a44c3d6ce..7e7267a0454 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -32,14 +32,13 @@
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
-static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
- 0x29, 0x2a, 0x2b,
- 0x4c, 0x4d, 0x4e,
- I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = {
+ 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
/*
* Insmod parameters
@@ -161,6 +160,14 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch
return sprintf(buf, "%d\n", data->alarms);
}
+static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ int bitnr = to_sensor_dev_attr(attr)->index;
+ struct max1619_data *data = max1619_update_device(dev);
+ return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
+}
+
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL);
static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_low2,
@@ -172,6 +179,10 @@ static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit2,
static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst2,
set_temp_hyst2);
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
static struct attribute *max1619_attributes[] = {
&dev_attr_temp1_input.attr,
@@ -182,6 +193,10 @@ static struct attribute *max1619_attributes[] = {
&dev_attr_temp2_crit_hyst.attr,
&dev_attr_alarms.attr,
+ &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp2_fault.dev_attr.attr,
+ &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
NULL
};
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c
index 755570c1f4e..52d528b76cc 100644
--- a/drivers/hwmon/max6650.c
+++ b/drivers/hwmon/max6650.c
@@ -44,7 +44,8 @@
* Addresses to scan. There are four disjoint possibilities, by pin config.
*/
-static unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, I2C_CLIENT_END};
+static const unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b,
+ I2C_CLIENT_END};
/*
* Insmod parameters
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 0d7f0c4d06b..d1b49854873 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -198,6 +198,14 @@ static ssize_t get_fan_div(struct device *dev, struct device_attribute
return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
}
+static ssize_t get_fan_alarm(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ int bitnr = to_sensor_dev_attr(devattr)->index;
+ struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
+ return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
+}
+
static ssize_t get_pwm(struct device *dev, struct device_attribute
*devattr, char *buf)
{
@@ -347,6 +355,8 @@ static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
get_fan_min, set_fan_min, offset - 1); \
static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
get_fan_div, set_fan_div, offset - 1); \
+static SENSOR_DEVICE_ATTR(fan##offset##_alarm, S_IRUGO, get_fan_alarm, \
+ NULL, offset - 1); \
static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
get_pwm, set_pwm, offset - 1); \
static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
@@ -374,12 +384,15 @@ static struct attribute *smsc47m1_attributes[] = {
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan1_min.dev_attr.attr,
&sensor_dev_attr_fan1_div.dev_attr.attr,
+ &sensor_dev_attr_fan1_alarm.dev_attr.attr,
&sensor_dev_attr_fan2_input.dev_attr.attr,
&sensor_dev_attr_fan2_min.dev_attr.attr,
&sensor_dev_attr_fan2_div.dev_attr.attr,
+ &sensor_dev_attr_fan2_alarm.dev_attr.attr,
&sensor_dev_attr_fan3_input.dev_attr.attr,
&sensor_dev_attr_fan3_min.dev_attr.attr,
&sensor_dev_attr_fan3_div.dev_attr.attr,
+ &sensor_dev_attr_fan3_alarm.dev_attr.attr,
&sensor_dev_attr_pwm1.dev_attr.attr,
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
@@ -533,7 +546,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev)
|| (err = device_create_file(dev,
&sensor_dev_attr_fan1_min.dev_attr))
|| (err = device_create_file(dev,
- &sensor_dev_attr_fan1_div.dev_attr)))
+ &sensor_dev_attr_fan1_div.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_fan1_alarm.dev_attr)))
goto error_remove_files;
} else
dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n");
@@ -544,7 +559,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev)
|| (err = device_create_file(dev,
&sensor_dev_attr_fan2_min.dev_attr))
|| (err = device_create_file(dev,
- &sensor_dev_attr_fan2_div.dev_attr)))
+ &sensor_dev_attr_fan2_div.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_fan2_alarm.dev_attr)))
goto error_remove_files;
} else
dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n");
@@ -555,7 +572,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev)
|| (err = device_create_file(dev,
&sensor_dev_attr_fan3_min.dev_attr))
|| (err = device_create_file(dev,
- &sensor_dev_attr_fan3_div.dev_attr)))
+ &sensor_dev_attr_fan3_div.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_fan3_alarm.dev_attr)))
goto error_remove_files;
} else if (data->type == smsc47m2)
dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n");
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c
index 8b0c188e60f..3c9db6598ba 100644
--- a/drivers/hwmon/smsc47m192.c
+++ b/drivers/hwmon/smsc47m192.c
@@ -34,7 +34,7 @@
#include <linux/mutex.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(smsc47m192);
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
index 04dd7699b3a..76a3859c3fb 100644
--- a/drivers/hwmon/thmc50.c
+++ b/drivers/hwmon/thmc50.c
@@ -32,7 +32,7 @@
MODULE_LICENSE("GPL");
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_2(thmc50, adm1022);
@@ -52,9 +52,9 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs "
*/
#define THMC50_REG_INTR 0x41
-const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
-const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
-const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
+static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
+static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
+static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
#define THMC50_REG_CONF_nFANOFF 0x20
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index 2635bba1e3f..f1ee5e73196 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -533,6 +533,24 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch
}
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ int bitnr = to_sensor_dev_attr(attr)->index;
+ struct via686a_data *data = via686a_update_device(dev);
+ return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
+}
+static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
+static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
+static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11);
+static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 15);
+static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
+
static ssize_t show_name(struct device *dev, struct device_attribute
*devattr, char *buf)
{
@@ -557,6 +575,11 @@ static struct attribute *via686a_attributes[] = {
&sensor_dev_attr_in2_max.dev_attr.attr,
&sensor_dev_attr_in3_max.dev_attr.attr,
&sensor_dev_attr_in4_max.dev_attr.attr,
+ &sensor_dev_attr_in0_alarm.dev_attr.attr,
+ &sensor_dev_attr_in1_alarm.dev_attr.attr,
+ &sensor_dev_attr_in2_alarm.dev_attr.attr,
+ &sensor_dev_attr_in3_alarm.dev_attr.attr,
+ &sensor_dev_attr_in4_alarm.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr,
@@ -567,6 +590,9 @@ static struct attribute *via686a_attributes[] = {
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp1_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp2_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp3_alarm.dev_attr.attr,
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan2_input.dev_attr.attr,
@@ -574,6 +600,8 @@ static struct attribute *via686a_attributes[] = {
&sensor_dev_attr_fan2_min.dev_attr.attr,
&sensor_dev_attr_fan1_div.dev_attr.attr,
&sensor_dev_attr_fan2_div.dev_attr.attr,
+ &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan2_alarm.dev_attr.attr,
&dev_attr_alarms.attr,
&dev_attr_name.attr,
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index f87661775fe..5bc57275cae 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -2,7 +2,7 @@
vt8231.c - Part of lm_sensors, Linux kernel modules
for hardware monitoring
- Copyright (c) 2005 Roger Lucas <roger@planbit.co.uk>
+ Copyright (c) 2005 Roger Lucas <vt8231@hiddenengine.co.uk>
Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
Aaron M. Marsh <amarsh@sdf.lonestar.org>
@@ -541,6 +541,28 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ int bitnr = to_sensor_dev_attr(attr)->index;
+ struct vt8231_data *data = vt8231_update_device(dev);
+ return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
+}
+static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
+static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11);
+static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL, 8);
+static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 11);
+static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
+static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
+
static ssize_t show_name(struct device *dev, struct device_attribute
*devattr, char *buf)
{
@@ -549,36 +571,42 @@ static ssize_t show_name(struct device *dev, struct device_attribute
}
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-static struct attribute *vt8231_attributes_temps[6][4] = {
+static struct attribute *vt8231_attributes_temps[6][5] = {
{
&dev_attr_temp1_input.attr,
&dev_attr_temp1_max_hyst.attr,
&dev_attr_temp1_max.attr,
+ &sensor_dev_attr_temp1_alarm.dev_attr.attr,
NULL
}, {
&sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp2_max.dev_attr.attr,
+ &sensor_dev_attr_temp2_alarm.dev_attr.attr,
NULL
}, {
&sensor_dev_attr_temp3_input.dev_attr.attr,
&sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp3_max.dev_attr.attr,
+ &sensor_dev_attr_temp3_alarm.dev_attr.attr,
NULL
}, {
&sensor_dev_attr_temp4_input.dev_attr.attr,
&sensor_dev_attr_temp4_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp4_max.dev_attr.attr,
+ &sensor_dev_attr_temp4_alarm.dev_attr.attr,
NULL
}, {
&sensor_dev_attr_temp5_input.dev_attr.attr,
&sensor_dev_attr_temp5_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp5_max.dev_attr.attr,
+ &sensor_dev_attr_temp5_alarm.dev_attr.attr,
NULL
}, {
&sensor_dev_attr_temp6_input.dev_attr.attr,
&sensor_dev_attr_temp6_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp6_max.dev_attr.attr,
+ &sensor_dev_attr_temp6_alarm.dev_attr.attr,
NULL
}
};
@@ -592,36 +620,42 @@ static const struct attribute_group vt8231_group_temps[6] = {
{ .attrs = vt8231_attributes_temps[5] },
};
-static struct attribute *vt8231_attributes_volts[6][4] = {
+static struct attribute *vt8231_attributes_volts[6][5] = {
{
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_min.dev_attr.attr,
&sensor_dev_attr_in0_max.dev_attr.attr,
+ &sensor_dev_attr_in0_alarm.dev_attr.attr,
NULL
}, {
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in1_min.dev_attr.attr,
&sensor_dev_attr_in1_max.dev_attr.attr,
+ &sensor_dev_attr_in1_alarm.dev_attr.attr,
NULL
}, {
&sensor_dev_attr_in2_input.dev_attr.attr,
&sensor_dev_attr_in2_min.dev_attr.attr,
&sensor_dev_attr_in2_max.dev_attr.attr,
+ &sensor_dev_attr_in2_alarm.dev_attr.attr,
NULL
}, {
&sensor_dev_attr_in3_input.dev_attr.attr,
&sensor_dev_attr_in3_min.dev_attr.attr,
&sensor_dev_attr_in3_max.dev_attr.attr,
+ &sensor_dev_attr_in3_alarm.dev_attr.attr,
NULL
}, {
&sensor_dev_attr_in4_input.dev_attr.attr,
&sensor_dev_attr_in4_min.dev_attr.attr,
&sensor_dev_attr_in4_max.dev_attr.attr,
+ &sensor_dev_attr_in4_alarm.dev_attr.attr,
NULL
}, {
&dev_attr_in5_input.attr,
&dev_attr_in5_min.attr,
&dev_attr_in5_max.attr,
+ &sensor_dev_attr_in5_alarm.dev_attr.attr,
NULL
}
};
@@ -642,6 +676,8 @@ static struct attribute *vt8231_attributes[] = {
&sensor_dev_attr_fan2_min.dev_attr.attr,
&sensor_dev_attr_fan1_div.dev_attr.attr,
&sensor_dev_attr_fan2_div.dev_attr.attr,
+ &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan2_alarm.dev_attr.attr,
&dev_attr_alarms.attr,
&dev_attr_name.attr,
NULL
@@ -963,7 +999,7 @@ static void __exit sm_vt8231_exit(void)
}
}
-MODULE_AUTHOR("Roger Lucas <roger@planbit.co.uk>");
+MODULE_AUTHOR("Roger Lucas <vt8231@hiddenengine.co.uk>");
MODULE_DESCRIPTION("VT8231 sensors");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 7421f6ea53e..5c85670e2d1 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -53,8 +53,8 @@
static struct platform_device *pdev;
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
- 0x2e, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
+ 0x2e, 0x2f, I2C_CLIENT_END };
static unsigned short isa_address = 0x290;
/* Insmod parameters */
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index 85bd21ee329..85077c4c803 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -47,7 +47,8 @@
#define NUMBER_OF_TEMPIN 3
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
+ I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(w83791d);
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 007449d3e16..299629d47ed 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -46,7 +46,8 @@
#include <linux/sysfs.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
+ I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(w83792d);
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 3ba1d6b3347..ee35af93b57 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -37,7 +37,8 @@
#include <linux/mutex.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
+ I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(w83793);
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c
index 1d6259d29e7..77f2d482888 100644
--- a/drivers/hwmon/w83l785ts.c
+++ b/drivers/hwmon/w83l785ts.c
@@ -49,7 +49,7 @@
* Address is fully defined internally and cannot be changed.
*/
-static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END };
/*
* Insmod parameters
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index 1dbee4fa23a..41e22ddb568 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -35,7 +35,7 @@
#include <linux/mutex.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(w83l786ng);
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index b61f56b6f31..476b0bb72d6 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -177,6 +177,8 @@ config I2C_I801
ESB2
ICH8
ICH9
+ Tolapai
+ ICH10
This driver can also be built as a module. If so, the module
will be called i2c-i801.
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index aa9157913b9..b0f771fe432 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -40,7 +40,9 @@
82801G (ICH7) 0x27da 32 hard yes yes yes
82801H (ICH8) 0x283e 32 hard yes yes yes
82801I (ICH9) 0x2930 32 hard yes yes yes
- Tolapai 0x5032 32 hard yes ? ?
+ Tolapai 0x5032 32 hard yes yes yes
+ ICH10 0x3a30 32 hard yes yes yes
+ ICH10 0x3a60 32 hard yes yes yes
Features supported by this driver:
Software PEC no
@@ -588,6 +590,8 @@ static struct pci_device_id i801_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
{ 0, }
};
@@ -608,10 +612,12 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
case PCI_DEVICE_ID_INTEL_ESB2_17:
case PCI_DEVICE_ID_INTEL_ICH8_5:
case PCI_DEVICE_ID_INTEL_ICH9_6:
+ case PCI_DEVICE_ID_INTEL_TOLAPAI_1:
+ case PCI_DEVICE_ID_INTEL_ICH10_4:
+ case PCI_DEVICE_ID_INTEL_ICH10_5:
i801_features |= FEATURE_I2C_BLOCK_READ;
/* fall through */
case PCI_DEVICE_ID_INTEL_82801DB_3:
- case PCI_DEVICE_ID_INTEL_TOLAPAI_1:
i801_features |= FEATURE_SMBUS_PEC;
i801_features |= FEATURE_BLOCK_BUFFER;
break;
diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c
index 5161aaf9341..496ee875eb4 100644
--- a/drivers/i2c/busses/i2c-pca-isa.c
+++ b/drivers/i2c/busses/i2c-pca-isa.c
@@ -125,6 +125,13 @@ static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq);
+#ifdef CONFIG_PPC_MERGE
+ if (check_legacy_ioport(base)) {
+ dev_err(dev, "I/O address %#08lx is not available\n", base);
+ goto out;
+ }
+#endif
+
if (!request_region(base, IO_SIZE, "i2c-pca-isa")) {
dev_err(dev, "I/O address %#08lx is in use\n", base);
goto out;
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c
index be99c02ecac..b03af5653c6 100644
--- a/drivers/i2c/busses/i2c-pmcmsp.c
+++ b/drivers/i2c/busses/i2c-pmcmsp.c
@@ -122,7 +122,7 @@ struct pmcmsptwi_data {
};
/* The default settings */
-const static struct pmcmsptwi_clockcfg pmcmsptwi_defclockcfg = {
+static const struct pmcmsptwi_clockcfg pmcmsptwi_defclockcfg = {
.standard = {
.filter = 0x3,
.clock = 0x1f,
@@ -133,7 +133,7 @@ const static struct pmcmsptwi_clockcfg pmcmsptwi_defclockcfg = {
},
};
-const static struct pmcmsptwi_cfg pmcmsptwi_defcfg = {
+static const struct pmcmsptwi_cfg pmcmsptwi_defcfg = {
.arbf = 0x03,
.nak = 0x03,
.add10 = 0x00,
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 2598d29fd7a..2d2087ad708 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -138,11 +138,13 @@ static const struct bits icr_bits[] = {
PXA_BIT(ICR_UR, "UR", "ur"),
};
+#ifdef CONFIG_I2C_PXA_SLAVE
static void decode_ICR(unsigned int val)
{
decode_bits(KERN_DEBUG "ICR", icr_bits, ARRAY_SIZE(icr_bits), val);
printk("\n");
}
+#endif
static unsigned int i2c_debug = DEBUG;
@@ -997,7 +999,14 @@ static int i2c_pxa_probe(struct platform_device *dev)
spin_lock_init(&i2c->lock);
init_waitqueue_head(&i2c->wait);
- sprintf(i2c->adap.name, "pxa_i2c-i2c.%u", dev->id);
+ /*
+ * If "dev->id" is negative we consider it as zero.
+ * The reason to do so is to avoid sysfs names that only make
+ * sense when there are multiple adapters.
+ */
+ i2c->adap.nr = dev->id != -1 ? dev->id : 0;
+ snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u",
+ i2c->adap.nr);
i2c->clk = clk_get(&dev->dev, "I2CCLK");
if (IS_ERR(i2c->clk)) {
@@ -1048,13 +1057,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
i2c->adap.algo_data = i2c;
i2c->adap.dev.parent = &dev->dev;
- /*
- * If "dev->id" is negative we consider it as zero.
- * The reason to do so is to avoid sysfs names that only make
- * sense when there are multiple adapters.
- */
- i2c->adap.nr = dev->id != -1 ? dev->id : 0;
-
ret = i2c_add_numbered_adapter(&i2c->adap);
if (ret < 0) {
printk(KERN_INFO "I2C: Failed to add bus\n");
@@ -1078,6 +1080,7 @@ eadapt:
ereqirq:
clk_disable(i2c->clk);
i2c_pxa_disable(dev);
+ iounmap(i2c->reg_base);
eremap:
clk_put(i2c->clk);
eclk:
@@ -1087,7 +1090,7 @@ emalloc:
return ret;
}
-static int i2c_pxa_remove(struct platform_device *dev)
+static int __exit i2c_pxa_remove(struct platform_device *dev)
{
struct pxa_i2c *i2c = platform_get_drvdata(dev);
@@ -1101,6 +1104,7 @@ static int i2c_pxa_remove(struct platform_device *dev)
clk_put(i2c->clk);
i2c_pxa_disable(dev);
+ iounmap(i2c->reg_base);
release_mem_region(i2c->iobase, i2c->iosize);
kfree(i2c);
@@ -1109,9 +1113,10 @@ static int i2c_pxa_remove(struct platform_device *dev)
static struct platform_driver i2c_pxa_driver = {
.probe = i2c_pxa_probe,
- .remove = i2c_pxa_remove,
+ .remove = __exit_p(i2c_pxa_remove),
.driver = {
.name = "pxa2xx-i2c",
+ .owner = THIS_MODULE,
},
};
@@ -1120,9 +1125,9 @@ static int __init i2c_adap_pxa_init(void)
return platform_driver_register(&i2c_pxa_driver);
}
-static void i2c_adap_pxa_exit(void)
+static void __exit i2c_adap_pxa_exit(void)
{
- return platform_driver_unregister(&i2c_pxa_driver);
+ platform_driver_unregister(&i2c_pxa_driver);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index df752e690e4..eed6d8e1b5c 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -50,7 +50,7 @@ menuconfig IDE
To compile this driver as a module, choose M here: the
module will be called ide.
- For further information, please read <file:Documentation/ide.txt>.
+ For further information, please read <file:Documentation/ide/ide.txt>.
If unsure, say Y.
@@ -77,7 +77,7 @@ config BLK_DEV_IDE
Useful information about large (>540 MB) IDE disks, multiple
interfaces, what to do if ATA/IDE devices are not automatically
detected, sound card ATA/IDE ports, module support, and other
- topics, is contained in <file:Documentation/ide.txt>. For detailed
+ topics, is contained in <file:Documentation/ide/ide.txt>. For detailed
information about hard drives, consult the Disk-HOWTO and the
Multi-Disk-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
@@ -87,7 +87,7 @@ config BLK_DEV_IDE
<ftp://ibiblio.org/pub/Linux/system/hardware/>.
To compile this driver as a module, choose M here and read
- <file:Documentation/ide.txt>. The module will be called ide-mod.
+ <file:Documentation/ide/ide.txt>. The module will be called ide-mod.
Do not compile this driver as a module if your root file system (the
one containing the directory /) is located on an IDE device.
@@ -98,7 +98,7 @@ config BLK_DEV_IDE
if BLK_DEV_IDE
-comment "Please see Documentation/ide.txt for help/info on IDE drives"
+comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"
config BLK_DEV_IDE_SATA
bool "Support for SATA (deprecated; conflicts with libata SATA driver)"
@@ -235,8 +235,8 @@ config BLK_DEV_IDETAPE
along with other IDE devices, as "hdb" or "hdc", or something
similar, and will be mapped to a character device such as "ht0"
(check the boot messages with dmesg). Be sure to consult the
- <file:drivers/ide/ide-tape.c> and <file:Documentation/ide.txt> files
- for usage information.
+ <file:drivers/ide/ide-tape.c> and <file:Documentation/ide/ide.txt>
+ files for usage information.
To compile this driver as a module, choose M here: the
module will be called ide-tape.
@@ -358,7 +358,7 @@ config BLK_DEV_CMD640
The CMD640 chip is also used on add-in cards by Acculogic, and on
the "CSA-6400E PCI to IDE controller" that some people have. For
- details, read <file:Documentation/ide.txt>.
+ details, read <file:Documentation/ide/ide.txt>.
config BLK_DEV_CMD640_ENHANCED
bool "CMD640 enhanced support"
@@ -366,7 +366,7 @@ config BLK_DEV_CMD640_ENHANCED
help
This option includes support for setting/autotuning PIO modes and
prefetch on CMD640 IDE interfaces. For details, read
- <file:Documentation/ide.txt>. If you have a CMD640 IDE interface
+ <file:Documentation/ide/ide.txt>. If you have a CMD640 IDE interface
and your BIOS does not already do this for you, then say Y here.
Otherwise say N.
@@ -1069,9 +1069,9 @@ config BLK_DEV_ALI14XX
This driver is enabled at runtime using the "ali14xx.probe" kernel
boot parameter. It enables support for the secondary IDE interface
of the ALI M1439/1443/1445/1487/1489 chipsets, and permits faster
- I/O speeds to be set as well. See the files
- <file:Documentation/ide.txt> and <file:drivers/ide/legacy/ali14xx.c>
- for more info.
+ I/O speeds to be set as well.
+ See the files <file:Documentation/ide/ide.txt> and
+ <file:drivers/ide/legacy/ali14xx.c> for more info.
config BLK_DEV_DTC2278
tristate "DTC-2278 support"
@@ -1079,7 +1079,7 @@ config BLK_DEV_DTC2278
This driver is enabled at runtime using the "dtc2278.probe" kernel
boot parameter. It enables support for the secondary IDE interface
of the DTC-2278 card, and permits faster I/O speeds to be set as
- well. See the <file:Documentation/ide.txt> and
+ well. See the <file:Documentation/ide/ide.txt> and
<file:drivers/ide/legacy/dtc2278.c> files for more info.
config BLK_DEV_HT6560B
@@ -1088,7 +1088,7 @@ config BLK_DEV_HT6560B
This driver is enabled at runtime using the "ht6560b.probe" kernel
boot parameter. It enables support for the secondary IDE interface
of the Holtek card, and permits faster I/O speeds to be set as well.
- See the <file:Documentation/ide.txt> and
+ See the <file:Documentation/ide/ide.txt> and
<file:drivers/ide/legacy/ht6560b.c> files for more info.
config BLK_DEV_QD65XX
@@ -1096,7 +1096,7 @@ config BLK_DEV_QD65XX
help
This driver is enabled at runtime using the "qd65xx.probe" kernel
boot parameter. It permits faster I/O speeds to be set. See the
- <file:Documentation/ide.txt> and <file:drivers/ide/legacy/qd65xx.c>
+ <file:Documentation/ide/ide.txt> and <file:drivers/ide/legacy/qd65xx.c>
for more info.
config BLK_DEV_UMC8672
@@ -1105,7 +1105,7 @@ config BLK_DEV_UMC8672
This driver is enabled at runtime using the "umc8672.probe" kernel
boot parameter. It enables support for the secondary IDE interface
of the UMC-8672, and permits faster I/O speeds to be set as well.
- See the files <file:Documentation/ide.txt> and
+ See the files <file:Documentation/ide/ide.txt> and
<file:drivers/ide/legacy/umc8672.c> for more info.
endif
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 354c91d06a6..c8d0e871599 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -670,8 +670,8 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
* and attempt to recover if there are problems. Returns 0 if everything's
* ok; nonzero if the request has been terminated.
*/
-static
-int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw)
+static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
+ int len, int ireason, int rw)
{
/*
* ireason == 0: the drive wants to receive data from us
@@ -701,6 +701,9 @@ int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw)
drive->name, __FUNCTION__, ireason);
}
+ if (rq->cmd_type == REQ_TYPE_ATA_PC)
+ rq->cmd_flags |= REQ_FAILED;
+
cdrom_end_request(drive, 0);
return -1;
}
@@ -1071,11 +1074,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
/*
* check which way to transfer data
*/
- if (blk_fs_request(rq) || blk_pc_request(rq)) {
- if (ide_cd_check_ireason(drive, len, ireason, write))
- return ide_stopped;
+ if (ide_cd_check_ireason(drive, rq, len, ireason, write))
+ return ide_stopped;
- if (blk_fs_request(rq) && write == 0) {
+ if (blk_fs_request(rq)) {
+ if (write == 0) {
int nskip;
if (ide_cd_check_transfer_size(drive, len)) {
@@ -1101,16 +1104,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (ireason == 0) {
write = 1;
xferfunc = HWIF(drive)->atapi_output_bytes;
- } else if (ireason == 2 || (ireason == 1 &&
- (blk_fs_request(rq) || blk_pc_request(rq)))) {
+ } else {
write = 0;
xferfunc = HWIF(drive)->atapi_input_bytes;
- } else {
- printk(KERN_ERR "%s: %s: The drive "
- "appears confused (ireason = 0x%02x). "
- "Trying to recover by ending request.\n",
- drive->name, __FUNCTION__, ireason);
- goto end_request;
}
/*
@@ -1182,11 +1178,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
else
rq->data += blen;
}
+ if (!write && blk_sense_request(rq))
+ rq->sense_len += blen;
}
- if (write && blk_sense_request(rq))
- rq->sense_len += thislen;
-
/*
* pad, if necessary
*/
@@ -1207,9 +1202,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
end_request:
if (blk_pc_request(rq)) {
unsigned long flags;
+ unsigned int dlen = rq->data_len;
+
+ if (dma)
+ rq->data_len = 0;
spin_lock_irqsave(&ide_lock, flags);
- if (__blk_end_request(rq, 0, rq->data_len))
+ if (__blk_end_request(rq, 0, dlen))
BUG();
HWGROUP(drive)->rq = NULL;
spin_unlock_irqrestore(&ide_lock, flags);
@@ -1927,6 +1926,7 @@ static const struct cd_list_entry ide_cd_quirks_list[] = {
{ "MATSHITADVD-ROM SR-8186", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
{ "MATSHITADVD-ROM SR-8176", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
{ "MATSHITADVD-ROM SR-8174", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
+ { "Optiarc DVD RW AD-5200A", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
{ NULL, NULL, 0 }
};
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c
index b68284de4e8..6d147ce6782 100644
--- a/drivers/ide/ide-cd_ioctl.c
+++ b/drivers/ide/ide-cd_ioctl.c
@@ -457,6 +457,10 @@ int ide_cdrom_packet(struct cdrom_device_info *cdi,
layer. the packet must be complete, as we do not
touch it at all. */
ide_cd_init_rq(drive, &req);
+
+ if (cgc->data_direction == CGC_DATA_WRITE)
+ req.cmd_flags |= REQ_RW;
+
memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE);
if (cgc->sense)
memset(cgc->sense, 0, sizeof(struct request_sense));
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index aed8b31ca56..39501d13025 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -397,6 +397,7 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id)
static const struct drive_list_entry hpa_list[] = {
{ "ST340823A", NULL },
{ "ST320413A", NULL },
+ { "ST310211A", NULL },
{ NULL, NULL }
};
@@ -866,7 +867,7 @@ static void idedisk_setup (ide_drive_t *drive)
/* Only print cache size when it was specified */
if (id->buf_size)
- printk (" w/%dKiB Cache", id->buf_size/2);
+ printk(KERN_CONT " w/%dKiB Cache", id->buf_size / 2);
printk(KERN_CONT ", CHS=%d/%d/%d\n",
drive->bios_cyl, drive->bios_head, drive->bios_sect);
@@ -948,7 +949,8 @@ static void ide_device_shutdown(ide_drive_t *drive)
return;
}
- printk("Shutdown: %s\n", drive->name);
+ printk(KERN_INFO "Shutdown: %s\n", drive->name);
+
drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
}
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index d0e7b537353..d61e5788d31 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -1,9 +1,13 @@
/*
+ * IDE DMA support (including IDE PCI BM-DMA).
+ *
* Copyright (C) 1995-1998 Mark Lord
* Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2004, 2007 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
+ *
+ * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies).
*/
/*
@@ -11,49 +15,6 @@
*/
/*
- * This module provides support for the bus-master IDE DMA functions
- * of various PCI chipsets, including the Intel PIIX (i82371FB for
- * the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and
- * 440 chipsets), and the PIIX4 (i82371AB for the 430 TX chipset)
- * ("PIIX" stands for "PCI ISA IDE Xcellerator").
- *
- * Pretty much the same code works for other IDE PCI bus-mastering chipsets.
- *
- * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies).
- *
- * By default, DMA support is prepared for use, but is currently enabled only
- * for drives which already have DMA enabled (UltraDMA or mode 2 multi/single),
- * or which are recognized as "good" (see table below). Drives with only mode0
- * or mode1 (multi/single) DMA should also work with this chipset/driver
- * (eg. MC2112A) but are not enabled by default.
- *
- * Use "hdparm -i" to view modes supported by a given drive.
- *
- * The hdparm-3.5 (or later) utility can be used for manually enabling/disabling
- * DMA support, but must be (re-)compiled against this kernel version or later.
- *
- * To enable DMA, use "hdparm -d1 /dev/hd?" on a per-drive basis after booting.
- * If problems arise, ide.c will disable DMA operation after a few retries.
- * This error recovery mechanism works and has been extremely well exercised.
- *
- * IDE drives, depending on their vintage, may support several different modes
- * of DMA operation. The boot-time modes are indicated with a "*" in
- * the "hdparm -i" listing, and can be changed with *knowledgeable* use of
- * the "hdparm -X" feature. There is seldom a need to do this, as drives
- * normally power-up with their "best" PIO/DMA modes enabled.
- *
- * Testing has been done with a rather extensive number of drives,
- * with Quantum & Western Digital models generally outperforming the pack,
- * and Fujitsu & Conner (and some Seagate which are really Conner) drives
- * showing more lackluster throughput.
- *
- * Keep an eye on /var/adm/messages for "DMA disabled" messages.
- *
- * Some people have reported trouble with Intel Zappa motherboards.
- * This can be fixed by upgrading the AMI BIOS to version 1.00.04.BS0,
- * available from ftp://ftp.intel.com/pub/bios/10004bs0.exe
- * (thanks to Glen Morrell <glen@spin.Stanford.edu> for researching this).
- *
* Thanks to "Christopher J. Reimer" <reimer@doe.carleton.ca> for
* fixing the problem with the BIOS on some Acer motherboards.
*
@@ -65,11 +26,6 @@
*
* Most importantly, thanks to Robert Bringman <rob@mars.trion.com>
* for supplying a Promise UDMA board & WD UDMA drive for this work!
- *
- * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports.
- *
- * ATA-66/100 and recovery functions, I forgot the rest......
- *
*/
#include <linux/module.h>
@@ -757,7 +713,7 @@ static int ide_tune_dma(ide_drive_t *drive)
}
if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
- return 0;
+ return 1;
if (ide_set_dma_mode(drive, speed))
return 0;
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 709b9e4d287..9ebec08eefd 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -17,9 +17,6 @@ static int __init ide_generic_init(void)
u8 idx[MAX_HWIFS];
int i;
- if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
- ide_get_lock(NULL, NULL); /* for atari only */
-
for (i = 0; i < MAX_HWIFS; i++) {
ide_hwif_t *hwif = &ide_hwifs[i];
@@ -31,9 +28,6 @@ static int __init ide_generic_init(void)
ide_device_add_all(idx, NULL);
- if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
- ide_release_lock(); /* for atari only */
-
return 0;
}
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 4a2cb286822..194ecb0049e 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -756,7 +756,8 @@ static int ide_probe_port(ide_hwif_t *hwif)
BUG_ON(hwif->present);
- if (hwif->noprobe)
+ if (hwif->noprobe ||
+ (hwif->drives[0].noprobe && hwif->drives[1].noprobe))
return -EACCES;
/*
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 0598ecfd5f3..43e0e055777 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -3765,6 +3765,11 @@ static int ide_tape_probe(ide_drive_t *drive)
g->fops = &idetape_block_ops;
ide_register_region(g);
+ printk(KERN_WARNING "It is possible that this driver does not have any"
+ " users anymore and, as a result, it will be REMOVED soon."
+ " Please notify Bart <bzolnier@gmail.com> or Boris"
+ " <petkovbb@gmail.com> in case you still need it.\n");
+
return 0;
out_free_tape:
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 4a8952a6c3d..9976f9d627d 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -590,11 +590,6 @@ void ide_unregister(unsigned int index, int init_default, int restore)
hwif->extra_ports = 0;
}
- /*
- * Note that we only release the standard ports,
- * and do not even try to handle any extra ports
- * allocated for weird IDE interface chipsets.
- */
ide_hwif_release_regions(hwif);
/* copy original settings */
@@ -672,7 +667,6 @@ int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *),
do {
hwif = ide_deprecated_find_port(hw->io_ports[IDE_DATA_OFFSET]);
- index = hwif->index;
if (hwif)
goto found;
for (index = 0; index < MAX_HWIFS; index++)
@@ -680,6 +674,7 @@ int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *),
} while (retry--);
return -1;
found:
+ index = hwif->index;
if (hwif->present)
ide_unregister(index, 0, 1);
else if (!hwif->hold)
@@ -1036,10 +1031,9 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
drive->nice1 = (arg >> IDE_NICE_1) & 1;
return 0;
case HDIO_DRIVE_RESET:
- {
- unsigned long flags;
- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
/*
* Abort the current command on the
* group if there is one, taking
@@ -1058,17 +1052,15 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
ide_abort(drive, "drive reset");
BUG_ON(HWGROUP(drive)->handler);
-
+
/* Ensure nothing gets queued after we
drop the lock. Reset will clear the busy */
-
+
HWGROUP(drive)->busy = 1;
spin_unlock_irqrestore(&ide_lock, flags);
(void) ide_do_reset(drive);
return 0;
- }
-
case HDIO_GET_BUSSTATE:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -1188,7 +1180,7 @@ static int __initdata is_chipset_set[MAX_HWIFS];
* ide_setup() gets called VERY EARLY during initialization,
* to handle kernel "command line" strings beginning with "hdx=" or "ide".
*
- * Remember to update Documentation/ide.txt if you change something here.
+ * Remember to update Documentation/ide/ide.txt if you change something here.
*/
static int __init ide_setup(char *s)
{
@@ -1229,7 +1221,7 @@ static int __init ide_setup(char *s)
if (!strcmp(s, "ide=reverse")) {
ide_scan_direction = 1;
printk(" : Enabled support for IDE inverse scan order.\n");
- return 1;
+ goto obsolete_option;
}
#endif
@@ -1449,7 +1441,7 @@ static int __init ide_setup(char *s)
case -1: /* "noprobe" */
hwif->noprobe = 1;
- goto done;
+ goto obsolete_option;
case 1: /* base */
vals[1] = vals[0] + 0x206; /* default ctl */
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
index f044048903b..8949ce71bdd 100644
--- a/drivers/ide/legacy/falconide.c
+++ b/drivers/ide/legacy/falconide.c
@@ -54,7 +54,7 @@ static void __init falconide_setup_ports(hw_regs_t *hw)
for (i = 1; i < 8; i++)
hw->io_ports[i] = ATA_HD_BASE + 1 + i * 4;
- hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_CONTROL;
+ hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_BASE + ATA_HD_CONTROL;
hw->irq = IRQ_MFP_IDE;
hw->ack_intr = NULL;
@@ -84,7 +84,9 @@ static int __init falconide_init(void)
ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
+ ide_get_lock(NULL, NULL);
ide_device_add(idx, NULL);
+ ide_release_lock();
}
return 0;
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index 02d12c74764..78ca68e60f9 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -21,18 +21,21 @@
* "Prefetch" mode bit OFF for ide disks and
* ON for anything else.
*
+ * Version 0.08 Need to force prefetch for CDs and other non-disk
+ * devices. (not sure which devices exactly need
+ * prefetch)
*
* HT-6560B EIDE-controller support
* To activate controller support use kernel parameter "ide0=ht6560b".
* Use hdparm utility to enable PIO mode support.
*
* Author: Mikko Ala-Fossi <maf@iki.fi>
- * Jan Evert van Grootheest <janevert@iae.nl>
+ * Jan Evert van Grootheest <janevert@caiway.nl>
*
* Try: http://www.maf.iki.fi/~maf/ht6560b/
*/
-#define HT6560B_VERSION "v0.07"
+#define HT6560B_VERSION "v0.08"
#include <linux/module.h>
#include <linux/types.h>
@@ -130,15 +133,20 @@ static void ht6560b_selectproc (ide_drive_t *drive)
u8 select, timing;
local_irq_save(flags);
-
+
select = HT_CONFIG(drive);
timing = HT_TIMING(drive);
-
+
+ /*
+ * Need to enforce prefetch sometimes because otherwise
+ * it'll hang (hard).
+ */
+ if (drive->media != ide_disk || !drive->present)
+ select |= HT_PREFETCH_MODE;
+
if (select != current_select || timing != current_timing) {
current_select = select;
current_timing = timing;
- if (drive->media != ide_disk || !drive->present)
- select |= HT_PREFETCH_MODE;
(void)inb(HT_CONFIG_PORT);
(void)inb(HT_CONFIG_PORT);
(void)inb(HT_CONFIG_PORT);
@@ -188,11 +196,12 @@ static int __init try_to_init_ht6560b(void)
outb(HT_TIMING_DEFAULT, 0x1f6); /* IDE_SELECT_REG */
(void) inb(0x1f7); /* IDE_STATUS_REG */
- printk("\nht6560b " HT6560B_VERSION
+ printk("ht6560b " HT6560B_VERSION
": chipset detected and initialized"
#ifdef DEBUG
" with debug enabled"
#endif
+ "\n"
);
return 1;
}
@@ -323,7 +332,7 @@ static const struct ide_port_info ht6560b_port_info __initdata = {
IDE_HFLAG_NO_DMA |
IDE_HFLAG_NO_AUTOTUNE |
IDE_HFLAG_ABUSE_PREFETCH,
- .pio_mask = ATA_PIO5,
+ .pio_mask = ATA_PIO4,
};
static int __init ht6560b_init(void)
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index a61e60737dc..9a79098d9eb 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -74,7 +74,7 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base,
for (i = 0; i < 8; i++)
hw->io_ports[i] = base + i * 4;
- hw->io_ports[IDE_CONTROL_OFFSET] = IDE_CONTROL;
+ hw->io_ports[IDE_CONTROL_OFFSET] = base + IDE_CONTROL;
hw->irq = irq;
hw->ack_intr = ack_intr;
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
index bba29df5f21..2f4f47ad602 100644
--- a/drivers/ide/legacy/qd65xx.c
+++ b/drivers/ide/legacy/qd65xx.c
@@ -334,43 +334,6 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
hwif->drives[1].drive_data = t2;
}
-/*
- * qd_unsetup:
- *
- * called to unsetup an ata channel : back to default values, unlinks tuning
- */
-/*
-static void __exit qd_unsetup(ide_hwif_t *hwif)
-{
- u8 config = hwif->config_data;
- int base = hwif->select_data;
- void *set_pio_mode = (void *)hwif->set_pio_mode;
-
- if (hwif->chipset != ide_qd65xx)
- return;
-
- printk(KERN_NOTICE "%s: back to defaults\n", hwif->name);
-
- hwif->selectproc = NULL;
- hwif->set_pio_mode = NULL;
-
- if (set_pio_mode == (void *)qd6500_set_pio_mode) {
- // will do it for both
- outb(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
- } else if (set_pio_mode == (void *)qd6580_set_pio_mode) {
- if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) {
- outb(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
- outb(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
- } else {
- outb(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
- }
- } else {
- printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n");
- printk(KERN_WARNING "keeping settings !\n");
- }
-}
-*/
-
static const struct ide_port_info qd65xx_port_info __initdata = {
.chipset = ide_qd65xx,
.host_flags = IDE_HFLAG_IO_32BIT |
@@ -444,6 +407,8 @@ static int __init qd_probe(int base)
printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n",
config, control, QD_ID3);
+ outb(QD_DEF_CONTR, QD_CONTROL_PORT);
+
if (control & QD_CONTR_SEC_DISABLED) {
/* secondary disabled */
@@ -460,8 +425,6 @@ static int __init qd_probe(int base)
ide_device_add(idx, &qd65xx_port_info);
- outb(QD_DEF_CONTR, QD_CONTROL_PORT);
-
return 1;
} else {
ide_hwif_t *mate;
@@ -487,8 +450,6 @@ static int __init qd_probe(int base)
ide_device_add(idx, &qd65xx_port_info);
- outb(QD_DEF_CONTR, QD_CONTROL_PORT);
-
return 0; /* no other qd65xx possible */
}
}
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index bd24dad3cfc..ec667982809 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -787,7 +787,8 @@ static int __init cmd640x_init(void)
/*
* Try to enable the secondary interface, if not already enabled
*/
- if (cmd_hwif1->noprobe) {
+ if (cmd_hwif1->noprobe ||
+ (cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe)) {
port2 = "not probed";
} else {
b = get_cmd640_reg(CNTRL);
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index d0f7bb8b8ad..6357bb6269a 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1570,10 +1570,12 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
if (rev < 3)
info = &hpt36x;
else {
- static const struct hpt_info *hpt37x_info[] =
- { &hpt370, &hpt370a, &hpt372, &hpt372n };
-
- info = hpt37x_info[min_t(u8, rev, 6) - 3];
+ switch (min_t(u8, rev, 6)) {
+ case 3: info = &hpt370; break;
+ case 4: info = &hpt370a; break;
+ case 5: info = &hpt372; break;
+ case 6: info = &hpt372n; break;
+ }
idx++;
}
break;
@@ -1626,7 +1628,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
return ide_setup_pci_device(dev, &d);
}
-static const struct pci_device_id hpt366_pci_tbl[] = {
+static const struct pci_device_id hpt366_pci_tbl[] __devinitconst = {
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), 0 },
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), 1 },
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), 2 },
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index f3f79f80581..9004e752188 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -479,6 +479,7 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
static const struct pci_device_id via_pci_tbl[] = {
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), 0 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), 0 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), 1 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 },
{ 0, },
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 12ac3bfb4f9..78c9eeb8563 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1254,7 +1254,7 @@ pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t mesg)
int rc = 0;
if (mesg.event != mdev->ofdev.dev.power.power_state.event
- && mesg.event == PM_EVENT_SUSPEND) {
+ && (mesg.event & PM_EVENT_SLEEP)) {
rc = pmac_ide_do_suspend(hwif);
if (rc == 0)
mdev->ofdev.dev.power.power_state = mesg;
@@ -1364,7 +1364,7 @@ pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
int rc = 0;
if (mesg.event != pdev->dev.power.power_state.event
- && mesg.event == PM_EVENT_SUSPEND) {
+ && (mesg.event & PM_EVENT_SLEEP)) {
rc = pmac_ide_do_suspend(hwif);
if (rc == 0)
pdev->dev.power.power_state = mesg;
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 28e155a9e2a..9e2b1964d71 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -183,6 +183,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
* Avoids access beyond actual disk limits on devices with an off-by-one bug.
* Don't use this with devices which don't have this bug.
*
+ * - delay inquiry
+ * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
+ *
* - override internal blacklist
* Instead of adding to the built-in blacklist, use only the workarounds
* specified in the module load parameter.
@@ -195,6 +198,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36)
", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
+ ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
", or a combination)");
@@ -357,6 +361,11 @@ static const struct {
.workarounds = SBP2_WORKAROUND_INQUIRY_36 |
SBP2_WORKAROUND_MODE_SENSE_8,
},
+ /* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
+ .firmware_revision = 0x002800,
+ .model_id = 0x000000,
+ .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY,
+ },
/* Initio bridges, actually only needed for some older ones */ {
.firmware_revision = 0x000200,
.model_id = SBP2_ROM_VALUE_WILDCARD,
@@ -914,6 +923,9 @@ static int sbp2_start_device(struct sbp2_lu *lu)
sbp2_agent_reset(lu, 1);
sbp2_max_speed_and_size(lu);
+ if (lu->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY)
+ ssleep(SBP2_INQUIRY_DELAY);
+
error = scsi_add_device(lu->shost, 0, lu->ud->id, 0);
if (error) {
SBP2_ERR("scsi_add_device failed");
@@ -1962,6 +1974,9 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
{
struct sbp2_lu *lu = (struct sbp2_lu *)sdev->host->hostdata[0];
+ if (sdev->lun != 0 || sdev->id != lu->ud->id || sdev->channel != 0)
+ return -ENODEV;
+
lu->sdev = sdev;
sdev->allow_restart = 1;
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index d2ecb0d8a1b..80d8e097b06 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -343,6 +343,8 @@ enum sbp2lu_state_types {
#define SBP2_WORKAROUND_INQUIRY_36 0x2
#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
+#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10
+#define SBP2_INQUIRY_DELAY 12
#define SBP2_WORKAROUND_OVERRIDE 0x100
#endif /* SBP2_H */
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index c864ef70fdf..5a4b2e65534 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -686,8 +686,10 @@ int ib_device_register_sysfs(struct ib_device *device)
device->ports_parent = kobject_create_and_add("ports",
kobject_get(&class_dev->kobj));
- if (!device->ports_parent)
+ if (!device->ports_parent) {
+ ret = -ENOMEM;
goto err_put;
+ }
if (device->node_type == RDMA_NODE_IB_SWITCH) {
ret = add_port(device, 0);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c
index 73bfd1656f8..b8797c66676 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_mem.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c
@@ -136,14 +136,8 @@ int build_phys_page_list(struct ib_phys_buf *buffer_list,
/* Find largest page shift we can use to cover buffers */
for (*shift = PAGE_SHIFT; *shift < 27; ++(*shift))
- if (num_phys_buf > 1) {
- if ((1ULL << *shift) & mask)
- break;
- } else
- if (1ULL << *shift >=
- buffer_list[0].size +
- (buffer_list[0].addr & ((1ULL << *shift) - 1)))
- break;
+ if ((1ULL << *shift) & mask)
+ break;
buffer_list[0].size += buffer_list[0].addr & ((1ULL << *shift) - 1);
buffer_list[0].addr &= ~0ull << *shift;
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index 3b6985557cb..3538da16e3f 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -686,7 +686,7 @@ err_out_table:
mthca_table_put(dev, dev->mr_table.mpt_table, key);
err_out_mpt_free:
- mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
+ mthca_free(&dev->mr_table.mpt_alloc, key);
return err;
}
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 7f8853b44ee..b2112f5a422 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -567,12 +567,12 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
/* Init the adapter */
nesdev->nesadapter = nes_init_adapter(nesdev, hw_rev);
- nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval;
if (!nesdev->nesadapter) {
printk(KERN_ERR PFX "Unable to initialize adapter.\n");
ret = -ENOMEM;
goto bail5;
}
+ nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval;
/* nesdev->base_doorbell_index =
nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index fd57e8a1582..a48b288618e 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -285,6 +285,21 @@ struct nes_device {
};
+static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad)
+{
+ u32 crc_value;
+ crc_value = crc32c(~0, (void *)nes_quad, sizeof (struct nes_v4_quad));
+
+ /*
+ * With commit ef19454b ("[LIB] crc32c: Keep intermediate crc
+ * state in cpu order"), behavior of crc32c changes on
+ * big-endian platforms. Our algorithm expects the previous
+ * behavior; otherwise we have RDMA connection establishment
+ * issue on big-endian.
+ */
+ return cpu_to_le32(crc_value);
+}
+
static inline void
set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value)
{
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index bd5cfeaac20..39adb267fb1 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -370,11 +370,11 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
int ret = 0;
u32 was_timer_set;
+ if (!cm_node)
+ return -EINVAL;
new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC);
if (!new_send)
return -1;
- if (!cm_node)
- return -EINVAL;
/* new_send->timetosend = currenttime */
new_send->retrycount = NES_DEFAULT_RETRYS;
@@ -947,6 +947,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
nes_debug(NES_DBG_CM, "destroying listener (%p)\n", listener);
kfree(listener);
+ listener = NULL;
ret = 0;
cm_listens_destroyed++;
} else {
@@ -2319,6 +2320,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
struct iw_cm_event cm_event;
struct nes_hw_qp_wqe *wqe;
struct nes_v4_quad nes_quad;
+ u32 crc_value;
int ret;
ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
@@ -2435,8 +2437,8 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port;
/* Produce hash key */
- nesqp->hte_index = cpu_to_be32(
- crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff);
+ crc_value = get_crc_value(&nes_quad);
+ nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff);
nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n",
nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask);
@@ -2750,6 +2752,7 @@ void cm_event_connected(struct nes_cm_event *event)
struct iw_cm_event cm_event;
struct nes_hw_qp_wqe *wqe;
struct nes_v4_quad nes_quad;
+ u32 crc_value;
int ret;
/* get all our handles */
@@ -2827,8 +2830,8 @@ void cm_event_connected(struct nes_cm_event *event)
nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port;
/* Produce hash key */
- nesqp->hte_index = cpu_to_be32(
- crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff);
+ crc_value = get_crc_value(&nes_quad);
+ nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff);
nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, After CRC = 0x%08X\n",
nesqp->hte_index, nesqp->hte_index & nesadapter->hte_index_mask);
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 7c4c0fbf0ab..49e53e4c1eb 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -156,15 +156,14 @@ static void nes_nic_tune_timer(struct nes_device *nesdev)
spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags);
- if (shared_timer->cq_count_old < cq_count) {
- if (cq_count > shared_timer->threshold_low)
- shared_timer->cq_direction_downward=0;
- }
- if (shared_timer->cq_count_old >= cq_count)
+ if (shared_timer->cq_count_old <= cq_count)
+ shared_timer->cq_direction_downward = 0;
+ else
shared_timer->cq_direction_downward++;
shared_timer->cq_count_old = cq_count;
if (shared_timer->cq_direction_downward > NES_NIC_CQ_DOWNWARD_TREND) {
- if (cq_count <= shared_timer->threshold_low) {
+ if (cq_count <= shared_timer->threshold_low &&
+ shared_timer->threshold_low > 4) {
shared_timer->threshold_low = shared_timer->threshold_low/2;
shared_timer->cq_direction_downward=0;
nesdev->currcq_count = 0;
@@ -1728,7 +1727,6 @@ int nes_napi_isr(struct nes_device *nesdev)
nesdev->int_req &= ~NES_INT_TIMER;
nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);
- nesadapter->tune_timer.timer_in_use_old = 0;
}
nesdev->deepcq_count = 0;
return 1;
@@ -1867,7 +1865,6 @@ void nes_dpc(unsigned long param)
nesdev->int_req &= ~NES_INT_TIMER;
nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);
- nesdev->nesadapter->tune_timer.timer_in_use_old = 0;
} else {
nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req));
}
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index 1e10df550c9..b7e2844f096 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -962,7 +962,7 @@ struct nes_arp_entry {
#define DEFAULT_JUMBO_NES_QL_LOW 12
#define DEFAULT_JUMBO_NES_QL_TARGET 40
#define DEFAULT_JUMBO_NES_QL_HIGH 128
-#define NES_NIC_CQ_DOWNWARD_TREND 8
+#define NES_NIC_CQ_DOWNWARD_TREND 16
struct nes_hw_tune_timer {
//u16 cq_count;
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index b6cc265aa9a..eee77da6193 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -148,14 +148,15 @@ static int nes_netdev_open(struct net_device *netdev)
struct nes_device *nesdev = nesvnic->nesdev;
int ret;
int i;
- struct nes_vnic *first_nesvnic;
+ struct nes_vnic *first_nesvnic = NULL;
u32 nic_active_bit;
u32 nic_active;
+ struct list_head *list_pos, *list_temp;
assert(nesdev != NULL);
- first_nesvnic = list_entry(nesdev->nesadapter->nesvnic_list[nesdev->mac_index].next,
- struct nes_vnic, list);
+ if (nesvnic->netdev_open == 1)
+ return 0;
if (netif_msg_ifup(nesvnic))
printk(KERN_INFO PFX "%s: enabling interface\n", netdev->name);
@@ -225,7 +226,18 @@ static int nes_netdev_open(struct net_device *netdev)
nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
nesvnic->nic_cq.cq_number);
nes_read32(nesdev->regs+NES_CQE_ALLOC);
-
+ list_for_each_safe(list_pos, list_temp, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) {
+ first_nesvnic = container_of(list_pos, struct nes_vnic, list);
+ if (first_nesvnic->netdev_open == 1)
+ break;
+ }
+ if (first_nesvnic->netdev_open == 0) {
+ nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n");
+ nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * nesdev->mac_index),
+ ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT |
+ NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR));
+ first_nesvnic = nesvnic;
+ }
if (first_nesvnic->linkup) {
/* Enable network packets */
nesvnic->linkup = 1;
@@ -248,6 +260,8 @@ static int nes_netdev_stop(struct net_device *netdev)
struct nes_device *nesdev = nesvnic->nesdev;
u32 nic_active_mask;
u32 nic_active;
+ struct nes_vnic *first_nesvnic = NULL;
+ struct list_head *list_pos, *list_temp;
nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n",
nesvnic, nesdev, netdev, netdev->name);
@@ -260,9 +274,20 @@ static int nes_netdev_stop(struct net_device *netdev)
/* Disable network packets */
napi_disable(&nesvnic->napi);
netif_stop_queue(netdev);
- if ((nesdev->netdev[0] == netdev) & (nesvnic->logical_port == nesdev->mac_index)) {
- nes_write_indexed(nesdev,
- NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 0xffffffff);
+ list_for_each_safe(list_pos, list_temp, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) {
+ first_nesvnic = container_of(list_pos, struct nes_vnic, list);
+ if ((first_nesvnic->netdev_open == 1) && (first_nesvnic != nesvnic))
+ break;
+ }
+
+ if (first_nesvnic->netdev_open == 0)
+ nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 0xffffffff);
+ else if ((first_nesvnic != nesvnic) &&
+ (PCI_FUNC(first_nesvnic->nesdev->pcidev->devfn) != PCI_FUNC(nesvnic->nesdev->pcidev->devfn))) {
+ nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * nesdev->mac_index), 0xffffffff);
+ nes_write_indexed(first_nesvnic->nesdev, NES_IDX_MAC_INT_MASK + (0x200 * first_nesvnic->nesdev->mac_index),
+ ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT |
+ NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR));
}
nic_active_mask = ~((u32)(1 << nesvnic->nic_index));
@@ -859,7 +884,6 @@ void nes_netdev_set_multicast_list(struct net_device *netdev)
for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) {
while (multicast_addr && nesvnic->mcrq_mcast_filter && ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, multicast_addr->dmi_addr)) == 0))
multicast_addr = multicast_addr->next;
-
if (mc_nic_index < 0)
mc_nic_index = nesvnic->nic_index;
if (multicast_addr) {
@@ -908,7 +932,7 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL;
netdev->mtu = new_mtu;
- nesvnic->max_frame_size = new_mtu+ETH_HLEN;
+ nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN;
if (netdev->mtu > 1500) {
jumbomode=1;
@@ -1470,10 +1494,15 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
{
struct nes_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev;
+ struct nes_adapter *nesadapter = nesdev->nesadapter;
u32 u32temp;
+ unsigned long flags;
+ spin_lock_irqsave(&nesadapter->phy_lock, flags);
nesvnic->vlan_grp = grp;
+ nes_debug(NES_DBG_NETDEV, "%s: %s\n", __func__, netdev->name);
+
/* Enable/Disable VLAN Stripping */
u32temp = nes_read_indexed(nesdev, NES_IDX_PCIX_DIAG);
if (grp)
@@ -1482,6 +1511,7 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
u32temp |= 0x02000000;
nes_write_indexed(nesdev, NES_IDX_PCIX_DIAG, u32temp);
+ spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
}
@@ -1540,7 +1570,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
nesvnic->msg_enable = netif_msg_init(debug, default_msg);
nesvnic->netdev_index = nesdev->netdev_count;
nesvnic->perfect_filter_index = nesdev->nesadapter->netdev_count;
- nesvnic->max_frame_size = netdev->mtu+netdev->hard_header_len;
+ nesvnic->max_frame_size = netdev->mtu + netdev->hard_header_len + VLAN_HLEN;
curr_qp_map = nic_qp_mapping_per_function[PCI_FUNC(nesdev->pcidev->devfn)];
nesvnic->nic.qp_id = curr_qp_map[nesdev->netdev_count].qpid;
@@ -1610,7 +1640,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]);
if ((nesdev->netdev_count == 0) &&
- (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) {
+ (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) {
nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n",
NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1)));
u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
@@ -1648,18 +1678,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
nesvnic->linkup = 1;
}
}
- nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n");
/* clear the MAC interrupt status, assumes direct logical to physical mapping */
- u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS+(0x200*nesvnic->logical_port));
+ u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));
nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp);
- nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS+(0x200*nesvnic->logical_port), u32temp);
+ nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp);
- if (nesdev->nesadapter->phy_type[nesvnic->logical_port] != NES_PHY_TYPE_IRIS)
+ if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_IRIS)
nes_init_phy(nesdev);
- nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK+(0x200*nesvnic->logical_port),
- ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT |
- NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR));
}
return netdev;
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index ffd4b425567..a651e9d9f0e 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -929,7 +929,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev,
NES_MAX_USER_DB_REGIONS, nesucontext->first_free_db);
nes_debug(NES_DBG_PD, "find_first_zero_biton doorbells returned %u, mapping pd_id %u.\n",
nespd->mmap_db_index, nespd->pd_id);
- if (nespd->mmap_db_index > NES_MAX_USER_DB_REGIONS) {
+ if (nespd->mmap_db_index >= NES_MAX_USER_DB_REGIONS) {
nes_debug(NES_DBG_PD, "mmap_db_index > MAX\n");
nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num);
kfree(nespd);
@@ -1327,7 +1327,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
(long long unsigned int)req.user_wqe_buffers);
nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num);
kfree(nesqp->allocated_buffer);
- return ERR_PTR(-ENOMEM);
+ return ERR_PTR(-EFAULT);
}
}
@@ -1337,7 +1337,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
NES_MAX_USER_WQ_REGIONS, nes_ucontext->first_free_wq);
/* nes_debug(NES_DBG_QP, "find_first_zero_biton wqs returned %u\n",
nespd->mmap_db_index); */
- if (nesqp->mmap_sq_db_index > NES_MAX_USER_WQ_REGIONS) {
+ if (nesqp->mmap_sq_db_index >= NES_MAX_USER_WQ_REGIONS) {
nes_debug(NES_DBG_QP,
"db index > max user regions, failing create QP\n");
nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num);
@@ -1674,6 +1674,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
}
nes_debug(NES_DBG_CQ, "CQ Virtual Address = %08lX, size = %u.\n",
(unsigned long)req.user_cq_buffer, entries);
+ err = 1;
list_for_each_entry(nespbl, &nes_ucontext->cq_reg_mem_list, list) {
if (nespbl->user_base == (unsigned long )req.user_cq_buffer) {
list_del(&nespbl->list);
@@ -1686,7 +1687,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
if (err) {
nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
kfree(nescq);
- return ERR_PTR(err);
+ return ERR_PTR(-EFAULT);
}
pbl_entries = nespbl->pbl_size >> 3;
@@ -1831,9 +1832,6 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
}
}
- nes_debug(NES_DBG_CQ, "iWARP CQ%u create timeout expired, major code = 0x%04X,"
- " minor code = 0x%04X\n",
- nescq->hw_cq.cq_number, cqp_request->major_code, cqp_request->minor_code);
if (!context)
pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem,
nescq->hw_cq.cq_pbase);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 7dd2ec473d2..52b1bebfa74 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -824,7 +824,6 @@ void ipoib_cm_dev_stop(struct net_device *dev)
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_cm_rx *p;
unsigned long begin;
- LIST_HEAD(list);
int ret;
if (!IPOIB_CM_SUPPORTED(dev->dev_addr) || !priv->cm.id)
@@ -857,9 +856,12 @@ void ipoib_cm_dev_stop(struct net_device *dev)
/*
* assume the HW is wedged and just free up everything.
*/
- list_splice_init(&priv->cm.rx_flush_list, &list);
- list_splice_init(&priv->cm.rx_error_list, &list);
- list_splice_init(&priv->cm.rx_drain_list, &list);
+ list_splice_init(&priv->cm.rx_flush_list,
+ &priv->cm.rx_reap_list);
+ list_splice_init(&priv->cm.rx_error_list,
+ &priv->cm.rx_reap_list);
+ list_splice_init(&priv->cm.rx_drain_list,
+ &priv->cm.rx_reap_list);
break;
}
spin_unlock_irq(&priv->lock);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 8b10d9f23be..c5263d63aca 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -42,14 +42,14 @@ config INPUT_M68K_BEEP
config INPUT_APANEL
tristate "Fujitsu Lifebook Application Panel buttons"
- depends on X86
- select I2C_I801
+ depends on X86 && I2C && LEDS_CLASS
select INPUT_POLLDEV
select CHECK_SIGNATURE
help
Say Y here for support of the Application Panel buttons, used on
Fujitsu Lifebook. These are attached to the mainboard through
- an SMBus interface managed by the I2C Intel ICH (i801) driver.
+ an SMBus interface managed by the I2C Intel ICH (i801) driver,
+ which you should also build for this kernel.
To compile this driver as a module, choose M here: the module will
be called apanel.
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index aacedec4986..827c32c1679 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -637,7 +637,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
err("maximum number of devices exceeded");
return NULL;
}
- mutex_init(&cs->mutex);
gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1);
cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL);
@@ -898,8 +897,10 @@ int gigaset_shutdown(struct cardstate *cs)
{
mutex_lock(&cs->mutex);
- if (!(cs->flags & VALID_MINOR))
+ if (!(cs->flags & VALID_MINOR)) {
+ mutex_unlock(&cs->mutex);
return -1;
+ }
cs->waiting = 1;
@@ -1086,6 +1087,7 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
drv->cs[i].driver = drv;
drv->cs[i].ops = drv->ops;
drv->cs[i].minor_index = i;
+ mutex_init(&drv->cs[i].mutex);
}
gigaset_if_initdriver(drv, procname, devname);
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index 7993e01f9fc..76043dedba5 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -725,23 +725,6 @@ static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
switch (adapter->type) {
case AVM_FRITZ_PCIV2:
- retval = request_irq(adapter->irq, fcpci2_irq, IRQF_SHARED,
- "fcpcipnp", adapter);
- break;
- case AVM_FRITZ_PCI:
- retval = request_irq(adapter->irq, fcpci_irq, IRQF_SHARED,
- "fcpcipnp", adapter);
- break;
- case AVM_FRITZ_PNP:
- retval = request_irq(adapter->irq, fcpci_irq, 0,
- "fcpcipnp", adapter);
- break;
- }
- if (retval)
- goto err_region;
-
- switch (adapter->type) {
- case AVM_FRITZ_PCIV2:
case AVM_FRITZ_PCI:
val = inl(adapter->io);
break;
@@ -796,6 +779,23 @@ static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
switch (adapter->type) {
case AVM_FRITZ_PCIV2:
+ retval = request_irq(adapter->irq, fcpci2_irq, IRQF_SHARED,
+ "fcpcipnp", adapter);
+ break;
+ case AVM_FRITZ_PCI:
+ retval = request_irq(adapter->irq, fcpci_irq, IRQF_SHARED,
+ "fcpcipnp", adapter);
+ break;
+ case AVM_FRITZ_PNP:
+ retval = request_irq(adapter->irq, fcpci_irq, 0,
+ "fcpcipnp", adapter);
+ break;
+ }
+ if (retval)
+ goto err_region;
+
+ switch (adapter->type) {
+ case AVM_FRITZ_PCIV2:
fcpci2_init(adapter);
isacsx_setup(&adapter->isac);
break;
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c
index f93de4a3035..78f7660c1d0 100644
--- a/drivers/isdn/i4l/isdn_ttyfax.c
+++ b/drivers/isdn/i4l/isdn_ttyfax.c
@@ -906,7 +906,8 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
sprintf(rs, "\r\n0-2");
isdn_tty_at_cout(rs, info);
} else {
- if ((f->phase != ISDN_FAX_PHASE_D) || (!info->faxonline & 1))
+ if ((f->phase != ISDN_FAX_PHASE_D) ||
+ (!(info->faxonline & 1)))
PARSE_ERROR1;
par = isdn_getnum(p);
if ((par < 0) || (par > 2))
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index 655ef9a3f4d..a335c85a736 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -1289,7 +1289,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
}
break;
case ISDN_CMD_CLREAZ:
- if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
+ if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
return -ENODEV;
if (card->leased)
break;
@@ -1333,7 +1333,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
}
break;
case ISDN_CMD_SETL3:
- if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
+ if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
return -ENODEV;
return 0;
default:
@@ -1380,7 +1380,7 @@ if_writecmd(const u_char __user *buf, int len, int id, int channel)
isdnloop_card *card = isdnloop_findcard(id);
if (card) {
- if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
+ if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
return -ENODEV;
return (isdnloop_writecmd(buf, len, 1, card));
}
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index 51a112815f4..bd8a1d14b45 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -698,7 +698,8 @@ static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
{
struct media_bay_info *bay = macio_get_drvdata(mdev);
- if (state.event != mdev->ofdev.dev.power.power_state.event && state.event == PM_EVENT_SUSPEND) {
+ if (state.event != mdev->ofdev.dev.power.power_state.event
+ && (state.event & PM_EVENT_SLEEP)) {
down(&bay->lock);
bay->sleeping = 1;
set_mb_power(bay, 0);
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 7aeceedcf7d..831aed9c56f 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1047,6 +1047,11 @@ void bitmap_daemon_work(struct bitmap *bitmap)
if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ))
return;
bitmap->daemon_lastrun = jiffies;
+ if (bitmap->allclean) {
+ bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
+ return;
+ }
+ bitmap->allclean = 1;
for (j = 0; j < bitmap->chunks; j++) {
bitmap_counter_t *bmc;
@@ -1068,8 +1073,10 @@ void bitmap_daemon_work(struct bitmap *bitmap)
clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
spin_unlock_irqrestore(&bitmap->lock, flags);
- if (need_write)
+ if (need_write) {
write_page(bitmap, page, 0);
+ bitmap->allclean = 0;
+ }
continue;
}
@@ -1098,6 +1105,9 @@ void bitmap_daemon_work(struct bitmap *bitmap)
/*
if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc);
*/
+ if (*bmc)
+ bitmap->allclean = 0;
+
if (*bmc == 2) {
*bmc=1; /* maybe clear the bit next time */
set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
@@ -1132,6 +1142,8 @@ void bitmap_daemon_work(struct bitmap *bitmap)
}
}
+ if (bitmap->allclean == 0)
+ bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ;
}
static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
@@ -1226,6 +1238,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
sectors -= blocks;
else sectors = 0;
}
+ bitmap->allclean = 0;
return 0;
}
@@ -1296,6 +1309,7 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
}
}
spin_unlock_irq(&bitmap->lock);
+ bitmap->allclean = 0;
return rv;
}
@@ -1332,6 +1346,7 @@ void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int ab
}
unlock:
spin_unlock_irqrestore(&bitmap->lock, flags);
+ bitmap->allclean = 0;
}
void bitmap_close_sync(struct bitmap *bitmap)
@@ -1399,7 +1414,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
}
spin_unlock_irq(&bitmap->lock);
-
+ bitmap->allclean = 0;
}
/* dirty the memory and file bits for bitmap chunks "s" to "e" */
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 2928ef22810..51605870f89 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1695,14 +1695,15 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
* information for a retry or there was no other
* mirror in-sync.
*/
- DMERR_LIMIT("Mirror read failed from %s.",
- m->dev->name);
+ DMERR_LIMIT("Mirror read failed.");
return -EIO;
}
+
+ m = read_record->m;
+
DMERR("Mirror read failed from %s. Trying alternative device.",
m->dev->name);
- m = read_record->m;
fail_mirror(m, DM_RAID1_READ_ERROR);
/*
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 7da6ec244e1..827824a9f3e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1105,7 +1105,11 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256;
bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1;
if (rdev->sb_size & bmask)
- rdev-> sb_size = (rdev->sb_size | bmask)+1;
+ rdev->sb_size = (rdev->sb_size | bmask) + 1;
+
+ if (minor_version
+ && rdev->data_offset < sb_offset + (rdev->sb_size/512))
+ return -EINVAL;
if (sb->level == cpu_to_le32(LEVEL_MULTIPATH))
rdev->desc_nr = -1;
@@ -1137,7 +1141,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
else
ret = 0;
}
- if (minor_version)
+ if (minor_version)
rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2;
else
rdev->size = rdev->sb_offset;
@@ -1499,7 +1503,8 @@ static void export_rdev(mdk_rdev_t * rdev)
free_disk_sb(rdev);
list_del_init(&rdev->same_set);
#ifndef MODULE
- md_autodetect_dev(rdev->bdev->bd_dev);
+ if (test_bit(AutoDetected, &rdev->flags))
+ md_autodetect_dev(rdev->bdev->bd_dev);
#endif
unlock_rdev(rdev);
kobject_put(&rdev->kobj);
@@ -1996,9 +2001,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
char *e;
unsigned long long size = simple_strtoull(buf, &e, 10);
unsigned long long oldsize = rdev->size;
+ mddev_t *my_mddev = rdev->mddev;
+
if (e==buf || (*e && *e != '\n'))
return -EINVAL;
- if (rdev->mddev->pers)
+ if (my_mddev->pers)
return -EBUSY;
rdev->size = size;
if (size > oldsize && rdev->mddev->external) {
@@ -2011,7 +2018,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
int overlap = 0;
struct list_head *tmp, *tmp2;
- mddev_unlock(rdev->mddev);
+ mddev_unlock(my_mddev);
for_each_mddev(mddev, tmp) {
mdk_rdev_t *rdev2;
@@ -2031,7 +2038,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
break;
}
}
- mddev_lock(rdev->mddev);
+ mddev_lock(my_mddev);
if (overlap) {
/* Someone else could have slipped in a size
* change here, but doing so is just silly.
@@ -2043,8 +2050,8 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
return -EBUSY;
}
}
- if (size < rdev->mddev->size || rdev->mddev->size == 0)
- rdev->mddev->size = size;
+ if (size < my_mddev->size || my_mddev->size == 0)
+ my_mddev->size = size;
return len;
}
@@ -2065,10 +2072,21 @@ rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
{
struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
+ mddev_t *mddev = rdev->mddev;
+ ssize_t rv;
if (!entry->show)
return -EIO;
- return entry->show(rdev, page);
+
+ rv = mddev ? mddev_lock(mddev) : -EBUSY;
+ if (!rv) {
+ if (rdev->mddev == NULL)
+ rv = -EBUSY;
+ else
+ rv = entry->show(rdev, page);
+ mddev_unlock(mddev);
+ }
+ return rv;
}
static ssize_t
@@ -2077,15 +2095,19 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr,
{
struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
- int rv;
+ ssize_t rv;
+ mddev_t *mddev = rdev->mddev;
if (!entry->store)
return -EIO;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- rv = mddev_lock(rdev->mddev);
+ rv = mddev ? mddev_lock(mddev): -EBUSY;
if (!rv) {
- rv = entry->store(rdev, page, length);
+ if (rdev->mddev == NULL)
+ rv = -EBUSY;
+ else
+ rv = entry->store(rdev, page, length);
mddev_unlock(rdev->mddev);
}
return rv;
@@ -5351,6 +5373,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
mddev->ro = 0;
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread);
+ md_wakeup_thread(mddev->sync_thread);
}
atomic_inc(&mddev->writes_pending);
if (mddev->in_sync) {
@@ -6021,6 +6044,7 @@ static void autostart_arrays(int part)
MD_BUG();
continue;
}
+ set_bit(AutoDetected, &rdev->flags);
list_add(&rdev->same_set, &pending_raid_disks);
i_passed++;
}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 5c7fef091ce..ff61b309129 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -592,6 +592,37 @@ static int raid1_congested(void *data, int bits)
}
+static int flush_pending_writes(conf_t *conf)
+{
+ /* Any writes that have been queued but are awaiting
+ * bitmap updates get flushed here.
+ * We return 1 if any requests were actually submitted.
+ */
+ int rv = 0;
+
+ spin_lock_irq(&conf->device_lock);
+
+ if (conf->pending_bio_list.head) {
+ struct bio *bio;
+ bio = bio_list_get(&conf->pending_bio_list);
+ blk_remove_plug(conf->mddev->queue);
+ spin_unlock_irq(&conf->device_lock);
+ /* flush any pending bitmap writes to
+ * disk before proceeding w/ I/O */
+ bitmap_unplug(conf->mddev->bitmap);
+
+ while (bio) { /* submit pending writes */
+ struct bio *next = bio->bi_next;
+ bio->bi_next = NULL;
+ generic_make_request(bio);
+ bio = next;
+ }
+ rv = 1;
+ } else
+ spin_unlock_irq(&conf->device_lock);
+ return rv;
+}
+
/* Barriers....
* Sometimes we need to suspend IO while we do something else,
* either some resync/recovery, or reconfigure the array.
@@ -673,15 +704,23 @@ static void freeze_array(conf_t *conf)
/* stop syncio and normal IO and wait for everything to
* go quite.
* We increment barrier and nr_waiting, and then
- * wait until barrier+nr_pending match nr_queued+2
+ * wait until nr_pending match nr_queued+1
+ * This is called in the context of one normal IO request
+ * that has failed. Thus any sync request that might be pending
+ * will be blocked by nr_pending, and we need to wait for
+ * pending IO requests to complete or be queued for re-try.
+ * Thus the number queued (nr_queued) plus this request (1)
+ * must match the number of pending IOs (nr_pending) before
+ * we continue.
*/
spin_lock_irq(&conf->resync_lock);
conf->barrier++;
conf->nr_waiting++;
wait_event_lock_irq(conf->wait_barrier,
- conf->barrier+conf->nr_pending == conf->nr_queued+2,
+ conf->nr_pending == conf->nr_queued+1,
conf->resync_lock,
- raid1_unplug(conf->mddev->queue));
+ ({ flush_pending_writes(conf);
+ raid1_unplug(conf->mddev->queue); }));
spin_unlock_irq(&conf->resync_lock);
}
static void unfreeze_array(conf_t *conf)
@@ -907,6 +946,9 @@ static int make_request(struct request_queue *q, struct bio * bio)
blk_plug_device(mddev->queue);
spin_unlock_irqrestore(&conf->device_lock, flags);
+ /* In case raid1d snuck into freeze_array */
+ wake_up(&conf->wait_barrier);
+
if (do_sync)
md_wakeup_thread(mddev->thread);
#if 0
@@ -1473,28 +1515,14 @@ static void raid1d(mddev_t *mddev)
for (;;) {
char b[BDEVNAME_SIZE];
- spin_lock_irqsave(&conf->device_lock, flags);
-
- if (conf->pending_bio_list.head) {
- bio = bio_list_get(&conf->pending_bio_list);
- blk_remove_plug(mddev->queue);
- spin_unlock_irqrestore(&conf->device_lock, flags);
- /* flush any pending bitmap writes to disk before proceeding w/ I/O */
- bitmap_unplug(mddev->bitmap);
- while (bio) { /* submit pending writes */
- struct bio *next = bio->bi_next;
- bio->bi_next = NULL;
- generic_make_request(bio);
- bio = next;
- }
- unplug = 1;
+ unplug += flush_pending_writes(conf);
- continue;
- }
-
- if (list_empty(head))
+ spin_lock_irqsave(&conf->device_lock, flags);
+ if (list_empty(head)) {
+ spin_unlock_irqrestore(&conf->device_lock, flags);
break;
+ }
r1_bio = list_entry(head->prev, r1bio_t, retry_list);
list_del(head->prev);
conf->nr_queued--;
@@ -1590,7 +1618,6 @@ static void raid1d(mddev_t *mddev)
}
}
}
- spin_unlock_irqrestore(&conf->device_lock, flags);
if (unplug)
unplug_slaves(mddev);
}
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 017f58113c3..32389d2f18f 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -537,7 +537,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
current_distance = abs(r10_bio->devs[slot].addr -
conf->mirrors[disk].head_position);
- /* Find the disk whose head is closest */
+ /* Find the disk whose head is closest,
+ * or - for far > 1 - find the closest to partition beginning */
for (nslot = slot; nslot < conf->copies; nslot++) {
int ndisk = r10_bio->devs[nslot].devnum;
@@ -557,8 +558,13 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
slot = nslot;
break;
}
- new_distance = abs(r10_bio->devs[nslot].addr -
- conf->mirrors[ndisk].head_position);
+
+ /* for far > 1 always use the lowest address */
+ if (conf->far_copies > 1)
+ new_distance = r10_bio->devs[nslot].addr;
+ else
+ new_distance = abs(r10_bio->devs[nslot].addr -
+ conf->mirrors[ndisk].head_position);
if (new_distance < current_distance) {
current_distance = new_distance;
disk = ndisk;
@@ -629,7 +635,36 @@ static int raid10_congested(void *data, int bits)
return ret;
}
-
+static int flush_pending_writes(conf_t *conf)
+{
+ /* Any writes that have been queued but are awaiting
+ * bitmap updates get flushed here.
+ * We return 1 if any requests were actually submitted.
+ */
+ int rv = 0;
+
+ spin_lock_irq(&conf->device_lock);
+
+ if (conf->pending_bio_list.head) {
+ struct bio *bio;
+ bio = bio_list_get(&conf->pending_bio_list);
+ blk_remove_plug(conf->mddev->queue);
+ spin_unlock_irq(&conf->device_lock);
+ /* flush any pending bitmap writes to disk
+ * before proceeding w/ I/O */
+ bitmap_unplug(conf->mddev->bitmap);
+
+ while (bio) { /* submit pending writes */
+ struct bio *next = bio->bi_next;
+ bio->bi_next = NULL;
+ generic_make_request(bio);
+ bio = next;
+ }
+ rv = 1;
+ } else
+ spin_unlock_irq(&conf->device_lock);
+ return rv;
+}
/* Barriers....
* Sometimes we need to suspend IO while we do something else,
* either some resync/recovery, or reconfigure the array.
@@ -712,15 +747,23 @@ static void freeze_array(conf_t *conf)
/* stop syncio and normal IO and wait for everything to
* go quiet.
* We increment barrier and nr_waiting, and then
- * wait until barrier+nr_pending match nr_queued+2
+ * wait until nr_pending match nr_queued+1
+ * This is called in the context of one normal IO request
+ * that has failed. Thus any sync request that might be pending
+ * will be blocked by nr_pending, and we need to wait for
+ * pending IO requests to complete or be queued for re-try.
+ * Thus the number queued (nr_queued) plus this request (1)
+ * must match the number of pending IOs (nr_pending) before
+ * we continue.
*/
spin_lock_irq(&conf->resync_lock);
conf->barrier++;
conf->nr_waiting++;
wait_event_lock_irq(conf->wait_barrier,
- conf->barrier+conf->nr_pending == conf->nr_queued+2,
+ conf->nr_pending == conf->nr_queued+1,
conf->resync_lock,
- raid10_unplug(conf->mddev->queue));
+ ({ flush_pending_writes(conf);
+ raid10_unplug(conf->mddev->queue); }));
spin_unlock_irq(&conf->resync_lock);
}
@@ -892,6 +935,9 @@ static int make_request(struct request_queue *q, struct bio * bio)
blk_plug_device(mddev->queue);
spin_unlock_irqrestore(&conf->device_lock, flags);
+ /* In case raid10d snuck in to freeze_array */
+ wake_up(&conf->wait_barrier);
+
if (do_sync)
md_wakeup_thread(mddev->thread);
@@ -1464,28 +1510,14 @@ static void raid10d(mddev_t *mddev)
for (;;) {
char b[BDEVNAME_SIZE];
- spin_lock_irqsave(&conf->device_lock, flags);
- if (conf->pending_bio_list.head) {
- bio = bio_list_get(&conf->pending_bio_list);
- blk_remove_plug(mddev->queue);
- spin_unlock_irqrestore(&conf->device_lock, flags);
- /* flush any pending bitmap writes to disk before proceeding w/ I/O */
- bitmap_unplug(mddev->bitmap);
-
- while (bio) { /* submit pending writes */
- struct bio *next = bio->bi_next;
- bio->bi_next = NULL;
- generic_make_request(bio);
- bio = next;
- }
- unplug = 1;
-
- continue;
- }
+ unplug += flush_pending_writes(conf);
- if (list_empty(head))
+ spin_lock_irqsave(&conf->device_lock, flags);
+ if (list_empty(head)) {
+ spin_unlock_irqrestore(&conf->device_lock, flags);
break;
+ }
r10_bio = list_entry(head->prev, r10bio_t, retry_list);
list_del(head->prev);
conf->nr_queued--;
@@ -1548,7 +1580,6 @@ static void raid10d(mddev_t *mddev)
}
}
}
- spin_unlock_irqrestore(&conf->device_lock, flags);
if (unplug)
unplug_slaves(mddev);
}
@@ -1787,6 +1818,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
if (j == conf->copies) {
/* Cannot recover, so abort the recovery */
put_buf(r10_bio);
+ if (rb2)
+ atomic_dec(&rb2->remaining);
r10_bio = rb2;
if (!test_and_set_bit(MD_RECOVERY_ERR, &mddev->recovery))
printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n",
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 8f4a45346de..11950698a2e 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -25,11 +25,16 @@ config VIDEO_DEV
To compile this driver as a module, choose M here: the
module will be called videodev.
+config VIDEO_V4L2_COMMON
+ tristate
+ depends on (I2C || I2C=n) && VIDEO_DEV
+ default (I2C || I2C=n) && VIDEO_DEV
+
config VIDEO_V4L1
bool "Enable Video For Linux API 1 (DEPRECATED)"
- depends on VIDEO_DEV
+ depends on VIDEO_DEV && VIDEO_V4L2_COMMON
+ default VIDEO_DEV && VIDEO_V4L2_COMMON
select VIDEO_V4L1_COMPAT
- default y
---help---
Enables a compatibility API used by most V4L2 devices to allow
its usage with legacy applications that supports only V4L1 api.
@@ -39,7 +44,7 @@ config VIDEO_V4L1
config VIDEO_V4L1_COMPAT
bool "Enable Video For Linux API 1 compatible Layer"
depends on VIDEO_DEV
- default y
+ default VIDEO_DEV
---help---
This api were developed to be used at Kernel 2.2 and 2.4, but
lacks support for several video standards. There are several
@@ -55,8 +60,8 @@ config VIDEO_V4L1_COMPAT
config VIDEO_V4L2
bool
- depends on VIDEO_DEV
- default y
+ depends on VIDEO_DEV && VIDEO_V4L2_COMMON
+ default VIDEO_DEV && VIDEO_V4L2_COMMON
source "drivers/media/video/Kconfig"
@@ -93,7 +98,7 @@ if VIDEO_TUNER_CUSTOMIZE
config TUNER_XC2028
tristate "XCeive xc2028/xc3028 tuners"
- depends on I2C
+ depends on I2C && FW_LOADER
default m if VIDEO_TUNER_CUSTOMIZE
help
Say Y here to include support for the xc2028/xc3028 tuners.
@@ -180,7 +185,6 @@ config VIDEO_TVEEPROM
config DAB
boolean "DAB adapters"
- default y
---help---
Allow selecting support for for Digital Audio Broadcasting (DAB)
Receiver adapters.
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index 06ca75911b7..769c6f8142d 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -4,6 +4,6 @@ config VIDEO_SAA7146
config VIDEO_SAA7146_VV
tristate
- depends on VIDEO_DEV
+ depends on VIDEO_V4L2
select VIDEOBUF_DMA_SG
select VIDEO_SAA7146
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index a4a937c9053..2ab5a120470 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -1987,3 +1987,49 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_behold);
+
+/*
+ * Remote control for the Genius TVGO A11MCE
+ * Adrian Pardini <pardo.bsso@gmail.com>
+ */
+IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE] = {
+ /* Keys 0 to 9 */
+ [0x48] = KEY_0,
+ [0x09] = KEY_1,
+ [0x1d] = KEY_2,
+ [0x1f] = KEY_3,
+ [0x19] = KEY_4,
+ [0x1b] = KEY_5,
+ [0x11] = KEY_6,
+ [0x17] = KEY_7,
+ [0x12] = KEY_8,
+ [0x16] = KEY_9,
+
+ [0x54] = KEY_RECORD, /* recording */
+ [0x06] = KEY_MUTE, /* mute */
+ [0x10] = KEY_POWER,
+ [0x40] = KEY_LAST, /* recall */
+ [0x4c] = KEY_CHANNELUP, /* channel / program + */
+ [0x00] = KEY_CHANNELDOWN, /* channel / program - */
+ [0x0d] = KEY_VOLUMEUP,
+ [0x15] = KEY_VOLUMEDOWN,
+ [0x4d] = KEY_OK, /* also labeled as Pause */
+ [0x1c] = KEY_ZOOM, /* full screen and Stop*/
+ [0x02] = KEY_MODE, /* AV Source or Rewind*/
+ [0x04] = KEY_LIST, /* -/-- */
+ /* small arrows above numbers */
+ [0x1a] = KEY_NEXT, /* also Fast Forward */
+ [0x0e] = KEY_PREVIOUS, /* also Rewind */
+ /* these are in a rather non standard layout and have
+ an alternate name written */
+ [0x1e] = KEY_UP, /* Video Setting */
+ [0x0a] = KEY_DOWN, /* Video Default */
+ [0x05] = KEY_LEFT, /* Snapshot */
+ [0x0c] = KEY_RIGHT, /* Hide Panel */
+ /* Four buttons without label */
+ [0x49] = KEY_RED,
+ [0x0b] = KEY_GREEN,
+ [0x13] = KEY_YELLOW,
+ [0x50] = KEY_BLUE,
+};
+EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce);
diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c
index c32dda973e9..bfbd5a841eb 100644
--- a/drivers/media/common/saa7146_vbi.c
+++ b/drivers/media/common/saa7146_vbi.c
@@ -413,7 +413,6 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
sizeof(struct saa7146_buf),
file);
- mutex_init(&fh->vbi_q.lock);
init_timer(&fh->vbi_read_timeout);
fh->vbi_read_timeout.function = vbi_read_timeout;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index c31ab480d8e..66fdbd0e6a6 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1417,8 +1417,6 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
sizeof(struct saa7146_buf),
file);
- mutex_init(&fh->video_q.lock);
-
return 0;
}
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index c7bbb40223f..56d8fab688b 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -75,7 +75,11 @@ EXPORT_SYMBOL(bt878);
#if defined(dprintk)
#undef dprintk
#endif
-#define dprintk if(bt878_debug) printk
+#define dprintk(fmt, arg...) \
+ do { \
+ if (bt878_debug) \
+ printk(KERN_DEBUG fmt, ##arg); \
+ } while (0)
static void bt878_mem_free(struct bt878 *bt)
{
@@ -154,7 +158,7 @@ static int bt878_make_risc(struct bt878 *bt)
}
if (bt->line_count > 255) {
- printk("bt878: buffer size error!\n");
+ printk(KERN_ERR "bt878: buffer size error!\n");
return -EINVAL;
}
return 0;
@@ -285,7 +289,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
if (astat & (BT878_ASCERR | BT878_AOCERR)) {
if (bt878_verbose) {
- printk("bt878(%d): irq%s%s risc_pc=%08x\n",
+ printk(KERN_INFO
+ "bt878(%d): irq%s%s risc_pc=%08x\n",
bt->nr,
(astat & BT878_ASCERR) ? " SCERR" :
"",
@@ -295,8 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
}
if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
if (bt878_verbose) {
- printk
- ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
+ printk(KERN_INFO
+ "bt878(%d): irq%s%s%s risc_pc=%08x\n",
bt->nr,
(astat & BT878_APABORT) ? " PABORT" :
"",
@@ -308,8 +313,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
}
if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
if (bt878_verbose) {
- printk
- ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
+ printk(KERN_INFO
+ "bt878(%d): irq%s%s%s risc_pc=%08x\n",
bt->nr,
(astat & BT878_AFDSR) ? " FDSR" : "",
(astat & BT878_AFTRGT) ? " FTRGT" :
@@ -510,7 +515,7 @@ static int __devinit bt878_probe(struct pci_dev *dev,
*/
if ((result = bt878_mem_alloc(bt))) {
- printk("bt878: failed to allocate memory!\n");
+ printk(KERN_ERR "bt878: failed to allocate memory!\n");
goto fail2;
}
@@ -536,7 +541,7 @@ static void __devexit bt878_remove(struct pci_dev *pci_dev)
struct bt878 *bt = pci_get_drvdata(pci_dev);
if (bt878_verbose)
- printk("bt878(%d): unloading\n", bt->nr);
+ printk(KERN_INFO "bt878(%d): unloading\n", bt->nr);
/* turn off all capturing, DMA and IRQs */
btand(~0x13, BT878_AGPIO_DMA_CTL);
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c
index 88dc4367a2e..3b9da9c25c6 100644
--- a/drivers/media/dvb/dvb-usb/ttusb2.c
+++ b/drivers/media/dvb/dvb-usb/ttusb2.c
@@ -144,6 +144,7 @@ static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
static struct tda10086_config tda10086_config = {
.demod_address = 0x0e,
.invert = 0,
+ .diseqc_tone = 1,
};
static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap)
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c
index 9d26ace6515..0d2b69a99ad 100644
--- a/drivers/media/dvb/frontends/tda10086.c
+++ b/drivers/media/dvb/frontends/tda10086.c
@@ -106,9 +106,12 @@ static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask,
static int tda10086_init(struct dvb_frontend* fe)
{
struct tda10086_state* state = fe->demodulator_priv;
+ u8 t22k_off = 0x80;
dprintk ("%s\n", __FUNCTION__);
+ if (state->config->diseqc_tone)
+ t22k_off = 0;
// reset
tda10086_write_byte(state, 0x00, 0x00);
msleep(10);
@@ -158,7 +161,7 @@ static int tda10086_init(struct dvb_frontend* fe)
tda10086_write_byte(state, 0x3d, 0x80);
// setup SEC
- tda10086_write_byte(state, 0x36, 0x80); // all SEC off, no 22k tone
+ tda10086_write_byte(state, 0x36, t22k_off); // all SEC off, 22k tone
tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); // } tone frequency
tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // }
@@ -180,16 +183,20 @@ static void tda10086_diseqc_wait(struct tda10086_state *state)
static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{
struct tda10086_state* state = fe->demodulator_priv;
+ u8 t22k_off = 0x80;
dprintk ("%s\n", __FUNCTION__);
+ if (state->config->diseqc_tone)
+ t22k_off = 0;
+
switch (tone) {
case SEC_TONE_OFF:
- tda10086_write_byte(state, 0x36, 0x80);
+ tda10086_write_byte(state, 0x36, t22k_off);
break;
case SEC_TONE_ON:
- tda10086_write_byte(state, 0x36, 0x81);
+ tda10086_write_byte(state, 0x36, 0x01 + t22k_off);
break;
}
@@ -202,9 +209,13 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
struct tda10086_state* state = fe->demodulator_priv;
int i;
u8 oldval;
+ u8 t22k_off = 0x80;
dprintk ("%s\n", __FUNCTION__);
+ if (state->config->diseqc_tone)
+ t22k_off = 0;
+
if (cmd->msg_len > 6)
return -EINVAL;
oldval = tda10086_read_byte(state, 0x36);
@@ -212,7 +223,8 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
for(i=0; i< cmd->msg_len; i++) {
tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
}
- tda10086_write_byte(state, 0x36, 0x88 | ((cmd->msg_len - 1) << 4));
+ tda10086_write_byte(state, 0x36, (0x08 + t22k_off)
+ | ((cmd->msg_len - 1) << 4));
tda10086_diseqc_wait(state);
@@ -225,16 +237,20 @@ static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minic
{
struct tda10086_state* state = fe->demodulator_priv;
u8 oldval = tda10086_read_byte(state, 0x36);
+ u8 t22k_off = 0x80;
dprintk ("%s\n", __FUNCTION__);
+ if (state->config->diseqc_tone)
+ t22k_off = 0;
+
switch(minicmd) {
case SEC_MINI_A:
- tda10086_write_byte(state, 0x36, 0x84);
+ tda10086_write_byte(state, 0x36, 0x04 + t22k_off);
break;
case SEC_MINI_B:
- tda10086_write_byte(state, 0x36, 0x86);
+ tda10086_write_byte(state, 0x36, 0x06 + t22k_off);
break;
}
diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h
index ed584a8f4a8..eeceaeee78f 100644
--- a/drivers/media/dvb/frontends/tda10086.h
+++ b/drivers/media/dvb/frontends/tda10086.h
@@ -33,6 +33,9 @@ struct tda10086_config
/* does the "inversion" need inverted? */
u8 invert;
+
+ /* do we need the diseqc signal with carrier? */
+ u8 diseqc_tone;
};
#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE))
diff --git a/drivers/media/dvb/frontends/tda18271-common.c b/drivers/media/dvb/frontends/tda18271-common.c
index cebb6b90b7e..bca57099061 100644
--- a/drivers/media/dvb/frontends/tda18271-common.c
+++ b/drivers/media/dvb/frontends/tda18271-common.c
@@ -171,7 +171,7 @@ int tda18271_read_extended(struct dvb_frontend *fe)
if (ret != 2)
tda_err("ERROR: i2c_transfer returned: %d\n", ret);
- for (i = 0; i <= TDA18271_NUM_REGS; i++) {
+ for (i = 0; i < TDA18271_NUM_REGS; i++) {
/* don't update write-only registers */
if ((i != R_EB9) &&
(i != R_EB16) &&
diff --git a/drivers/media/dvb/frontends/xc5000.h b/drivers/media/dvb/frontends/xc5000.h
index e0e84562aed..32a5f1c86a1 100644
--- a/drivers/media/dvb/frontends/xc5000.h
+++ b/drivers/media/dvb/frontends/xc5000.h
@@ -45,7 +45,8 @@ struct xc5000_config {
/* xc5000 callback command */
#define XC5000_TUNER_RESET 0
-#if defined(CONFIG_DVB_TUNER_XC5000) || defined(CONFIG_DVB_TUNER_XC5000_MODULE)
+#if defined(CONFIG_DVB_TUNER_XC5000) || \
+ (defined(CONFIG_DVB_TUNER_XC5000_MODULE) && defined(MODULE))
extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
struct xc5000_config *cfg);
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index aef6e36d7c5..3e6b650fbb8 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -966,6 +966,7 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x
static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock)
{
int i, n;
+ int progressive = 0;
dprintk(2, "av7110:%p, \n", av7110);
@@ -974,6 +975,14 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
return -EBUSY;
}
+ for (i = 0; i < len - 5; i++) {
+ /* get progressive flag from picture extension */
+ if (buf[i] == 0x00 && buf[i+1] == 0x00 &&
+ buf[i+2] == 0x01 && (unsigned char)buf[i+3] == 0xb5 &&
+ (buf[i+4] & 0xf0) == 0x10)
+ progressive = buf[i+5] & 0x08;
+ }
+
/* setting n always > 1, fixes problems when playing stillframes
consisting of I- and P-Frames */
n = MIN_IFRAME / len + 1;
@@ -985,7 +994,11 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
dvb_play(av7110, buf, len, 0, 1);
av7110_ipack_flush(&av7110->ipack[1]);
- return 0;
+
+ if (progressive)
+ return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
+ else
+ return 0;
}
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 3439c9864f6..2d64d557b97 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -896,6 +896,7 @@ static u8 read_pwm(struct budget_av *budget_av)
#define SUBID_DVBS_CINERGY1200 0x1154
#define SUBID_DVBS_CYNERGY1200N 0x1155
#define SUBID_DVBS_TV_STAR 0x0014
+#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015
#define SUBID_DVBS_TV_STAR_CI 0x0016
#define SUBID_DVBS_EASYWATCH_1 0x001a
#define SUBID_DVBS_EASYWATCH_2 0x001b
@@ -910,6 +911,7 @@ static u8 read_pwm(struct budget_av *budget_av)
#define SUBID_DVBC_CINERGY1200 0x1156
#define SUBID_DVBC_CINERGY1200_MK3 0x1176
+#define SUBID_DVBT_EASYWATCH 0x003a
#define SUBID_DVBT_KNC1_PLUS 0x0031
#define SUBID_DVBT_KNC1 0x0030
#define SUBID_DVBT_CINERGY1200 0x1157
@@ -957,6 +959,7 @@ static void frontend_init(struct budget_av *budget_av)
break;
case SUBID_DVBS_TV_STAR:
+ case SUBID_DVBS_TV_STAR_PLUS_X4:
case SUBID_DVBS_TV_STAR_CI:
case SUBID_DVBS_CYNERGY1200N:
case SUBID_DVBS_EASYWATCH:
@@ -1018,6 +1021,7 @@ static void frontend_init(struct budget_av *budget_av)
}
break;
+ case SUBID_DVBT_EASYWATCH:
case SUBID_DVBT_KNC1:
case SUBID_DVBT_KNC1_PLUS:
case SUBID_DVBT_CINERGY1200:
@@ -1248,7 +1252,9 @@ MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
+MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
+MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
@@ -1266,12 +1272,14 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
+ MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
+ MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 9268a82bada..14b00f57b5d 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -351,6 +351,7 @@ static struct s5h1420_config s5h1420_config = {
static struct tda10086_config tda10086_config = {
.demod_address = 0x0e,
.invert = 0,
+ .diseqc_tone = 1,
};
static u8 read_pwm(struct budget* budget)
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 8d5214f18cf..1b41b3f77cf 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -4,12 +4,12 @@
menuconfig RADIO_ADAPTERS
bool "Radio Adapters"
- depends on VIDEO_DEV
+ depends on VIDEO_V4L2
default y
---help---
Say Y here to enable selecting AM/FM radio adapters.
-if RADIO_ADAPTERS && VIDEO_DEV
+if RADIO_ADAPTERS && VIDEO_V4L2
config RADIO_CADET
tristate "ADS Cadet AM/FM Tuner"
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 3118bdab318..53e11485737 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -361,6 +361,7 @@ static int __init fmi_init(void)
}
if (!request_region(io, 2, "radio-sf16fmi")) {
printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io);
+ pnp_device_detach(dev);
return -EBUSY;
}
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index f7c8b000404..ebc5fbbc38b 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -470,9 +470,8 @@ static int __init fmr2_init(void)
mutex_init(&lock);
- if (request_region(io, 2, "sf16fmr2"))
- {
- printk(KERN_ERR "fmr2: port 0x%x already in use\n", io);
+ if (!request_region(io, 2, "sf16fmr2")) {
+ printk(KERN_ERR "radio-sf16fmr2: request_region failed!\n");
return -EBUSY;
}
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 8e4bd476904..649f14d2c01 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -62,6 +62,29 @@
* - code cleaned of unnecessary rds_commands
* - USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
* (thanks to Guillaume RAMOUSSE)
+ * 2008-01-27 Tobias Lorenz <tobias.lorenz@gmx.net>
+ * Version 1.0.5
+ * - number of seek_retries changed to tune_timeout
+ * - fixed problem with incomplete tune operations by own buffers
+ * - optimization of variables and printf types
+ * - improved error logging
+ * 2008-01-31 Tobias Lorenz <tobias.lorenz@gmx.net>
+ * Oliver Neukum <oliver@neukum.org>
+ * Version 1.0.6
+ * - fixed coverity checker warnings in *_usb_driver_disconnect
+ * - probe()/open() race by correct ordering in probe()
+ * - DMA coherency rules by separate allocation of all buffers
+ * - use of endianness macros
+ * - abuse of spinlock, replaced by mutex
+ * - racy handling of timer in disconnect,
+ * replaced by delayed_work
+ * - racy interruptible_sleep_on(),
+ * replaced with wait_event_interruptible()
+ * - handle signals in read()
+ * 2008-02-08 Tobias Lorenz <tobias.lorenz@gmx.net>
+ * Oliver Neukum <oliver@neukum.org>
+ * Version 1.0.7
+ * - usb autosuspend support
*
* ToDo:
* - add seeking support
@@ -74,9 +97,10 @@
/* driver definitions */
#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
#define DRIVER_NAME "radio-si470x"
-#define DRIVER_VERSION KERNEL_VERSION(1, 0, 4)
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 6)
#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
+#define DRIVER_VERSION "1.0.6"
/* kernel includes */
@@ -89,8 +113,10 @@
#include <linux/hid.h>
#include <linux/version.h>
#include <linux/videodev2.h>
+#include <linux/mutex.h>
#include <media/v4l2-common.h>
#include <media/rds.h>
+#include <asm/unaligned.h>
/* USB Device ID List */
@@ -119,56 +145,56 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr");
/* 0: 200 kHz (USA, Australia) */
/* 1: 100 kHz (Europe, Japan) */
/* 2: 50 kHz */
-static int space = 2;
-module_param(space, int, 0);
+static unsigned short space = 2;
+module_param(space, ushort, 0);
MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
/* Bottom of Band (MHz) */
/* 0: 87.5 - 108 MHz (USA, Europe)*/
/* 1: 76 - 108 MHz (Japan wide band) */
/* 2: 76 - 90 MHz (Japan) */
-static int band = 1;
-module_param(band, int, 0);
+static unsigned short band = 1;
+module_param(band, ushort, 0);
MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
/* De-emphasis */
/* 0: 75 us (USA) */
/* 1: 50 us (Europe, Australia, Japan) */
-static int de = 1;
-module_param(de, int, 0);
+static unsigned short de = 1;
+module_param(de, ushort, 0);
MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*");
/* USB timeout */
-static int usb_timeout = 500;
-module_param(usb_timeout, int, 0);
+static unsigned int usb_timeout = 500;
+module_param(usb_timeout, uint, 0);
MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
-/* Seek retries */
-static int seek_retries = 100;
-module_param(seek_retries, int, 0);
-MODULE_PARM_DESC(seek_retries, "Seek retries: *100*");
+/* Tune timeout */
+static unsigned int tune_timeout = 3000;
+module_param(tune_timeout, uint, 0);
+MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
/* RDS buffer blocks */
-static int rds_buf = 100;
-module_param(rds_buf, int, 0);
+static unsigned int rds_buf = 100;
+module_param(rds_buf, uint, 0);
MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
/* RDS maximum block errors */
-static int max_rds_errors = 1;
+static unsigned short max_rds_errors = 1;
/* 0 means 0 errors requiring correction */
/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */
/* 2 means 3-5 errors requiring correction */
/* 3 means 6+ errors or errors in checkword, correction not possible */
-module_param(max_rds_errors, int, 0);
+module_param(max_rds_errors, ushort, 0);
MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
/* RDS poll frequency */
-static int rds_poll_time = 40;
+static unsigned int rds_poll_time = 40;
/* 40 is used by the original USBRadio.exe */
/* 50 is used by radio-cadet */
/* 75 should be okay */
/* 80 is the usual RDS receive interval */
-module_param(rds_poll_time, int, 0);
+module_param(rds_poll_time, uint, 0);
MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
@@ -393,22 +419,19 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
struct si470x_device {
/* reference to USB and video device */
struct usb_device *usbdev;
+ struct usb_interface *intf;
struct video_device *videodev;
- /* are these really necessary ? */
- int users;
-
- /* report buffer (maximum 64 bytes) */
- unsigned char buf[64];
+ /* driver management */
+ unsigned int users;
/* Silabs internal registers (0..15) */
unsigned short registers[RADIO_REGISTER_NUM];
/* RDS receive buffer */
- struct work_struct work;
+ struct delayed_work work;
wait_queue_head_t read_queue;
- struct timer_list timer;
- spinlock_t lock; /* buffer locking */
+ struct mutex lock; /* buffer locking */
unsigned char *buffer; /* size is always multiple of three */
unsigned int buf_size;
unsigned int rd_index;
@@ -434,28 +457,46 @@ struct si470x_device {
/*
* si470x_get_report - receive a HID report
*/
-static int si470x_get_report(struct si470x_device *radio, int size)
+static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
{
- return usb_control_msg(radio->usbdev,
+ unsigned char *report = (unsigned char *) buf;
+ int retval;
+
+ retval = usb_control_msg(radio->usbdev,
usb_rcvctrlpipe(radio->usbdev, 0),
HID_REQ_GET_REPORT,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- radio->buf[0], 2,
- radio->buf, size, usb_timeout);
+ report[0], 2,
+ buf, size, usb_timeout);
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": si470x_get_report: usb_control_msg returned %d\n",
+ retval);
+
+ return retval;
}
/*
* si470x_set_report - send a HID report
*/
-static int si470x_set_report(struct si470x_device *radio, int size)
+static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
{
- return usb_control_msg(radio->usbdev,
+ unsigned char *report = (unsigned char *) buf;
+ int retval;
+
+ retval = usb_control_msg(radio->usbdev,
usb_sndctrlpipe(radio->usbdev, 0),
HID_REQ_SET_REPORT,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
- radio->buf[0], 2,
- radio->buf, size, usb_timeout);
+ report[0], 2,
+ buf, size, usb_timeout);
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": si470x_set_report: usb_control_msg returned %d\n",
+ retval);
+
+ return retval;
}
@@ -464,13 +505,16 @@ static int si470x_set_report(struct si470x_device *radio, int size)
*/
static int si470x_get_register(struct si470x_device *radio, int regnr)
{
+ unsigned char buf[REGISTER_REPORT_SIZE];
int retval;
- radio->buf[0] = REGISTER_REPORT(regnr);
+ buf[0] = REGISTER_REPORT(regnr);
+
+ retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
- retval = si470x_get_report(radio, REGISTER_REPORT_SIZE);
if (retval >= 0)
- radio->registers[regnr] = (radio->buf[1] << 8) | radio->buf[2];
+ radio->registers[regnr] = be16_to_cpu(get_unaligned(
+ (unsigned short *) &buf[1]));
return (retval < 0) ? -EINVAL : 0;
}
@@ -481,13 +525,14 @@ static int si470x_get_register(struct si470x_device *radio, int regnr)
*/
static int si470x_set_register(struct si470x_device *radio, int regnr)
{
+ unsigned char buf[REGISTER_REPORT_SIZE];
int retval;
- radio->buf[0] = REGISTER_REPORT(regnr);
- radio->buf[1] = (radio->registers[regnr] & 0xff00) >> 8;
- radio->buf[2] = (radio->registers[regnr] & 0x00ff);
+ buf[0] = REGISTER_REPORT(regnr);
+ put_unaligned(cpu_to_be16(radio->registers[regnr]),
+ (unsigned short *) &buf[1]);
- retval = si470x_set_report(radio, REGISTER_REPORT_SIZE);
+ retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
return (retval < 0) ? -EINVAL : 0;
}
@@ -498,18 +543,19 @@ static int si470x_set_register(struct si470x_device *radio, int regnr)
*/
static int si470x_get_all_registers(struct si470x_device *radio)
{
+ unsigned char buf[ENTIRE_REPORT_SIZE];
int retval;
- int regnr;
+ unsigned char regnr;
- radio->buf[0] = ENTIRE_REPORT;
+ buf[0] = ENTIRE_REPORT;
- retval = si470x_get_report(radio, ENTIRE_REPORT_SIZE);
+ retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
if (retval >= 0)
for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
- radio->registers[regnr] =
- (radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) |
- radio->buf[regnr * RADIO_REGISTER_SIZE + 2];
+ radio->registers[regnr] = be16_to_cpu(get_unaligned(
+ (unsigned short *)
+ &buf[regnr * RADIO_REGISTER_SIZE + 1]));
return (retval < 0) ? -EINVAL : 0;
}
@@ -520,21 +566,28 @@ static int si470x_get_all_registers(struct si470x_device *radio)
*/
static int si470x_get_rds_registers(struct si470x_device *radio)
{
+ unsigned char buf[RDS_REPORT_SIZE];
int retval;
- int regnr;
int size;
+ unsigned char regnr;
- radio->buf[0] = RDS_REPORT;
+ buf[0] = RDS_REPORT;
retval = usb_interrupt_msg(radio->usbdev,
- usb_rcvctrlpipe(radio->usbdev, 1),
- radio->buf, RDS_REPORT_SIZE, &size, usb_timeout);
+ usb_rcvintpipe(radio->usbdev, 1),
+ (void *) &buf, sizeof(buf), &size, usb_timeout);
+ if (size != sizeof(buf))
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: "
+ "return size differs: %d != %zu\n", size, sizeof(buf));
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+ "usb_interrupt_msg returned %d\n", retval);
if (retval >= 0)
for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
radio->registers[STATUSRSSI + regnr] =
- (radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) |
- radio->buf[regnr * RADIO_REGISTER_SIZE + 2];
+ be16_to_cpu(get_unaligned((unsigned short *)
+ &buf[regnr * RADIO_REGISTER_SIZE + 1]));
return (retval < 0) ? -EINVAL : 0;
}
@@ -543,9 +596,11 @@ static int si470x_get_rds_registers(struct si470x_device *radio)
/*
* si470x_set_chan - set the channel
*/
-static int si470x_set_chan(struct si470x_device *radio, int chan)
+static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
{
- int retval, i;
+ int retval;
+ unsigned long timeout;
+ bool timed_out = 0;
/* start tuning */
radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
@@ -555,16 +610,17 @@ static int si470x_set_chan(struct si470x_device *radio, int chan)
return retval;
/* wait till seek operation has completed */
- i = 0;
+ timeout = jiffies + msecs_to_jiffies(tune_timeout);
do {
retval = si470x_get_register(radio, STATUSRSSI);
if (retval < 0)
return retval;
- } while ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) &&
- (++i < seek_retries));
- if (i >= seek_retries)
+ timed_out = time_after(jiffies, timeout);
+ } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
+ (!timed_out));
+ if (timed_out)
printk(KERN_WARNING DRIVER_NAME
- ": seek does not finish after %d tries\n", i);
+ ": seek does not finish after %u ms\n", tune_timeout);
/* stop tuning */
radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
@@ -575,9 +631,10 @@ static int si470x_set_chan(struct si470x_device *radio, int chan)
/*
* si470x_get_freq - get the frequency
*/
-static int si470x_get_freq(struct si470x_device *radio)
+static unsigned int si470x_get_freq(struct si470x_device *radio)
{
- int spacing, band_bottom, chan, freq;
+ unsigned int spacing, band_bottom, freq;
+ unsigned short chan;
int retval;
/* Spacing (kHz) */
@@ -616,9 +673,10 @@ static int si470x_get_freq(struct si470x_device *radio)
/*
* si470x_set_freq - set the frequency
*/
-static int si470x_set_freq(struct si470x_device *radio, int freq)
+static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
{
- int spacing, band_bottom, chan;
+ unsigned int spacing, band_bottom;
+ unsigned short chan;
/* Spacing (kHz) */
switch (space) {
@@ -709,9 +767,17 @@ static int si470x_stop(struct si470x_device *radio)
*/
static int si470x_rds_on(struct si470x_device *radio)
{
+ int retval;
+
/* sysconfig 1 */
+ mutex_lock(&radio->lock);
radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
- return si470x_set_register(radio, SYSCONFIG1);
+ retval = si470x_set_register(radio, SYSCONFIG1);
+ if (retval < 0)
+ radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
+ mutex_unlock(&radio->lock);
+
+ return retval;
}
@@ -725,11 +791,10 @@ static int si470x_rds_on(struct si470x_device *radio)
*/
static void si470x_rds(struct si470x_device *radio)
{
- unsigned char tmpbuf[3];
unsigned char blocknum;
- unsigned char bler; /* rds block errors */
+ unsigned short bler; /* rds block errors */
unsigned short rds;
- unsigned int i;
+ unsigned char tmpbuf[3];
/* get rds blocks */
if (si470x_get_rds_registers(radio) < 0)
@@ -743,63 +808,58 @@ static void si470x_rds(struct si470x_device *radio)
return;
}
- /* copy four RDS blocks to internal buffer */
- if (spin_trylock(&radio->lock)) {
- /* process each rds block */
- for (blocknum = 0; blocknum < 4; blocknum++) {
- switch (blocknum) {
- default:
- bler = (radio->registers[STATUSRSSI] &
- STATUSRSSI_BLERA) >> 9;
- rds = radio->registers[RDSA];
- break;
- case 1:
- bler = (radio->registers[READCHAN] &
- READCHAN_BLERB) >> 14;
- rds = radio->registers[RDSB];
- break;
- case 2:
- bler = (radio->registers[READCHAN] &
- READCHAN_BLERC) >> 12;
- rds = radio->registers[RDSC];
- break;
- case 3:
- bler = (radio->registers[READCHAN] &
- READCHAN_BLERD) >> 10;
- rds = radio->registers[RDSD];
- break;
- };
-
- /* Fill the V4L2 RDS buffer */
- tmpbuf[0] = rds & 0x00ff; /* LSB */
- tmpbuf[1] = (rds & 0xff00) >> 8;/* MSB */
- tmpbuf[2] = blocknum; /* offset name */
- tmpbuf[2] |= blocknum << 3; /* received offset */
- if (bler > max_rds_errors)
- tmpbuf[2] |= 0x80; /* uncorrectable errors */
- else if (bler > 0)
- tmpbuf[2] |= 0x40; /* corrected error(s) */
-
- /* copy RDS block to internal buffer */
- for (i = 0; i < 3; i++) {
- radio->buffer[radio->wr_index] = tmpbuf[i];
- radio->wr_index++;
- }
-
- /* wrap write pointer */
- if (radio->wr_index >= radio->buf_size)
- radio->wr_index = 0;
-
- /* check for overflow */
- if (radio->wr_index == radio->rd_index) {
- /* increment and wrap read pointer */
- radio->rd_index += 3;
- if (radio->rd_index >= radio->buf_size)
- radio->rd_index = 0;
- }
+ /* copy all four RDS blocks to internal buffer */
+ mutex_lock(&radio->lock);
+ for (blocknum = 0; blocknum < 4; blocknum++) {
+ switch (blocknum) {
+ default:
+ bler = (radio->registers[STATUSRSSI] &
+ STATUSRSSI_BLERA) >> 9;
+ rds = radio->registers[RDSA];
+ break;
+ case 1:
+ bler = (radio->registers[READCHAN] &
+ READCHAN_BLERB) >> 14;
+ rds = radio->registers[RDSB];
+ break;
+ case 2:
+ bler = (radio->registers[READCHAN] &
+ READCHAN_BLERC) >> 12;
+ rds = radio->registers[RDSC];
+ break;
+ case 3:
+ bler = (radio->registers[READCHAN] &
+ READCHAN_BLERD) >> 10;
+ rds = radio->registers[RDSD];
+ break;
+ };
+
+ /* Fill the V4L2 RDS buffer */
+ put_unaligned(cpu_to_le16(rds), (unsigned short *) &tmpbuf);
+ tmpbuf[2] = blocknum; /* offset name */
+ tmpbuf[2] |= blocknum << 3; /* received offset */
+ if (bler > max_rds_errors)
+ tmpbuf[2] |= 0x80; /* uncorrectable errors */
+ else if (bler > 0)
+ tmpbuf[2] |= 0x40; /* corrected error(s) */
+
+ /* copy RDS block to internal buffer */
+ memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
+ radio->wr_index += 3;
+
+ /* wrap write pointer */
+ if (radio->wr_index >= radio->buf_size)
+ radio->wr_index = 0;
+
+ /* check for overflow */
+ if (radio->wr_index == radio->rd_index) {
+ /* increment and wrap read pointer */
+ radio->rd_index += 3;
+ if (radio->rd_index >= radio->buf_size)
+ radio->rd_index = 0;
}
- spin_unlock(&radio->lock);
}
+ mutex_unlock(&radio->lock);
/* wake up read queue */
if (radio->wr_index != radio->rd_index)
@@ -808,29 +868,18 @@ static void si470x_rds(struct si470x_device *radio)
/*
- * si470x_timer - rds timer function
- */
-static void si470x_timer(unsigned long data)
-{
- struct si470x_device *radio = (struct si470x_device *) data;
-
- schedule_work(&radio->work);
-}
-
-
-/*
* si470x_work - rds work function
*/
static void si470x_work(struct work_struct *work)
{
struct si470x_device *radio = container_of(work, struct si470x_device,
- work);
+ work.work);
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
return;
si470x_rds(radio);
- mod_timer(&radio->timer, jiffies + msecs_to_jiffies(rds_poll_time));
+ schedule_delayed_work(&radio->work, msecs_to_jiffies(rds_poll_time));
}
@@ -852,44 +901,44 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
/* switch on rds reception */
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
si470x_rds_on(radio);
- schedule_work(&radio->work);
+ schedule_delayed_work(&radio->work,
+ msecs_to_jiffies(rds_poll_time));
}
/* block if no new data available */
while (radio->wr_index == radio->rd_index) {
if (file->f_flags & O_NONBLOCK)
return -EWOULDBLOCK;
- interruptible_sleep_on(&radio->read_queue);
+ if (wait_event_interruptible(radio->read_queue,
+ radio->wr_index != radio->rd_index) < 0)
+ return -EINTR;
}
/* calculate block count from byte count */
count /= 3;
/* copy RDS block out of internal buffer and to user buffer */
- if (spin_trylock(&radio->lock)) {
- while (block_count < count) {
- if (radio->rd_index == radio->wr_index)
- break;
-
- /* always transfer rds complete blocks */
- if (copy_to_user(buf,
- &radio->buffer[radio->rd_index], 3))
- /* retval = -EFAULT; */
- break;
-
- /* increment and wrap read pointer */
- radio->rd_index += 3;
- if (radio->rd_index >= radio->buf_size)
- radio->rd_index = 0;
-
- /* increment counters */
- block_count++;
- buf += 3;
- retval += 3;
- }
-
- spin_unlock(&radio->lock);
+ mutex_lock(&radio->lock);
+ while (block_count < count) {
+ if (radio->rd_index == radio->wr_index)
+ break;
+
+ /* always transfer rds complete blocks */
+ if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
+ /* retval = -EFAULT; */
+ break;
+
+ /* increment and wrap read pointer */
+ radio->rd_index += 3;
+ if (radio->rd_index >= radio->buf_size)
+ radio->rd_index = 0;
+
+ /* increment counters */
+ block_count++;
+ buf += 3;
+ retval += 3;
}
+ mutex_unlock(&radio->lock);
return retval;
}
@@ -906,7 +955,8 @@ static unsigned int si470x_fops_poll(struct file *file,
/* switch on rds reception */
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
si470x_rds_on(radio);
- schedule_work(&radio->work);
+ schedule_delayed_work(&radio->work,
+ msecs_to_jiffies(rds_poll_time));
}
poll_wait(file, &radio->read_queue, pts);
@@ -924,10 +974,22 @@ static unsigned int si470x_fops_poll(struct file *file,
static int si470x_fops_open(struct inode *inode, struct file *file)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
radio->users++;
- if (radio->users == 1)
- return si470x_start(radio);
+
+ retval = usb_autopm_get_interface(radio->intf);
+ if (retval < 0) {
+ radio->users--;
+ return -EIO;
+ }
+
+ if (radio->users == 1) {
+ retval = si470x_start(radio);
+ if (retval < 0)
+ usb_autopm_put_interface(radio->intf);
+ return retval;
+ }
return 0;
}
@@ -939,6 +1001,7 @@ static int si470x_fops_open(struct inode *inode, struct file *file)
static int si470x_fops_release(struct inode *inode, struct file *file)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
if (!radio)
return -ENODEV;
@@ -946,13 +1009,14 @@ static int si470x_fops_release(struct inode *inode, struct file *file)
radio->users--;
if (radio->users == 0) {
/* stop rds reception */
- del_timer_sync(&radio->timer);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&radio->work);
/* cancel read processes */
wake_up_interruptible(&radio->read_queue);
- return si470x_stop(radio);
+ retval = si470x_stop(radio);
+ usb_autopm_put_interface(radio->intf);
+ return retval;
}
return 0;
@@ -1030,7 +1094,7 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
sprintf(capability->bus_info, "USB");
- capability->version = DRIVER_VERSION;
+ capability->version = DRIVER_KERNEL_VERSION;
capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
@@ -1067,16 +1131,21 @@ static int si470x_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
static int si470x_vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
+ unsigned char i;
+ int retval = -EINVAL;
for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) {
memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
- return 0;
+ retval = 0;
+ break;
}
}
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": query control failed with %d\n", retval);
- return -EINVAL;
+ return retval;
}
@@ -1110,21 +1179,29 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME:
radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
radio->registers[SYSCONFIG2] |= ctrl->value;
- return si470x_set_register(radio, SYSCONFIG2);
+ retval = si470x_set_register(radio, SYSCONFIG2);
+ break;
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value == 1)
radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
else
radio->registers[POWERCFG] |= POWERCFG_DMUTE;
- return si470x_set_register(radio, POWERCFG);
+ retval = si470x_set_register(radio, POWERCFG);
+ break;
+ default:
+ retval = -EINVAL;
}
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": set control failed with %d\n", retval);
- return -EINVAL;
+ return retval;
}
@@ -1163,8 +1240,8 @@ static int si470x_vidioc_s_audio(struct file *file, void *priv,
static int si470x_vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *tuner)
{
- int retval;
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
if (tuner->index > 0)
return -EINVAL;
@@ -1220,6 +1297,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *tuner)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
if (tuner->index > 0)
return -EINVAL;
@@ -1229,7 +1307,12 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
else
radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
- return si470x_set_register(radio, POWERCFG);
+ retval = si470x_set_register(radio, POWERCFG);
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": set tuner failed with %d\n", retval);
+
+ return retval;
}
@@ -1255,11 +1338,17 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *freq)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
if (freq->type != V4L2_TUNER_RADIO)
return -EINVAL;
- return si470x_set_freq(radio, freq->frequency);
+ retval = si470x_set_freq(radio, freq->frequency);
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": set frequency failed with %d\n", retval);
+
+ return 0;
}
@@ -1299,71 +1388,116 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct si470x_device *radio;
+ int retval = -ENOMEM;
- /* memory and interface allocations */
- radio = kmalloc(sizeof(struct si470x_device), GFP_KERNEL);
+ /* private data allocation */
+ radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
if (!radio)
- return -ENOMEM;
+ goto err_initial;
+
+ /* video device allocation */
radio->videodev = video_device_alloc();
- if (!radio->videodev) {
- kfree(radio);
- return -ENOMEM;
- }
+ if (!radio->videodev)
+ goto err_radio;
+
+ /* initial configuration */
memcpy(radio->videodev, &si470x_viddev_template,
sizeof(si470x_viddev_template));
radio->users = 0;
radio->usbdev = interface_to_usbdev(intf);
+ radio->intf = intf;
+ mutex_init(&radio->lock);
video_set_drvdata(radio->videodev, radio);
- if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
- printk(KERN_WARNING DRIVER_NAME
- ": Could not register video device\n");
- video_device_release(radio->videodev);
- kfree(radio);
- return -EIO;
- }
- usb_set_intfdata(intf, radio);
/* show some infos about the specific device */
- if (si470x_get_all_registers(radio) < 0) {
- video_device_release(radio->videodev);
- kfree(radio);
- return -EIO;
- }
- printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4x ChipID=0x%4.4x\n",
+ retval = -EIO;
+ if (si470x_get_all_registers(radio) < 0)
+ goto err_all;
+ printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
radio->registers[DEVICEID], radio->registers[CHIPID]);
/* check if firmware is current */
if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
- < RADIO_SW_VERSION_CURRENT)
+ < RADIO_SW_VERSION_CURRENT) {
+ printk(KERN_WARNING DRIVER_NAME
+ ": This driver is known to work with "
+ "firmware version %hu,\n", RADIO_SW_VERSION_CURRENT);
+ printk(KERN_WARNING DRIVER_NAME
+ ": but the device has firmware version %hu.\n",
+ radio->registers[CHIPID] & CHIPID_FIRMWARE);
+ printk(KERN_WARNING DRIVER_NAME
+ ": If you have some trouble using this driver,\n");
printk(KERN_WARNING DRIVER_NAME
- ": This driver is known to work with chip version %d, "
- "but the device has firmware %d.\n"
- DRIVER_NAME
- "If you have some trouble using this driver, please "
- "report to V4L ML at video4linux-list@redhat.com\n",
- radio->registers[CHIPID] & CHIPID_FIRMWARE,
- RADIO_SW_VERSION_CURRENT);
+ ": please report to V4L ML at "
+ "video4linux-list@redhat.com\n");
+ }
/* set initial frequency */
si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
- /* rds initialization */
+ /* rds buffer allocation */
radio->buf_size = rds_buf * 3;
radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
- if (!radio->buffer) {
- video_device_release(radio->videodev);
- kfree(radio);
- return -ENOMEM;
- }
+ if (!radio->buffer)
+ goto err_all;
+
+ /* rds buffer configuration */
radio->wr_index = 0;
radio->rd_index = 0;
init_waitqueue_head(&radio->read_queue);
- /* prepare polling via eventd */
- INIT_WORK(&radio->work, si470x_work);
- init_timer(&radio->timer);
- radio->timer.function = si470x_timer;
- radio->timer.data = (unsigned long) radio;
+ /* prepare rds work function */
+ INIT_DELAYED_WORK(&radio->work, si470x_work);
+
+ /* register video device */
+ if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
+ printk(KERN_WARNING DRIVER_NAME
+ ": Could not register video device\n");
+ goto err_all;
+ }
+ usb_set_intfdata(intf, radio);
+
+ return 0;
+err_all:
+ video_device_release(radio->videodev);
+ kfree(radio->buffer);
+err_radio:
+ kfree(radio);
+err_initial:
+ return retval;
+}
+
+
+/*
+ * si470x_usb_driver_suspend - suspend the device
+ */
+static int si470x_usb_driver_suspend(struct usb_interface *intf,
+ pm_message_t message)
+{
+ struct si470x_device *radio = usb_get_intfdata(intf);
+
+ printk(KERN_INFO DRIVER_NAME ": suspending now...\n");
+
+ cancel_delayed_work_sync(&radio->work);
+
+ return 0;
+}
+
+
+/*
+ * si470x_usb_driver_resume - resume the device
+ */
+static int si470x_usb_driver_resume(struct usb_interface *intf)
+{
+ struct si470x_device *radio = usb_get_intfdata(intf);
+
+ printk(KERN_INFO DRIVER_NAME ": resuming now...\n");
+
+ mutex_lock(&radio->lock);
+ if (radio->users && radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS)
+ schedule_delayed_work(&radio->work,
+ msecs_to_jiffies(rds_poll_time));
+ mutex_unlock(&radio->lock);
return 0;
}
@@ -1376,15 +1510,11 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
{
struct si470x_device *radio = usb_get_intfdata(intf);
- del_timer_sync(&radio->timer);
- flush_scheduled_work();
-
+ cancel_delayed_work_sync(&radio->work);
usb_set_intfdata(intf, NULL);
- if (radio) {
- video_unregister_device(radio->videodev);
- kfree(radio->buffer);
- kfree(radio);
- }
+ video_unregister_device(radio->videodev);
+ kfree(radio->buffer);
+ kfree(radio);
}
@@ -1392,10 +1522,13 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
* si470x_usb_driver - usb driver interface
*/
static struct usb_driver si470x_usb_driver = {
- .name = DRIVER_NAME,
- .probe = si470x_usb_driver_probe,
- .disconnect = si470x_usb_driver_disconnect,
- .id_table = si470x_usb_driver_id_table,
+ .name = DRIVER_NAME,
+ .probe = si470x_usb_driver_probe,
+ .disconnect = si470x_usb_driver_disconnect,
+ .suspend = si470x_usb_driver_suspend,
+ .resume = si470x_usb_driver_resume,
+ .id_table = si470x_usb_driver_id_table,
+ .supports_autosuspend = 1,
};
@@ -1409,7 +1542,7 @@ static struct usb_driver si470x_usb_driver = {
*/
static int __init si470x_module_init(void)
{
- printk(KERN_INFO DRIVER_DESC "\n");
+ printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
return usb_register(&si470x_usb_driver);
}
@@ -1429,4 +1562,4 @@ module_exit(si470x_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION("1.0.4");
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index a2e8987a619..37072a21d8c 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -4,14 +4,14 @@
menuconfig VIDEO_CAPTURE_DRIVERS
bool "Video capture adapters"
- depends on VIDEO_DEV
+ depends on VIDEO_V4L2
default y
---help---
Say Y here to enable selecting the video adapters for
webcams, analog TV, and hybrid analog/digital TV.
Some of those devices also supports FM radio.
-if VIDEO_CAPTURE_DRIVERS && VIDEO_DEV
+if VIDEO_CAPTURE_DRIVERS && VIDEO_V4L2
config VIDEO_ADV_DEBUG
bool "Enable advanced debug functionality"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 850b8c6f457..3f209b32eea 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -10,8 +10,9 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o
stkwebcam-objs := stk-webcam.o stk-sensor.o
-obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o \
- v4l2-int-device.o
+obj-$(CONFIG_VIDEO_DEV) += videodev.o compat_ioctl32.o v4l2-int-device.o
+
+obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 907dc62c178..5404fcc5276 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -2354,8 +2354,8 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
BUG();
}
- mutex_lock(&fh->cap.lock);
- kfree(fh->ov.clips);
+ mutex_lock(&fh->cap.vb_lock);
+ kfree(fh->ov.clips);
fh->ov.clips = clips;
fh->ov.nclips = n;
@@ -2376,7 +2376,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
retval = bttv_switch_overlay(btv,fh,new);
}
- mutex_unlock(&fh->cap.lock);
+ mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -2576,7 +2576,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
/* update our state informations */
- mutex_lock(&fh->cap.lock);
+ mutex_lock(&fh->cap.vb_lock);
fh->fmt = fmt;
fh->cap.field = f->fmt.pix.field;
fh->cap.last = V4L2_FIELD_NONE;
@@ -2585,7 +2585,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
btv->init.fmt = fmt;
btv->init.width = f->fmt.pix.width;
btv->init.height = f->fmt.pix.height;
- mutex_unlock(&fh->cap.lock);
+ mutex_unlock(&fh->cap.vb_lock);
return 0;
}
@@ -2611,11 +2611,11 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
unsigned int i;
struct bttv_fh *fh = priv;
- mutex_lock(&fh->cap.lock);
+ mutex_lock(&fh->cap.vb_lock);
retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
V4L2_MEMORY_MMAP);
if (retval < 0) {
- mutex_unlock(&fh->cap.lock);
+ mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -2627,7 +2627,7 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
for (i = 0; i < gbuffers; i++)
mbuf->offsets[i] = i * gbufsize;
- mutex_unlock(&fh->cap.lock);
+ mutex_unlock(&fh->cap.vb_lock);
return 0;
}
#endif
@@ -2756,10 +2756,11 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
if (!check_alloc_btres(btv, fh, RESOURCE_OVERLAY))
return -EBUSY;
- mutex_lock(&fh->cap.lock);
+ mutex_lock(&fh->cap.vb_lock);
if (on) {
fh->ov.tvnorm = btv->tvnorm;
new = videobuf_pci_alloc(sizeof(*new));
+ new->crop = btv->crop[!!fh->do_crop].rect;
bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
} else {
new = NULL;
@@ -2767,7 +2768,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
/* switch over */
retval = bttv_switch_overlay(btv, fh, new);
- mutex_unlock(&fh->cap.lock);
+ mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -2806,7 +2807,7 @@ static int bttv_s_fbuf(struct file *file, void *f,
}
/* ok, accept it */
- mutex_lock(&fh->cap.lock);
+ mutex_lock(&fh->cap.vb_lock);
btv->fbuf.base = fb->base;
btv->fbuf.fmt.width = fb->fmt.width;
btv->fbuf.fmt.height = fb->fmt.height;
@@ -2838,7 +2839,7 @@ static int bttv_s_fbuf(struct file *file, void *f,
retval = bttv_switch_overlay(btv, fh, new);
}
}
- mutex_unlock(&fh->cap.lock);
+ mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -3090,7 +3091,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
fh->do_crop = 1;
- mutex_lock(&fh->cap.lock);
+ mutex_lock(&fh->cap.vb_lock);
if (fh->width < c.min_scaled_width) {
fh->width = c.min_scaled_width;
@@ -3108,7 +3109,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
btv->init.height = c.max_scaled_height;
}
- mutex_unlock(&fh->cap.lock);
+ mutex_unlock(&fh->cap.vb_lock);
return 0;
}
@@ -3177,30 +3178,25 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
} else {
/* read() capture */
- mutex_lock(&fh->cap.lock);
+ mutex_lock(&fh->cap.vb_lock);
if (NULL == fh->cap.read_buf) {
/* need to capture a new frame */
- if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) {
- mutex_unlock(&fh->cap.lock);
- return POLLERR;
- }
+ if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM))
+ goto err;
fh->cap.read_buf = videobuf_pci_alloc(fh->cap.msize);
- if (NULL == fh->cap.read_buf) {
- mutex_unlock(&fh->cap.lock);
- return POLLERR;
- }
+ if (NULL == fh->cap.read_buf)
+ goto err;
fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
field = videobuf_next_field(&fh->cap);
if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
kfree (fh->cap.read_buf);
fh->cap.read_buf = NULL;
- mutex_unlock(&fh->cap.lock);
- return POLLERR;
+ goto err;
}
fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
fh->cap.read_off = 0;
}
- mutex_unlock(&fh->cap.lock);
+ mutex_unlock(&fh->cap.vb_lock);
buf = (struct bttv_buffer*)fh->cap.read_buf;
}
@@ -3209,6 +3205,9 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
buf->vb.state == VIDEOBUF_ERROR)
return POLLIN|POLLRDNORM;
return 0;
+err:
+ mutex_unlock(&fh->cap.vb_lock);
+ return POLLERR;
}
static int bttv_open(struct inode *inode, struct file *file)
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
index 1f0cc79e2a3..75fa82c7c73 100644
--- a/drivers/media/video/bt8xx/bttv-vbi.c
+++ b/drivers/media/video/bt8xx/bttv-vbi.c
@@ -352,13 +352,13 @@ int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
because vbi_fmt.end counts field lines times two. */
end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;
- mutex_lock(&fh->vbi.lock);
+ mutex_lock(&fh->vbi.vb_lock);
fh->vbi_fmt.fmt = frt->fmt.vbi;
fh->vbi_fmt.tvnorm = tvnorm;
fh->vbi_fmt.end = end;
- mutex_unlock(&fh->vbi.lock);
+ mutex_unlock(&fh->vbi.vb_lock);
rc = 0;
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 0aedbeaf94c..e357f415db0 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -609,13 +609,19 @@ static int cx8802_request_acquire(struct cx8802_driver *drv)
struct cx88_core *core = drv->core;
/* Fail a request for hardware if the device is busy. */
- if (core->active_type_id != CX88_BOARD_NONE)
+ if (core->active_type_id != CX88_BOARD_NONE &&
+ core->active_type_id != drv->type_id)
return -EBUSY;
if (drv->advise_acquire)
{
- core->active_type_id = drv->type_id;
- drv->advise_acquire(drv);
+ mutex_lock(&drv->core->lock);
+ core->active_ref++;
+ if (core->active_type_id == CX88_BOARD_NONE) {
+ core->active_type_id = drv->type_id;
+ drv->advise_acquire(drv);
+ }
+ mutex_unlock(&drv->core->lock);
mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
}
@@ -628,12 +634,14 @@ static int cx8802_request_release(struct cx8802_driver *drv)
{
struct cx88_core *core = drv->core;
- if (drv->advise_release)
+ mutex_lock(&drv->core->lock);
+ if (drv->advise_release && --core->active_ref == 0)
{
drv->advise_release(drv);
core->active_type_id = CX88_BOARD_NONE;
mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
}
+ mutex_unlock(&drv->core->lock);
return 0;
}
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 4e823f2a539..37e6d2e4002 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -336,6 +336,7 @@ struct cx88_core {
/* cx88-video needs to access cx8802 for hybrid tuner pll access. */
struct cx8802_dev *dvbdev;
enum cx88_board_type active_type_id;
+ int active_ref;
};
struct cx8800_dev;
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 941357c4f3f..8c67f678266 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -35,7 +35,6 @@
#include <linux/vmalloc.h>
#include <linux/proc_fs.h>
#include <linux/module.h>
-#include <sound/driver.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -270,8 +269,11 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
dprintk("opening device and trying to acquire exclusive lock\n");
/* Sets volume, mute, etc */
+
dev->mute = 0;
+ mutex_lock(&dev->lock);
ret = em28xx_audio_analog_set(dev);
+ mutex_unlock(&dev->lock);
if (ret < 0)
goto err;
@@ -303,7 +305,9 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
dprintk("closing device\n");
dev->mute = 1;
+ mutex_lock(&dev->lock);
em28xx_audio_analog_set(dev);
+ mutex_unlock(&dev->lock);
if (dev->adev->users == 0 && dev->adev->shutdown == 1) {
dprintk("audio users: %d\n", dev->adev->users);
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 2159d0160df..aae7753fef1 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -393,15 +393,15 @@ struct em28xx_board em28xx_boards[] = {
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = SAA7115_COMPOSITE2,
- .amux = 1,
+ .amux = EM28XX_AMUX_LINE_IN,
}, {
.type = EM28XX_VMUX_COMPOSITE1,
.vmux = SAA7115_COMPOSITE0,
- .amux = 1,
+ .amux = EM28XX_AMUX_LINE_IN,
}, {
.type = EM28XX_VMUX_SVIDEO,
.vmux = SAA7115_SVIDEO3,
- .amux = 1,
+ .amux = EM28XX_AMUX_LINE_IN,
} },
},
};
@@ -441,6 +441,8 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
{ USB_DEVICE(0x2040, 0x6500),
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
+ { USB_DEVICE(0x2040, 0x6502),
+ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
{ USB_DEVICE(0x2040, 0x6513),
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
{ USB_DEVICE(0x0ccd, 0x0042),
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index f6b78357f0e..7d1537cab86 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -72,7 +72,8 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */
void *buff = NULL;
u32 i;
- em28xx_coredbg("requested %i buffers with size %zi", count, imagesize);
+ em28xx_coredbg("requested %i buffers with size %zi\n",
+ count, imagesize);
if (count > EM28XX_NUM_FRAMES)
count = EM28XX_NUM_FRAMES;
@@ -150,7 +151,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
if (reg_debug){
printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
for (byte = 0; byte < len; byte++) {
- printk(" %02x", buf[byte]);
+ printk(" %02x", (unsigned char)buf[byte]);
}
printk("\n");
}
@@ -177,7 +178,8 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
0x0000, reg, &val, 1, HZ);
if (reg_debug)
- printk(ret < 0 ? " failed!\n" : "%02x\n", val);
+ printk(ret < 0 ? " failed!\n" :
+ "%02x\n", (unsigned char) val);
if (ret < 0)
return ret;
@@ -237,7 +239,7 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
* sets only some bits (specified by bitmask) of a register, by first reading
* the actual value
*/
-int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
u8 bitmask)
{
int oldval;
@@ -254,26 +256,31 @@ int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
*/
static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
{
- int ret;
+ int ret, i;
u8 addr = reg & 0x7f;
if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
return ret;
if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
return ret;
- if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
- return ret;
- else if (((u8) ret) & 0x01) {
- em28xx_warn ("AC97 command still being executed: not handled properly!\n");
+
+ /* Wait up to 50 ms for AC97 command to complete */
+ for (i = 0; i < 10; i++) {
+ if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
+ return ret;
+ if (!((u8) ret) & 0x01)
+ return 0;
+ msleep(5);
}
+ em28xx_warn ("AC97 command still being executed: not handled properly!\n");
return 0;
}
-int em28xx_set_audio_source(struct em28xx *dev)
+static int em28xx_set_audio_source(struct em28xx *dev)
{
static char *enable = "\x08\x08";
static char *disable = "\x08\x88";
char *video = enable, *line = disable;
- int ret, no_ac97;
+ int ret;
u8 input;
if (dev->is_em2800) {
@@ -293,11 +300,9 @@ int em28xx_set_audio_source(struct em28xx *dev)
switch (dev->ctl_ainput) {
case EM28XX_AMUX_VIDEO:
input = EM28XX_AUDIO_SRC_TUNER;
- no_ac97 = 1;
break;
case EM28XX_AMUX_LINE_IN:
input = EM28XX_AUDIO_SRC_LINE;
- no_ac97 = 1;
break;
case EM28XX_AMUX_AC97_VIDEO:
input = EM28XX_AUDIO_SRC_LINE;
@@ -313,12 +318,11 @@ int em28xx_set_audio_source(struct em28xx *dev)
ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
if (ret < 0)
return ret;
+ msleep(5);
- if (no_ac97)
- return 0;
-
- /* Sets AC97 mixer registers */
-
+ /* Sets AC97 mixer registers
+ This is seems to be needed, even for non-ac97 configs
+ */
ret = em28xx_write_ac97(dev, VIDEO_AC97, video);
if (ret < 0)
return ret;
@@ -337,9 +341,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
s[0] |= 0x1f - dev->volume;
s[1] |= 0x1f - dev->volume;
- if (dev->mute)
- s[1] |= 0x80;
+ /* Mute */
+ s[1] |= 0x80;
ret = em28xx_write_ac97(dev, MASTER_AC97, s);
+
if (ret < 0)
return ret;
@@ -357,6 +362,11 @@ int em28xx_audio_analog_set(struct em28xx *dev)
/* Selects the proper audio input */
ret = em28xx_set_audio_source(dev);
+ /* Unmute device */
+ if (!dev->mute)
+ s[1] &= ~0x80;
+ ret = em28xx_write_ac97(dev, MASTER_AC97, s);
+
return ret;
}
EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
@@ -667,7 +677,7 @@ static void em28xx_isocIrq(struct urb *urb)
continue;
}
if (urb->iso_frame_desc[i].actual_length >
- dev->max_pkt_size) {
+ urb->iso_frame_desc[i].length) {
em28xx_isocdbg("packet bigger than packet size");
continue;
}
@@ -713,8 +723,11 @@ void em28xx_uninit_isoc(struct em28xx *dev)
for (i = 0; i < EM28XX_NUM_BUFS; i++) {
if (dev->urb[i]) {
usb_kill_urb(dev->urb[i]);
- if (dev->transfer_buffer[i]){
- usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma);
+ if (dev->transfer_buffer[i]) {
+ usb_buffer_free(dev->udev,
+ dev->urb[i]->transfer_buffer_length,
+ dev->transfer_buffer[i],
+ dev->urb[i]->transfer_dma);
}
usb_free_urb(dev->urb[i]);
}
@@ -732,7 +745,10 @@ int em28xx_init_isoc(struct em28xx *dev)
{
/* change interface to 3 which allows the biggest packet sizes */
int i, errCode;
- const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
+ int sb_size;
+
+ em28xx_set_alternate(dev);
+ sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
/* reset streaming vars */
dev->frame_current = NULL;
@@ -741,7 +757,7 @@ int em28xx_init_isoc(struct em28xx *dev)
/* allocate urbs */
for (i = 0; i < EM28XX_NUM_BUFS; i++) {
struct urb *urb;
- int j, k;
+ int j;
/* allocate transfer buffer */
urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
if (!urb){
@@ -749,7 +765,9 @@ int em28xx_init_isoc(struct em28xx *dev)
em28xx_uninit_isoc(dev);
return -ENOMEM;
}
- dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma);
+ dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size,
+ GFP_KERNEL,
+ &urb->transfer_dma);
if (!dev->transfer_buffer[i]) {
em28xx_errdev
("unable to allocate %i bytes for transfer buffer %i\n",
@@ -762,22 +780,22 @@ int em28xx_init_isoc(struct em28xx *dev)
urb->dev = dev->udev;
urb->context = dev;
urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
- urb->transfer_flags = URB_ISO_ASAP;
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
urb->interval = 1;
urb->transfer_buffer = dev->transfer_buffer[i];
urb->complete = em28xx_isocIrq;
urb->number_of_packets = EM28XX_NUM_PACKETS;
urb->transfer_buffer_length = sb_size;
- for (j = k = 0; j < EM28XX_NUM_PACKETS;
- j++, k += dev->max_pkt_size) {
- urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length =
- dev->max_pkt_size;
+ for (j = 0; j < EM28XX_NUM_PACKETS; j++) {
+ urb->iso_frame_desc[j].offset = j * dev->max_pkt_size;
+ urb->iso_frame_desc[j].length = dev->max_pkt_size;
}
dev->urb[i] = urb;
}
/* submit urbs */
+ em28xx_coredbg("Submitting %d urbs of %d packets (%d each)\n",
+ EM28XX_NUM_BUFS, EM28XX_NUM_PACKETS, dev->max_pkt_size);
for (i = 0; i < EM28XX_NUM_BUFS; i++) {
errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
if (errCode) {
@@ -794,22 +812,31 @@ int em28xx_init_isoc(struct em28xx *dev)
int em28xx_set_alternate(struct em28xx *dev)
{
int errCode, prev_alt = dev->alt;
- dev->alt = alt;
- if (dev->alt == 0) {
- int i;
- for(i=0;i< dev->num_alt; i++)
- if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
- dev->alt=i;
- }
+ int i;
+ unsigned int min_pkt_size = dev->bytesperline+4;
+
+ /* When image size is bigger than a ceirtain value,
+ the frame size should be increased, otherwise, only
+ green screen will be received.
+ */
+ if (dev->frame_size > 720*240*2)
+ min_pkt_size *= 2;
+
+ for (i = 0; i < dev->num_alt; i++)
+ if (dev->alt_max_pkt_size[i] >= min_pkt_size)
+ break;
+ dev->alt = i;
if (dev->alt != prev_alt) {
+ em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
+ min_pkt_size, dev->alt);
dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
- em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt,
- dev->max_pkt_size);
+ em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
+ dev->alt, dev->max_pkt_size);
errCode = usb_set_interface(dev->udev, 0, dev->alt);
if (errCode < 0) {
em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
- dev->alt, errCode);
+ dev->alt, errCode);
return errCode;
}
}
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index a0c33467248..4abe6701a77 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -189,7 +189,7 @@ static void video_mux(struct em28xx *dev, int index)
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
}
- em28xx_set_audio_source(dev);
+ em28xx_audio_analog_set(dev);
}
/* Usage lock check functions */
@@ -830,6 +830,63 @@ static int vidioc_s_frequency(struct file *file, void *priv,
return 0;
}
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int em28xx_reg_len(int reg)
+{
+ switch (reg) {
+ case AC97LSB_REG:
+ case HSCALELOW_REG:
+ case VSCALELOW_REG:
+ return 2;
+ default:
+ return 1;
+ }
+}
+
+static int vidioc_g_register(struct file *file, void *priv,
+ struct v4l2_register *reg)
+{
+ struct em28xx_fh *fh = priv;
+ struct em28xx *dev = fh->dev;
+ int ret;
+
+ if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
+ return -EINVAL;
+
+ if (em28xx_reg_len(reg->reg) == 1) {
+ ret = em28xx_read_reg(dev, reg->reg);
+ if (ret < 0)
+ return ret;
+
+ reg->val = ret;
+ } else {
+ u64 val = 0;
+ ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
+ reg->reg, (char *)&val, 2);
+ if (ret < 0)
+ return ret;
+
+ reg->val = cpu_to_le64((__u64)val);
+ }
+
+ return 0;
+}
+
+static int vidioc_s_register(struct file *file, void *priv,
+ struct v4l2_register *reg)
+{
+ struct em28xx_fh *fh = priv;
+ struct em28xx *dev = fh->dev;
+ u64 buf;
+
+ buf = le64_to_cpu((__u64)reg->val);
+
+ return em28xx_write_regs(dev, reg->reg, (char *)&buf,
+ em28xx_reg_len(reg->reg));
+}
+#endif
+
+
static int vidioc_cropcap(struct file *file, void *priv,
struct v4l2_cropcap *cc)
{
@@ -1295,8 +1352,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
filp->private_data = fh;
if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
- em28xx_set_alternate(dev);
-
dev->width = norm_maxw(dev);
dev->height = norm_maxh(dev);
dev->frame_size = dev->width * dev->height * 2;
@@ -1305,6 +1360,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
dev->hscale = 0;
dev->vscale = 0;
+ em28xx_set_alternate(dev);
em28xx_capture_start(dev, 1);
em28xx_resolution_set(dev);
@@ -1730,6 +1786,10 @@ static const struct video_device em28xx_video_template = {
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = vidioc_g_register,
+ .vidioc_s_register = vidioc_s_register,
+#endif
.tvnorms = V4L2_STD_ALL,
.current_norm = V4L2_STD_PAL,
@@ -1752,6 +1812,10 @@ static struct video_device em28xx_radio_template = {
.vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = vidioc_g_register,
+ .vidioc_s_register = vidioc_s_register,
+#endif
};
/******************************** usb interface *****************************************/
@@ -1796,10 +1860,10 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
}
EXPORT_SYMBOL(em28xx_unregister_extension);
-struct video_device *em28xx_vdev_init(struct em28xx *dev,
- const struct video_device *template,
- const int type,
- const char *type_name)
+static struct video_device *em28xx_vdev_init(struct em28xx *dev,
+ const struct video_device *template,
+ const int type,
+ const char *type_name)
{
struct video_device *vfd;
@@ -2064,6 +2128,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
snprintf(dev->name, 29, "em28xx #%d", nr);
dev->devno = nr;
dev->model = id->driver_info;
+ dev->alt = -1;
/* Checks if audio is provided by some interface */
for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index f3bad0c1c51..04e0e48ecab 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -33,7 +33,7 @@
#define UNSET -1
/* maximum number of em28xx boards */
-#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */
+#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
/* maximum number of frames that can be queued */
#define EM28XX_NUM_FRAMES 5
@@ -345,9 +345,6 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg);
int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
int len);
int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
-int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
- u8 bitmask);
-int em28xx_set_audio_source(struct em28xx *dev);
int em28xx_audio_analog_set(struct em28xx *dev);
int em28xx_colorlevels_set_default(struct em28xx *dev);
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 7d7f383b404..262830da08c 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -928,27 +928,38 @@ struct saa7134_board saa7134_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
+ .gpiomask = 0x03,
.inputs = {{
.name = name_tv,
.vmux = 1,
.amux = TV,
.tv = 1,
- },{
+ .gpio = 0x00,
+ }, {
.name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
.vmux = 3,
- .amux = LINE2,
- },{
+ .amux = LINE1,
+ .gpio = 0x02,
+ }, {
+ .name = name_comp2,
+ .vmux = 0,
+ .amux = LINE1,
+ .gpio = 0x02,
+ }, {
.name = name_svideo,
.vmux = 8,
- .amux = LINE2,
- }},
+ .amux = LINE1,
+ .gpio = 0x02,
+ } },
.radio = {
.name = name_radio,
- .amux = LINE2,
+ .amux = LINE1,
+ .gpio = 0x01,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ .gpio = 0x00,
},
},
[SAA7134_BOARD_BMK_MPEX_TUNER] = {
@@ -3912,6 +3923,74 @@ struct saa7134_board saa7134_boards[] = {
},
.mpeg = SAA7134_MPEG_EMPRESS,
},
+ [SAA7134_BOARD_TWINHAN_DTV_DVB_3056] = {
+ .name = "Twinhan Hybrid DTV-DVB 3056 PCI",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tuner_config = 2,
+ .mpeg = SAA7134_MPEG_DVB,
+ .gpiomask = 0x0200000,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8, /* untested */
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0200000,
+ },
+ },
+ [SAA7134_BOARD_GENIUS_TVGO_A11MCE] = {
+ /* Adrian Pardini <pardo.bsso@gmail.com> */
+ .name = "Genius TVGO AM11MCE",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_TNF_5335MF,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 0xf000,
+ .inputs = {{
+ .name = name_tv_mono,
+ .vmux = 1,
+ .amux = LINE2,
+ .gpio = 0x0000,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x2000,
+ .tv = 1
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ .gpio = 0x2000,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ .gpio = 0x1000,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = LINE2,
+ .gpio = 0x6000,
+ },
+ },
};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -4511,6 +4590,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x5168,
+ .subdevice = 0x3307, /* FlyDVB-T Hybrid Mini PCI */
+ .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
+ }, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x16be,
.subdevice = 0x0007,
.driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
@@ -4523,6 +4608,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x16be,
+ .subdevice = 0x000d, /* triple CTX948_V1.1.1 */
+ .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
+ }, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x1461,
.subdevice = 0x2c05,
.driver_data = SAA7134_BOARD_AVERMEDIA_777,
@@ -4843,7 +4934,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x4e42,
.subdevice = 0x3502,
- .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS
+ .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
+ }, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1822, /*Twinhan Technology Co. Ltd*/
+ .subdevice = 0x0022,
+ .driver_data = SAA7134_BOARD_TWINHAN_DTV_DVB_3056,
},{
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
@@ -4995,6 +5092,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_BEHOLD_409:
case SAA7134_BOARD_BEHOLD_505FM:
case SAA7134_BOARD_BEHOLD_507_9FM:
+ case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
dev->has_remote = SAA7134_REMOTE_GPIO;
break;
case SAA7134_BOARD_FLYDVBS_LR300:
@@ -5232,7 +5330,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
case SAA7134_BOARD_MEDION_MD8800_QUADRO:
- case SAA7134_BOARD_AVERMEDIA_SUPER_007:
+ case SAA7134_BOARD_AVERMEDIA_SUPER_007:
+ case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
/* this is a hybrid board, initialize to analog mode
* and configure firmware eeprom address
*/
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index a9ca5730826..ea2be9eceeb 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -779,6 +779,21 @@ static struct tda1004x_config avermedia_super_007_config = {
.request_firmware = philips_tda1004x_request_firmware
};
+static struct tda1004x_config twinhan_dtv_dvb_3056_config = {
+ .demod_address = 0x08,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_TDA827X,
+ .gpio_config = TDA10046_GP01_I,
+ .if_freq = TDA10046_FREQ_045,
+ .i2c_gate = 0x42,
+ .tuner_address = 0x61,
+ .tuner_config = 2,
+ .antenna_switch = 1,
+ .request_firmware = philips_tda1004x_request_firmware
+};
+
/* ------------------------------------------------------------------
* special case: this card uses saa713x GPIO22 for the mode switch
*/
@@ -826,6 +841,7 @@ static struct tda1004x_config ads_tech_duo_config = {
static struct tda10086_config flydvbs = {
.demod_address = 0x0e,
.invert = 0,
+ .diseqc_tone = 0,
};
/* ==================================================================
@@ -940,9 +956,9 @@ static int dvb_init(struct saa7134_dev *dev)
configure_tda827x_fe(dev, &tda827x_lifeview_config);
break;
case SAA7134_BOARD_FLYDVB_TRIO:
- if(! use_frontend) { //terrestrial
+ if(! use_frontend) { /* terrestrial */
configure_tda827x_fe(dev, &lifeview_trio_config);
- } else { //satellite
+ } else { /* satellite */
dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
if (dev->dvb.frontend) {
if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
@@ -1007,8 +1023,9 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
- dev->dvb.frontend = tda10046_attach(&medion_cardbus,
- &dev->i2c_adap);
+ dev->dvb.frontend = dvb_attach(tda10046_attach,
+ &medion_cardbus,
+ &dev->i2c_adap);
if (dev->dvb.frontend) {
dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
@@ -1044,6 +1061,9 @@ static int dvb_init(struct saa7134_dev *dev)
case SAA7134_BOARD_AVERMEDIA_SUPER_007:
configure_tda827x_fe(dev, &avermedia_super_007_config);
break;
+ case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
+ configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config);
+ break;
default:
wprintk("Huh? unknown DVB card?\n");
break;
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index b1b01fa8672..3d2ec30de22 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -87,7 +87,7 @@ static int ts_open(struct inode *inode, struct file *file)
dprintk("open minor=%d\n",minor);
err = -EBUSY;
- if (!mutex_trylock(&dev->empress_tsq.lock))
+ if (!mutex_trylock(&dev->empress_tsq.vb_lock))
goto done;
if (dev->empress_users)
goto done_up;
@@ -101,7 +101,7 @@ static int ts_open(struct inode *inode, struct file *file)
err = 0;
done_up:
- mutex_unlock(&dev->empress_tsq.lock);
+ mutex_unlock(&dev->empress_tsq.vb_lock);
done:
return err;
}
@@ -110,7 +110,6 @@ static int ts_release(struct inode *inode, struct file *file)
{
struct saa7134_dev *dev = file->private_data;
- mutex_lock(&dev->empress_tsq.lock);
videobuf_stop(&dev->empress_tsq);
videobuf_mmap_free(&dev->empress_tsq);
dev->empress_users--;
@@ -122,7 +121,6 @@ static int ts_release(struct inode *inode, struct file *file)
saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
- mutex_unlock(&dev->empress_tsq.lock);
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 0db955c2d9b..b4188819782 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -406,6 +406,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keyup = 0x8000000;
polling = 50; //ms
break;
+ case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
+ ir_codes = ir_codes_genius_tvgo_a11mce;
+ mask_keycode = 0xff;
+ mask_keydown = 0xf00000;
+ polling = 50; /* ms */
+ break;
}
if (NULL == ir_codes) {
printk("%s: Oops: IR config error [card=%d]\n",
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 1184d359e84..39c41ad97d0 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1414,21 +1414,17 @@ video_poll(struct file *file, struct poll_table_struct *wait)
if (!list_empty(&fh->cap.stream))
buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
} else {
- mutex_lock(&fh->cap.lock);
+ mutex_lock(&fh->cap.vb_lock);
if (UNSET == fh->cap.read_off) {
/* need to capture a new frame */
- if (res_locked(fh->dev,RESOURCE_VIDEO)) {
- mutex_unlock(&fh->cap.lock);
- return POLLERR;
- }
- if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
- mutex_unlock(&fh->cap.lock);
- return POLLERR;
- }
+ if (res_locked(fh->dev,RESOURCE_VIDEO))
+ goto err;
+ if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field))
+ goto err;
fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
fh->cap.read_off = 0;
}
- mutex_unlock(&fh->cap.lock);
+ mutex_unlock(&fh->cap.vb_lock);
buf = fh->cap.read_buf;
}
@@ -1440,6 +1436,10 @@ video_poll(struct file *file, struct poll_table_struct *wait)
buf->state == VIDEOBUF_ERROR)
return POLLIN|POLLRDNORM;
return 0;
+
+err:
+ mutex_unlock(&fh->cap.vb_lock);
+ return POLLERR;
}
static int video_release(struct inode *inode, struct file *file)
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index b88ca995faf..f940d025479 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -252,6 +252,8 @@ struct saa7134_format {
#define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128
#define SAA7134_BOARD_BEHOLD_607_9FM 129
#define SAA7134_BOARD_BEHOLD_M6 130
+#define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131
+#define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/stk-sensor.c b/drivers/media/video/stk-sensor.c
index 4a9a0b62efa..e546b014d7a 100644
--- a/drivers/media/video/stk-sensor.c
+++ b/drivers/media/video/stk-sensor.c
@@ -225,7 +225,7 @@
/* Returns 0 if OK */
-int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
+static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
{
int i = 0;
int tmpval = 0;
@@ -250,7 +250,7 @@ int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
return 0;
}
-int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
+static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
{
int i = 0;
int tmpval = 0;
@@ -380,7 +380,7 @@ int stk_sensor_init(struct stk_camera *dev)
STK_ERROR("Strange error reading sensor ID\n");
return -ENODEV;
}
- if (idh != 0x7F || idl != 0xA2) {
+ if (idh != 0x7f || idl != 0xa2) {
STK_ERROR("Huh? you don't have a sensor from ovt\n");
return -ENODEV;
}
@@ -409,6 +409,19 @@ static struct regval ov_fmt_uyvy[] = {
{REG_COM15, COM15_R00FF },
{0xff, 0xff}, /* END MARKER */
};
+/* V4L2_PIX_FMT_YUYV */
+static struct regval ov_fmt_yuyv[] = {
+ {REG_TSLB, 0 },
+ { 0x4f, 0x80 }, /* "matrix coefficient 1" */
+ { 0x50, 0x80 }, /* "matrix coefficient 2" */
+ { 0x51, 0 }, /* vb */
+ { 0x52, 0x22 }, /* "matrix coefficient 4" */
+ { 0x53, 0x5e }, /* "matrix coefficient 5" */
+ { 0x54, 0x80 }, /* "matrix coefficient 6" */
+ {REG_COM13, COM13_UVSAT|COM13_CMATRIX},
+ {REG_COM15, COM15_R00FF },
+ {0xff, 0xff}, /* END MARKER */
+};
/* V4L2_PIX_FMT_RGB565X rrrrrggg gggbbbbb */
static struct regval ov_fmt_rgbr[] = {
@@ -519,6 +532,10 @@ int stk_sensor_configure(struct stk_camera *dev)
com7 |= COM7_YUV;
rv = ov_fmt_uyvy;
break;
+ case V4L2_PIX_FMT_YUYV:
+ com7 |= COM7_YUV;
+ rv = ov_fmt_yuyv;
+ break;
case V4L2_PIX_FMT_RGB565:
com7 |= COM7_RGB;
rv = ov_fmt_rgbp;
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index d37e5e2594b..ceba45ad029 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -63,7 +63,7 @@ static struct usb_device_id stkwebcam_table[] = {
};
MODULE_DEVICE_TABLE(usb, stkwebcam_table);
-void stk_camera_cleanup(struct kref *kref)
+static void stk_camera_cleanup(struct kref *kref)
{
struct stk_camera *dev = to_stk_camera(kref);
@@ -682,6 +682,7 @@ static int v4l_stk_open(struct inode *inode, struct file *fp)
return -ENXIO;
fp->private_data = vdev;
kref_get(&dev->kref);
+ usb_autopm_get_interface(dev->interface);
return 0;
}
@@ -703,6 +704,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
}
if (dev->owner != fp) {
+ usb_autopm_put_interface(dev->interface);
kref_put(&dev->kref, stk_camera_cleanup);
return 0;
}
@@ -713,6 +715,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
dev->owner = NULL;
+ usb_autopm_put_interface(dev->interface);
kref_put(&dev->kref, stk_camera_cleanup);
return 0;
@@ -993,6 +996,10 @@ static int stk_vidioc_enum_fmt_cap(struct file *filp,
fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8;
strcpy(fmtd->description, "Raw bayer");
break;
+ case 4:
+ fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
+ strcpy(fmtd->description, "yuv4:2:2");
+ break;
default:
return -EINVAL;
}
@@ -1048,6 +1055,7 @@ static int stk_vidioc_try_fmt_cap(struct file *filp,
case V4L2_PIX_FMT_RGB565:
case V4L2_PIX_FMT_RGB565X:
case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_SBGGR8:
break;
default:
@@ -1080,6 +1088,42 @@ static int stk_vidioc_try_fmt_cap(struct file *filp,
return 0;
}
+static int stk_setup_format(struct stk_camera *dev)
+{
+ int i = 0;
+ int depth;
+ if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
+ depth = 1;
+ else
+ depth = 2;
+ while (stk_sizes[i].m != dev->vsettings.mode
+ && i < ARRAY_SIZE(stk_sizes))
+ i++;
+ if (i == ARRAY_SIZE(stk_sizes)) {
+ STK_ERROR("Something is broken in %s\n", __FUNCTION__);
+ return -EFAULT;
+ }
+ /* This registers controls some timings, not sure of what. */
+ stk_camera_write_reg(dev, 0x001b, 0x0e);
+ if (dev->vsettings.mode == MODE_SXGA)
+ stk_camera_write_reg(dev, 0x001c, 0x0e);
+ else
+ stk_camera_write_reg(dev, 0x001c, 0x46);
+ /*
+ * Registers 0x0115 0x0114 are the size of each line (bytes),
+ * regs 0x0117 0x0116 are the heigth of the image.
+ */
+ stk_camera_write_reg(dev, 0x0115,
+ ((stk_sizes[i].w * depth) >> 8) & 0xff);
+ stk_camera_write_reg(dev, 0x0114,
+ (stk_sizes[i].w * depth) & 0xff);
+ stk_camera_write_reg(dev, 0x0117,
+ (stk_sizes[i].h >> 8) & 0xff);
+ stk_camera_write_reg(dev, 0x0116,
+ stk_sizes[i].h & 0xff);
+ return stk_sensor_configure(dev);
+}
+
static int stk_vidioc_s_fmt_cap(struct file *filp,
void *priv, struct v4l2_format *fmtd)
{
@@ -1094,10 +1138,10 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
return -EBUSY;
if (dev->owner && dev->owner != filp)
return -EBUSY;
- dev->owner = filp;
ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd);
if (ret)
return ret;
+ dev->owner = filp;
dev->vsettings.palette = fmtd->fmt.pix.pixelformat;
stk_free_buffers(dev);
@@ -1105,25 +1149,7 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m;
stk_initialise(dev);
- /* This registers controls some timings, not sure of what. */
- stk_camera_write_reg(dev, 0x001b, 0x0e);
- if (dev->vsettings.mode == MODE_SXGA)
- stk_camera_write_reg(dev, 0x001c, 0x0e);
- else
- stk_camera_write_reg(dev, 0x001c, 0x46);
- /*
- * Registers 0x0115 0x0114 are the size of each line (bytes),
- * regs 0x0117 0x0116 are the heigth of the image.
- */
- stk_camera_write_reg(dev, 0x0115,
- (fmtd->fmt.pix.bytesperline >> 8) & 0xff);
- stk_camera_write_reg(dev, 0x0114,
- fmtd->fmt.pix.bytesperline & 0xff);
- stk_camera_write_reg(dev, 0x0117,
- (fmtd->fmt.pix.height >> 8) & 0xff);
- stk_camera_write_reg(dev, 0x0116,
- fmtd->fmt.pix.height & 0xff);
- return stk_sensor_configure(dev);
+ return stk_setup_format(dev);
}
static int stk_vidioc_reqbufs(struct file *filp,
@@ -1288,6 +1314,9 @@ static struct file_operations v4l_stk_fops = {
.poll = v4l_stk_poll,
.mmap = v4l_stk_mmap,
.ioctl = video_ioctl2,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = v4l_compat_ioctl32,
+#endif
.llseek = no_llseek
};
@@ -1403,7 +1432,7 @@ static int stk_camera_probe(struct usb_interface *interface,
dev->vsettings.brightness = 0x7fff;
dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
dev->vsettings.mode = MODE_VGA;
- dev->frame_size = 640*480*2;
+ dev->frame_size = 640 * 480 * 2;
INIT_LIST_HEAD(&dev->sio_avail);
INIT_LIST_HEAD(&dev->sio_full);
@@ -1417,6 +1446,7 @@ static int stk_camera_probe(struct usb_interface *interface,
}
stk_create_sysfs_files(&dev->vdev);
+ usb_autopm_enable(dev->interface);
return 0;
}
@@ -1434,11 +1464,41 @@ static void stk_camera_disconnect(struct usb_interface *interface)
kref_put(&dev->kref, stk_camera_cleanup);
}
+#ifdef CONFIG_PM
+int stk_camera_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct stk_camera *dev = usb_get_intfdata(intf);
+ if (is_streaming(dev)) {
+ stk_stop_stream(dev);
+ /* yes, this is ugly */
+ set_streaming(dev);
+ }
+ return 0;
+}
+
+int stk_camera_resume(struct usb_interface *intf)
+{
+ struct stk_camera *dev = usb_get_intfdata(intf);
+ if (!is_initialised(dev))
+ return 0;
+ unset_initialised(dev);
+ stk_initialise(dev);
+ stk_setup_format(dev);
+ if (is_streaming(dev))
+ stk_start_stream(dev);
+ return 0;
+}
+#endif
+
static struct usb_driver stk_camera_driver = {
.name = "stkwebcam",
.probe = stk_camera_probe,
.disconnect = stk_camera_disconnect,
.id_table = stkwebcam_table,
+#ifdef CONFIG_PM
+ .suspend = stk_camera_suspend,
+ .resume = stk_camera_resume,
+#endif
};
diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h
index 7e989d1ac1e..df4dfefc532 100644
--- a/drivers/media/video/stk-webcam.h
+++ b/drivers/media/video/stk-webcam.h
@@ -79,6 +79,7 @@ enum stk_status {
#define unset_present(dev) ((dev)->status &= \
~(S_PRESENT|S_INITIALISED|S_STREAMING))
#define set_initialised(dev) ((dev)->status |= S_INITIALISED)
+#define unset_initialised(dev) ((dev)->status &= ~S_INITIALISED)
#define set_memallocd(dev) ((dev)->status |= S_MEMALLOCD)
#define unset_memallocd(dev) ((dev)->status &= ~S_MEMALLOCD)
#define set_streaming(dev) ((dev)->status |= S_STREAMING)
@@ -127,8 +128,6 @@ void stk_camera_delete(struct kref *);
int stk_camera_write_reg(struct stk_camera *, u16, u8);
int stk_camera_read_reg(struct stk_camera *, u16, int *);
-int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val);
-int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val);
int stk_sensor_init(struct stk_camera *);
int stk_sensor_configure(struct stk_camera *);
int stk_sensor_sleep(struct stk_camera *dev);
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
index 41cd6a0b048..fb895f6684a 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/video/tcm825x.c
@@ -851,7 +851,7 @@ static int tcm825x_probe(struct i2c_client *client)
sensor->platform_data = client->dev.platform_data;
if (sensor->platform_data == NULL
- && !sensor->platform_data->is_okay())
+ || !sensor->platform_data->is_okay())
return -ENODEV;
sensor->v4l2_int_device = &tcm825x_int_device;
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index ba538f6fbcc..78a09a2a485 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1038,7 +1038,7 @@ static int tuner_resume(struct i2c_client *c)
/* ---------------------------------------------------------------------- */
-LIST_HEAD(tuner_list);
+static LIST_HEAD(tuner_list);
/* Search for existing radio and/or TV tuners on the given I2C adapter.
Note that when this function is called from tuner_probe you can be
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c
index f191f6a4807..50cf876f020 100644
--- a/drivers/media/video/tuner-xc2028.c
+++ b/drivers/media/video/tuner-xc2028.c
@@ -754,6 +754,9 @@ skip_std_specific:
goto check_device;
}
+ if (new_fw.type & FM)
+ goto check_device;
+
/* Load SCODE firmware, if exists */
tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr);
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index a75560540e7..01ebcec040c 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -1571,14 +1571,14 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
ctrl->value=chip->muted;
return 0;
case V4L2_CID_AUDIO_VOLUME:
- if (!desc->flags & CHIP_HAS_VOLUME)
+ if (!(desc->flags & CHIP_HAS_VOLUME))
break;
ctrl->value = max(chip->left,chip->right);
return 0;
case V4L2_CID_AUDIO_BALANCE:
{
int volume;
- if (!desc->flags & CHIP_HAS_VOLUME)
+ if (!(desc->flags & CHIP_HAS_VOLUME))
break;
volume = max(chip->left,chip->right);
if (volume)
@@ -1621,7 +1621,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
{
int volume,balance;
- if (!desc->flags & CHIP_HAS_VOLUME)
+ if (!(desc->flags & CHIP_HAS_VOLUME))
break;
volume = max(chip->left,chip->right);
@@ -1642,7 +1642,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
case V4L2_CID_AUDIO_BALANCE:
{
int volume, balance;
- if (!desc->flags & CHIP_HAS_VOLUME)
+ if (!(desc->flags & CHIP_HAS_VOLUME))
break;
volume = max(chip->left,chip->right);
@@ -1702,7 +1702,7 @@ static int chip_command(struct i2c_client *client,
break;
case V4L2_CID_AUDIO_VOLUME:
case V4L2_CID_AUDIO_BALANCE:
- if (!desc->flags & CHIP_HAS_VOLUME)
+ if (!(desc->flags & CHIP_HAS_VOLUME))
return -EINVAL;
break;
case V4L2_CID_AUDIO_BASS:
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 0b8fbad3c72..dc0da44a5af 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -242,7 +242,7 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "TCL M2523_3DBH_E"},
{ TUNER_ABSENT, "TCL M2523_3DIH_E"},
{ TUNER_ABSENT, "TCL MFPE05_2_U"},
- { TUNER_ABSENT, "Philips FMD1216MEX"},
+ { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216MEX"},
{ TUNER_ABSENT, "Philips FRH2036B"},
{ TUNER_ABSENT, "Panasonic ENGF75_01GF"},
{ TUNER_ABSENT, "MaxLinear MXL5005"},
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index c056ff6d810..34deb68ae56 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -56,7 +56,6 @@
#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/div64.h>
-#include <linux/video_decoder.h>
#define __OLD_VIDIOC_ /* To allow fixing old calls*/
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
@@ -82,108 +81,6 @@ MODULE_LICENSE("GPL");
*/
-char *v4l2_norm_to_name(v4l2_std_id id)
-{
- char *name;
- u32 myid = id;
-
- /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
- 64 bit comparations. So, on that architecture, with some gcc variants,
- compilation fails. Currently, the max value is 30bit wide.
- */
- BUG_ON(myid != id);
-
- switch (myid) {
- case V4L2_STD_PAL:
- name="PAL"; break;
- case V4L2_STD_PAL_BG:
- name="PAL-BG"; break;
- case V4L2_STD_PAL_DK:
- name="PAL-DK"; break;
- case V4L2_STD_PAL_B:
- name="PAL-B"; break;
- case V4L2_STD_PAL_B1:
- name="PAL-B1"; break;
- case V4L2_STD_PAL_G:
- name="PAL-G"; break;
- case V4L2_STD_PAL_H:
- name="PAL-H"; break;
- case V4L2_STD_PAL_I:
- name="PAL-I"; break;
- case V4L2_STD_PAL_D:
- name="PAL-D"; break;
- case V4L2_STD_PAL_D1:
- name="PAL-D1"; break;
- case V4L2_STD_PAL_K:
- name="PAL-K"; break;
- case V4L2_STD_PAL_M:
- name="PAL-M"; break;
- case V4L2_STD_PAL_N:
- name="PAL-N"; break;
- case V4L2_STD_PAL_Nc:
- name="PAL-Nc"; break;
- case V4L2_STD_PAL_60:
- name="PAL-60"; break;
- case V4L2_STD_NTSC:
- name="NTSC"; break;
- case V4L2_STD_NTSC_M:
- name="NTSC-M"; break;
- case V4L2_STD_NTSC_M_JP:
- name="NTSC-M-JP"; break;
- case V4L2_STD_NTSC_443:
- name="NTSC-443"; break;
- case V4L2_STD_NTSC_M_KR:
- name="NTSC-M-KR"; break;
- case V4L2_STD_SECAM:
- name="SECAM"; break;
- case V4L2_STD_SECAM_DK:
- name="SECAM-DK"; break;
- case V4L2_STD_SECAM_B:
- name="SECAM-B"; break;
- case V4L2_STD_SECAM_D:
- name="SECAM-D"; break;
- case V4L2_STD_SECAM_G:
- name="SECAM-G"; break;
- case V4L2_STD_SECAM_H:
- name="SECAM-H"; break;
- case V4L2_STD_SECAM_K:
- name="SECAM-K"; break;
- case V4L2_STD_SECAM_K1:
- name="SECAM-K1"; break;
- case V4L2_STD_SECAM_L:
- name="SECAM-L"; break;
- case V4L2_STD_SECAM_LC:
- name="SECAM-LC"; break;
- default:
- name="Unknown"; break;
- }
-
- return name;
-}
-
-/* Fill in the fields of a v4l2_standard structure according to the
- 'id' and 'transmission' parameters. Returns negative on error. */
-int v4l2_video_std_construct(struct v4l2_standard *vs,
- int id, char *name)
-{
- u32 index = vs->index;
-
- memset(vs, 0, sizeof(struct v4l2_standard));
- vs->index = index;
- vs->id = id;
- if (id & V4L2_STD_525_60) {
- vs->frameperiod.numerator = 1001;
- vs->frameperiod.denominator = 30000;
- vs->framelines = 525;
- } else {
- vs->frameperiod.numerator = 1;
- vs->frameperiod.denominator = 25;
- vs->framelines = 625;
- }
- strlcpy(vs->name,name,sizeof(vs->name));
- return 0;
-}
-
/* ----------------------------------------------------------------- */
/* priority handling */
@@ -196,6 +93,7 @@ int v4l2_prio_init(struct v4l2_prio_state *global)
memset(global,0,sizeof(*global));
return 0;
}
+EXPORT_SYMBOL(v4l2_prio_init);
int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
enum v4l2_priority new)
@@ -211,11 +109,13 @@ int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
*local = new;
return 0;
}
+EXPORT_SYMBOL(v4l2_prio_change);
int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
{
return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT);
}
+EXPORT_SYMBOL(v4l2_prio_open);
int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
{
@@ -223,6 +123,7 @@ int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
atomic_dec(&global->prios[*local]);
return 0;
}
+EXPORT_SYMBOL(v4l2_prio_close);
enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
{
@@ -234,6 +135,7 @@ enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
return V4L2_PRIORITY_BACKGROUND;
return V4L2_PRIORITY_UNSET;
}
+EXPORT_SYMBOL(v4l2_prio_max);
int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
{
@@ -241,225 +143,7 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
return -EBUSY;
return 0;
}
-
-
-/* ----------------------------------------------------------------- */
-/* some arrays for pretty-printing debug messages of enum types */
-
-char *v4l2_field_names[] = {
- [V4L2_FIELD_ANY] = "any",
- [V4L2_FIELD_NONE] = "none",
- [V4L2_FIELD_TOP] = "top",
- [V4L2_FIELD_BOTTOM] = "bottom",
- [V4L2_FIELD_INTERLACED] = "interlaced",
- [V4L2_FIELD_SEQ_TB] = "seq-tb",
- [V4L2_FIELD_SEQ_BT] = "seq-bt",
- [V4L2_FIELD_ALTERNATE] = "alternate",
- [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
- [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
-};
-
-char *v4l2_type_names[] = {
- [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
- [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
- [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
- [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
- [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
- [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
-};
-
-
-#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
-
-/* ------------------------------------------------------------------ */
-/* debug help functions */
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static const char *v4l1_ioctls[] = {
- [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
- [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
- [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
- [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
- [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
- [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
- [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
- [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
- [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
- [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
- [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
- [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
- [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
- [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
- [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
- [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
- [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
- [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
- [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
- [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
- [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
- [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
- [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
- [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
- [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
- [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
- [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
- [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
- [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
-};
-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
-#endif
-
-static const char *v4l2_ioctls[] = {
- [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
- [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
- [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
- [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
- [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
- [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
- [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
- [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
- [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
- [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
- [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
- [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
- [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
- [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
- [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
- [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
- [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
- [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
- [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
- [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
- [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
- [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
- [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
- [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
- [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
- [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
- [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
- [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
- [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
- [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
- [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
- [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
- [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
- [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
- [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
- [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
- [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
- [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
- [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
- [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
- [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
- [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
- [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
- [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
- [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
- [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
- [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
- [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
- [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
- [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
- [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
- [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
- [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
- [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
- [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
-#if 1
- [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
- [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
- [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
- [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
- [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
-
- [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
- [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
-
- [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
-#endif
-};
-#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
-
-static const char *v4l2_int_ioctls[] = {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
- [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
- [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
- [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
- [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
- [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
- [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
- [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
- [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
- [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
- [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
-#endif
- [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
-
- [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
- [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
- [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG",
-
- [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
- [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
- [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
- [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
- [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
- [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
- [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
- [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
- [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
- [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
- [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
- [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
- [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
- [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
- [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
- [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
-};
-#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
-
-
-/* Common ioctl debug function. This function can be used by
- external ioctl messages as well as internal V4L ioctl */
-void v4l_printk_ioctl(unsigned int cmd)
-{
- char *dir;
-
- switch (_IOC_DIR(cmd)) {
- case _IOC_NONE: dir = "--"; break;
- case _IOC_READ: dir = "r-"; break;
- case _IOC_WRITE: dir = "-w"; break;
- case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
- default: dir = "*ERR*"; break;
- }
- switch (_IOC_TYPE(cmd)) {
- case 'd':
- printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
- (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
- v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
- break;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case 'v':
- printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
- (_IOC_NR(cmd) < V4L1_IOCTLS) ?
- v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
- break;
-#endif
- case 'V':
- printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
- (_IOC_NR(cmd) < V4L2_IOCTLS) ?
- v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
- break;
-
- default:
- printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
- _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
- }
-}
-
+EXPORT_SYMBOL(v4l2_prio_check);
/* ----------------------------------------------------------------- */
@@ -488,6 +172,7 @@ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
}
return 0;
}
+EXPORT_SYMBOL(v4l2_ctrl_check);
/* Returns NULL or a character pointer array containing the menu for
the given control ID. The pointer array ends with a NULL pointer.
@@ -648,6 +333,7 @@ const char **v4l2_ctrl_get_menu(u32 id)
return NULL;
}
}
+EXPORT_SYMBOL(v4l2_ctrl_get_menu);
/* Fill in a struct v4l2_queryctrl */
int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
@@ -770,6 +456,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
snprintf(qctrl->name, sizeof(qctrl->name), name);
return 0;
}
+EXPORT_SYMBOL(v4l2_ctrl_query_fill);
/* Fill in a struct v4l2_queryctrl with standard values based on
the control ID. */
@@ -904,6 +591,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
return -EINVAL;
}
}
+EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
the menu. The qctrl pointer may be NULL, in which case it is ignored. */
@@ -922,6 +610,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
qmenu->reserved = 0;
return 0;
}
+EXPORT_SYMBOL(v4l2_ctrl_query_menu);
/* ctrl_classes points to an array of u32 pointers, the last element is
a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
@@ -972,7 +661,20 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
return 0;
return **ctrl_classes;
}
+EXPORT_SYMBOL(v4l2_ctrl_next);
+int v4l2_chip_match_host(u32 match_type, u32 match_chip)
+{
+ switch (match_type) {
+ case V4L2_CHIP_MATCH_HOST:
+ return match_chip == 0;
+ default:
+ return 0;
+ }
+}
+EXPORT_SYMBOL(v4l2_chip_match_host);
+
+#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip)
{
switch (match_type) {
@@ -984,6 +686,7 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_c
return 0;
}
}
+EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip,
u32 ident, u32 revision)
@@ -1000,16 +703,7 @@ int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chi
}
return 0;
}
-
-int v4l2_chip_match_host(u32 match_type, u32 match_chip)
-{
- switch (match_type) {
- case V4L2_CHIP_MATCH_HOST:
- return match_chip == 0;
- default:
- return 0;
- }
-}
+EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
/* ----------------------------------------------------------------- */
@@ -1038,38 +732,5 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver
}
return err != -ENOMEM ? 0 : err;
}
-
-/* ----------------------------------------------------------------- */
-
-EXPORT_SYMBOL(v4l2_norm_to_name);
-EXPORT_SYMBOL(v4l2_video_std_construct);
-
-EXPORT_SYMBOL(v4l2_prio_init);
-EXPORT_SYMBOL(v4l2_prio_change);
-EXPORT_SYMBOL(v4l2_prio_open);
-EXPORT_SYMBOL(v4l2_prio_close);
-EXPORT_SYMBOL(v4l2_prio_max);
-EXPORT_SYMBOL(v4l2_prio_check);
-
-EXPORT_SYMBOL(v4l2_field_names);
-EXPORT_SYMBOL(v4l2_type_names);
-EXPORT_SYMBOL(v4l_printk_ioctl);
-
-EXPORT_SYMBOL(v4l2_ctrl_next);
-EXPORT_SYMBOL(v4l2_ctrl_check);
-EXPORT_SYMBOL(v4l2_ctrl_get_menu);
-EXPORT_SYMBOL(v4l2_ctrl_query_menu);
-EXPORT_SYMBOL(v4l2_ctrl_query_fill);
-EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
-
-EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
-EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
-EXPORT_SYMBOL(v4l2_chip_match_host);
-
EXPORT_SYMBOL(v4l2_i2c_attach);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
+#endif
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 80a14da9ace..eab79ffdf56 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -147,7 +147,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q,
/* Having implementations for abstract methods are mandatory */
BUG_ON(!q->int_ops);
- mutex_init(&q->lock);
+ mutex_init(&q->vb_lock);
INIT_LIST_HEAD(&q->stream);
}
@@ -189,7 +189,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
return 0;
}
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
void videobuf_queue_cancel(struct videobuf_queue *q)
{
unsigned long flags = 0;
@@ -220,7 +220,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q)
/* --------------------------------------------------------------------- */
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
{
enum v4l2_field field = q->field;
@@ -239,7 +239,7 @@ enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
return field;
}
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
struct videobuf_buffer *vb, enum v4l2_buf_type type)
{
@@ -295,7 +295,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
b->sequence = vb->field_count >> 1;
}
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
static int __videobuf_mmap_free(struct videobuf_queue *q)
{
int i;
@@ -328,13 +328,13 @@ static int __videobuf_mmap_free(struct videobuf_queue *q)
int videobuf_mmap_free(struct videobuf_queue *q)
{
int ret;
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
ret = __videobuf_mmap_free(q);
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return ret;
}
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
static int __videobuf_mmap_setup(struct videobuf_queue *q,
unsigned int bcount, unsigned int bsize,
enum v4l2_memory memory)
@@ -384,9 +384,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
enum v4l2_memory memory)
{
int ret;
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
ret = __videobuf_mmap_setup(q, bcount, bsize, memory);
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return ret;
}
@@ -408,7 +408,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
return -EINVAL;
}
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
if (req->type != q->type) {
dprintk(1, "reqbufs: queue type invalid\n");
retval = -EINVAL;
@@ -444,7 +444,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
req->count = retval;
done:
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return retval;
}
@@ -452,7 +452,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
{
int ret = -EINVAL;
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
if (unlikely(b->type != q->type)) {
dprintk(1, "querybuf: Wrong type.\n");
goto done;
@@ -470,7 +470,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
ret = 0;
done:
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return ret;
}
@@ -487,7 +487,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
if (b->memory == V4L2_MEMORY_MMAP)
down_read(&current->mm->mmap_sem);
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
retval = -EBUSY;
if (q->reading) {
dprintk(1, "qbuf: Reading running...\n");
@@ -573,7 +573,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
retval = 0;
done:
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
if (b->memory == V4L2_MEMORY_MMAP)
up_read(&current->mm->mmap_sem);
@@ -589,7 +589,7 @@ int videobuf_dqbuf(struct videobuf_queue *q,
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
retval = -EBUSY;
if (q->reading) {
dprintk(1, "dqbuf: Reading running...\n");
@@ -632,7 +632,7 @@ int videobuf_dqbuf(struct videobuf_queue *q,
videobuf_status(q, b, buf, q->type);
done:
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return retval;
}
@@ -642,7 +642,7 @@ int videobuf_streamon(struct videobuf_queue *q)
unsigned long flags = 0;
int retval;
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
retval = -EBUSY;
if (q->reading)
goto done;
@@ -659,11 +659,11 @@ int videobuf_streamon(struct videobuf_queue *q)
spin_unlock_irqrestore(q->irqlock, flags);
done:
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return retval;
}
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
static int __videobuf_streamoff(struct videobuf_queue *q)
{
if (!q->streaming)
@@ -679,14 +679,14 @@ int videobuf_streamoff(struct videobuf_queue *q)
{
int retval;
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
retval = __videobuf_streamoff(q);
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return retval;
}
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
char __user *data,
size_t count, loff_t *ppos)
@@ -745,7 +745,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
nbufs = 1; size = 0;
q->ops->buf_setup(q, &nbufs, &size);
@@ -817,11 +817,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
}
done:
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return retval;
}
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
static int __videobuf_read_start(struct videobuf_queue *q)
{
enum v4l2_field field;
@@ -882,23 +882,23 @@ int videobuf_read_start(struct videobuf_queue *q)
{
int rc;
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
rc = __videobuf_read_start(q);
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return rc;
}
void videobuf_read_stop(struct videobuf_queue *q)
{
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
__videobuf_read_stop(q);
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
}
void videobuf_stop(struct videobuf_queue *q)
{
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
if (q->streaming)
__videobuf_streamoff(q);
@@ -906,7 +906,7 @@ void videobuf_stop(struct videobuf_queue *q)
if (q->reading)
__videobuf_read_stop(q);
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
}
@@ -920,7 +920,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
dprintk(2, "%s\n", __FUNCTION__);
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
retval = -EBUSY;
if (q->streaming)
goto done;
@@ -980,7 +980,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
}
done:
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return retval;
}
@@ -991,7 +991,7 @@ unsigned int videobuf_poll_stream(struct file *file,
struct videobuf_buffer *buf = NULL;
unsigned int rc = 0;
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
if (q->streaming) {
if (!list_empty(&q->stream))
buf = list_entry(q->stream.next,
@@ -1019,7 +1019,7 @@ unsigned int videobuf_poll_stream(struct file *file,
buf->state == VIDEOBUF_ERROR)
rc = POLLIN|POLLRDNORM;
}
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return rc;
}
@@ -1030,10 +1030,10 @@ int videobuf_mmap_mapper(struct videobuf_queue *q,
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
retval = CALL(q, mmap_mapper, q, vma);
q->is_mmapped = 1;
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
return retval;
}
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 98efd7ab1f5..53fed4b74ce 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -356,7 +356,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
map->count--;
if (0 == map->count) {
dprintk(1,"munmap %p q=%p\n",map,q);
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i])
continue;
@@ -373,7 +373,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
q->bufs[i]->baddr = 0;
q->ops->buf_release(q,q->bufs[i]);
}
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
kfree(map);
}
return;
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index 9b3898347ca..5266ecc91da 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -70,7 +70,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
map->count--;
if (0 == map->count) {
dprintk(1,"munmap %p q=%p\n",map,q);
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i])
continue;
@@ -83,7 +83,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
q->bufs[i]->map = NULL;
q->bufs[i]->baddr = 0;
}
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
kfree(map);
}
return;
@@ -107,7 +107,7 @@ static struct vm_operations_struct videobuf_vm_ops =
static void *__videobuf_alloc(size_t size)
{
- struct videbuf_vmalloc_memory *mem;
+ struct videobuf_vmalloc_memory *mem;
struct videobuf_buffer *vb;
vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
@@ -127,9 +127,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
struct v4l2_framebuffer *fbuf)
{
int pages;
-
- struct videbuf_vmalloc_memory *mem=vb->priv;
-
+ struct videobuf_vmalloc_memory *mem=vb->priv;
BUG_ON(!mem);
@@ -195,7 +193,7 @@ static int __videobuf_mmap_free(struct videobuf_queue *q)
static int __videobuf_mmap_mapper(struct videobuf_queue *q,
struct vm_area_struct *vma)
{
- struct videbuf_vmalloc_memory *mem;
+ struct videobuf_vmalloc_memory *mem;
struct videobuf_mapping *map;
unsigned int first;
int retval;
@@ -267,7 +265,7 @@ static int __videobuf_copy_to_user ( struct videobuf_queue *q,
char __user *data, size_t count,
int nonblocking )
{
- struct videbuf_vmalloc_memory *mem=q->read_buf->priv;
+ struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
BUG_ON (!mem);
MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
@@ -288,7 +286,7 @@ static int __videobuf_copy_stream ( struct videobuf_queue *q,
int vbihack, int nonblocking )
{
unsigned int *fc;
- struct videbuf_vmalloc_memory *mem=q->read_buf->priv;
+ struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
BUG_ON (!mem);
MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
@@ -341,7 +339,7 @@ EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init);
void *videobuf_to_vmalloc (struct videobuf_buffer *buf)
{
- struct videbuf_vmalloc_memory *mem=buf->priv;
+ struct videobuf_vmalloc_memory *mem=buf->priv;
BUG_ON (!mem);
MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
@@ -351,7 +349,7 @@ EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
void videobuf_vmalloc_free (struct videobuf_buffer *buf)
{
- struct videbuf_vmalloc_memory *mem=buf->priv;
+ struct videobuf_vmalloc_memory *mem=buf->priv;
BUG_ON (!mem);
MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 28655f8983c..0d9b63762a4 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -46,10 +46,373 @@
#include <linux/videodev.h>
#endif
#include <media/v4l2-common.h>
+#include <linux/video_decoder.h>
#define VIDEO_NUM_DEVICES 256
#define VIDEO_NAME "video4linux"
+/* video4linux standard ID conversion to standard name
+ */
+char *v4l2_norm_to_name(v4l2_std_id id)
+{
+ char *name;
+ u32 myid = id;
+
+ /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
+ 64 bit comparations. So, on that architecture, with some gcc
+ variants, compilation fails. Currently, the max value is 30bit wide.
+ */
+ BUG_ON(myid != id);
+
+ switch (myid) {
+ case V4L2_STD_PAL:
+ name = "PAL";
+ break;
+ case V4L2_STD_PAL_BG:
+ name = "PAL-BG";
+ break;
+ case V4L2_STD_PAL_DK:
+ name = "PAL-DK";
+ break;
+ case V4L2_STD_PAL_B:
+ name = "PAL-B";
+ break;
+ case V4L2_STD_PAL_B1:
+ name = "PAL-B1";
+ break;
+ case V4L2_STD_PAL_G:
+ name = "PAL-G";
+ break;
+ case V4L2_STD_PAL_H:
+ name = "PAL-H";
+ break;
+ case V4L2_STD_PAL_I:
+ name = "PAL-I";
+ break;
+ case V4L2_STD_PAL_D:
+ name = "PAL-D";
+ break;
+ case V4L2_STD_PAL_D1:
+ name = "PAL-D1";
+ break;
+ case V4L2_STD_PAL_K:
+ name = "PAL-K";
+ break;
+ case V4L2_STD_PAL_M:
+ name = "PAL-M";
+ break;
+ case V4L2_STD_PAL_N:
+ name = "PAL-N";
+ break;
+ case V4L2_STD_PAL_Nc:
+ name = "PAL-Nc";
+ break;
+ case V4L2_STD_PAL_60:
+ name = "PAL-60";
+ break;
+ case V4L2_STD_NTSC:
+ name = "NTSC";
+ break;
+ case V4L2_STD_NTSC_M:
+ name = "NTSC-M";
+ break;
+ case V4L2_STD_NTSC_M_JP:
+ name = "NTSC-M-JP";
+ break;
+ case V4L2_STD_NTSC_443:
+ name = "NTSC-443";
+ break;
+ case V4L2_STD_NTSC_M_KR:
+ name = "NTSC-M-KR";
+ break;
+ case V4L2_STD_SECAM:
+ name = "SECAM";
+ break;
+ case V4L2_STD_SECAM_DK:
+ name = "SECAM-DK";
+ break;
+ case V4L2_STD_SECAM_B:
+ name = "SECAM-B";
+ break;
+ case V4L2_STD_SECAM_D:
+ name = "SECAM-D";
+ break;
+ case V4L2_STD_SECAM_G:
+ name = "SECAM-G";
+ break;
+ case V4L2_STD_SECAM_H:
+ name = "SECAM-H";
+ break;
+ case V4L2_STD_SECAM_K:
+ name = "SECAM-K";
+ break;
+ case V4L2_STD_SECAM_K1:
+ name = "SECAM-K1";
+ break;
+ case V4L2_STD_SECAM_L:
+ name = "SECAM-L";
+ break;
+ case V4L2_STD_SECAM_LC:
+ name = "SECAM-LC";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ }
+
+ return name;
+}
+EXPORT_SYMBOL(v4l2_norm_to_name);
+
+/* Fill in the fields of a v4l2_standard structure according to the
+ 'id' and 'transmission' parameters. Returns negative on error. */
+int v4l2_video_std_construct(struct v4l2_standard *vs,
+ int id, char *name)
+{
+ u32 index = vs->index;
+
+ memset(vs, 0, sizeof(struct v4l2_standard));
+ vs->index = index;
+ vs->id = id;
+ if (id & V4L2_STD_525_60) {
+ vs->frameperiod.numerator = 1001;
+ vs->frameperiod.denominator = 30000;
+ vs->framelines = 525;
+ } else {
+ vs->frameperiod.numerator = 1;
+ vs->frameperiod.denominator = 25;
+ vs->framelines = 625;
+ }
+ strlcpy(vs->name, name, sizeof(vs->name));
+ return 0;
+}
+EXPORT_SYMBOL(v4l2_video_std_construct);
+
+/* ----------------------------------------------------------------- */
+/* some arrays for pretty-printing debug messages of enum types */
+
+char *v4l2_field_names[] = {
+ [V4L2_FIELD_ANY] = "any",
+ [V4L2_FIELD_NONE] = "none",
+ [V4L2_FIELD_TOP] = "top",
+ [V4L2_FIELD_BOTTOM] = "bottom",
+ [V4L2_FIELD_INTERLACED] = "interlaced",
+ [V4L2_FIELD_SEQ_TB] = "seq-tb",
+ [V4L2_FIELD_SEQ_BT] = "seq-bt",
+ [V4L2_FIELD_ALTERNATE] = "alternate",
+ [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
+ [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
+};
+EXPORT_SYMBOL(v4l2_field_names);
+
+char *v4l2_type_names[] = {
+ [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
+ [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
+ [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
+ [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
+ [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
+ [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
+ [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
+ [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
+};
+EXPORT_SYMBOL(v4l2_type_names);
+
+static char *v4l2_memory_names[] = {
+ [V4L2_MEMORY_MMAP] = "mmap",
+ [V4L2_MEMORY_USERPTR] = "userptr",
+ [V4L2_MEMORY_OVERLAY] = "overlay",
+};
+
+#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
+ arr[a] : "unknown")
+
+/* ------------------------------------------------------------------ */
+/* debug help functions */
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static const char *v4l1_ioctls[] = {
+ [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
+ [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
+ [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
+ [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
+ [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
+ [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
+ [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
+ [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
+ [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
+ [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
+ [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
+ [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
+ [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
+ [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
+ [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
+ [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
+ [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
+ [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
+ [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
+ [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
+ [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
+ [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
+ [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
+ [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
+ [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
+ [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
+ [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
+ [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
+ [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
+};
+#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
+#endif
+
+static const char *v4l2_ioctls[] = {
+ [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
+ [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
+ [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
+ [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
+ [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
+ [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
+ [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
+ [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
+ [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
+ [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
+ [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
+ [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
+ [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
+ [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
+ [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
+ [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
+ [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
+ [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
+ [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
+ [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
+ [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
+ [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
+ [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
+ [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
+ [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
+ [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
+ [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
+ [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
+ [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
+ [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
+ [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
+ [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
+ [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
+ [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
+ [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
+ [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
+ [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
+ [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
+ [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
+ [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
+ [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
+ [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
+ [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
+ [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
+ [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
+ [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
+ [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
+ [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
+ [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
+ [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
+ [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
+ [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
+ [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
+ [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
+ [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
+#if 1
+ [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
+ [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
+ [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
+ [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
+ [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
+
+ [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
+ [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
+
+ [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
+#endif
+};
+#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
+
+static const char *v4l2_int_ioctls[] = {
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
+ [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
+ [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
+ [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
+ [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
+ [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
+ [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
+ [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
+ [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
+ [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
+ [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
+#endif
+ [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
+
+ [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
+ [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
+ [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG",
+
+ [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
+ [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
+ [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
+ [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
+ [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
+ [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
+ [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
+ [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
+ [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
+ [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
+ [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
+ [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
+};
+#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
+
+/* Common ioctl debug function. This function can be used by
+ external ioctl messages as well as internal V4L ioctl */
+void v4l_printk_ioctl(unsigned int cmd)
+{
+ char *dir;
+
+ switch (_IOC_DIR(cmd)) {
+ case _IOC_NONE: dir = "--"; break;
+ case _IOC_READ: dir = "r-"; break;
+ case _IOC_WRITE: dir = "-w"; break;
+ case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
+ default: dir = "*ERR*"; break;
+ }
+ switch (_IOC_TYPE(cmd)) {
+ case 'd':
+ printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
+ (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
+ v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+ break;
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ case 'v':
+ printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
+ (_IOC_NR(cmd) < V4L1_IOCTLS) ?
+ v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+ break;
+#endif
+ case 'V':
+ printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
+ (_IOC_NR(cmd) < V4L2_IOCTLS) ?
+ v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+ break;
+
+ default:
+ printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
+ _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
+ }
+}
+EXPORT_SYMBOL(v4l_printk_ioctl);
+
/*
* sysfs stuff
*/
@@ -69,11 +432,13 @@ struct video_device *video_device_alloc(void)
vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
return vfd;
}
+EXPORT_SYMBOL(video_device_alloc);
void video_device_release(struct video_device *vfd)
{
kfree(vfd);
}
+EXPORT_SYMBOL(video_device_release);
static void video_release(struct device *cd)
{
@@ -110,6 +475,7 @@ struct video_device* video_devdata(struct file *file)
{
return video_device[iminor(file->f_path.dentry->d_inode)];
}
+EXPORT_SYMBOL(video_devdata);
/*
* Open a video device - FIXME: Obsoleted
@@ -278,6 +644,7 @@ out:
kfree(mbuf);
return err;
}
+EXPORT_SYMBOL(video_usercopy);
/*
* open/release helper functions -- handle exclusive opens
@@ -297,6 +664,7 @@ int video_exclusive_open(struct inode *inode, struct file *file)
mutex_unlock(&vfl->lock);
return retval;
}
+EXPORT_SYMBOL(video_exclusive_open);
int video_exclusive_release(struct inode *inode, struct file *file)
{
@@ -305,41 +673,7 @@ int video_exclusive_release(struct inode *inode, struct file *file)
vfl->users--;
return 0;
}
-
-static char *v4l2_memory_names[] = {
- [V4L2_MEMORY_MMAP] = "mmap",
- [V4L2_MEMORY_USERPTR] = "userptr",
- [V4L2_MEMORY_OVERLAY] = "overlay",
-};
-
-
-/* FIXME: Those stuff are replicated also on v4l2-common.c */
-static char *v4l2_type_names_FIXME[] = {
- [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
- [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
- [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
- [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
- [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
- [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
- [V4L2_BUF_TYPE_PRIVATE] = "private",
-};
-
-static char *v4l2_field_names_FIXME[] = {
- [V4L2_FIELD_ANY] = "any",
- [V4L2_FIELD_NONE] = "none",
- [V4L2_FIELD_TOP] = "top",
- [V4L2_FIELD_BOTTOM] = "bottom",
- [V4L2_FIELD_INTERLACED] = "interlaced",
- [V4L2_FIELD_SEQ_TB] = "seq-tb",
- [V4L2_FIELD_SEQ_BT] = "seq-bt",
- [V4L2_FIELD_ALTERNATE] = "alternate",
- [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
- [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
-};
-
-#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
+EXPORT_SYMBOL(video_exclusive_release);
static void dbgbuf(unsigned int cmd, struct video_device *vfd,
struct v4l2_buffer *p)
@@ -354,10 +688,10 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd,
(int)(p->timestamp.tv_sec%60),
p->timestamp.tv_usec,
p->index,
- prt_names(p->type,v4l2_type_names_FIXME),
- p->bytesused,p->flags,
- p->field,p->sequence,
- prt_names(p->memory,v4l2_memory_names),
+ prt_names(p->type, v4l2_type_names),
+ p->bytesused, p->flags,
+ p->field, p->sequence,
+ prt_names(p->memory, v4l2_memory_names),
p->m.userptr, p->length);
dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
"flags=0x%08d, frames=%d, userbits=0x%08x\n",
@@ -382,8 +716,8 @@ static inline void v4l_print_pix_fmt (struct video_device *vfd,
(fmt->pixelformat >> 8) & 0xff,
(fmt->pixelformat >> 16) & 0xff,
(fmt->pixelformat >> 24) & 0xff,
- prt_names(fmt->field,v4l2_field_names_FIXME),
- fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
+ prt_names(fmt->field, v4l2_field_names),
+ fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
};
@@ -597,7 +931,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
/* FIXME: Should be one dump per type */
dbgarg (cmd, "type=%s\n", prt_names(type,
- v4l2_type_names_FIXME));
+ v4l2_type_names));
switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -650,7 +984,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
/* FIXME: Should be one dump per type */
dbgarg (cmd, "type=%s\n", prt_names(f->type,
- v4l2_type_names_FIXME));
+ v4l2_type_names));
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -702,7 +1036,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
/* FIXME: Should be one dump per type */
dbgarg (cmd, "type=%s\n", prt_names(f->type,
- v4l2_type_names_FIXME));
+ v4l2_type_names));
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (vfd->vidioc_try_fmt_cap)
@@ -768,8 +1102,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
ret=vfd->vidioc_reqbufs(file, fh, p);
dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
p->count,
- prt_names(p->type,v4l2_type_names_FIXME),
- prt_names(p->memory,v4l2_memory_names));
+ prt_names(p->type, v4l2_type_names),
+ prt_names(p->memory, v4l2_memory_names));
break;
}
case VIDIOC_QUERYBUF:
@@ -858,7 +1192,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
enum v4l2_buf_type i = *(int *)arg;
if (!vfd->vidioc_streamon)
break;
- dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
+ dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
ret=vfd->vidioc_streamon(file, fh,i);
break;
}
@@ -868,7 +1202,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
if (!vfd->vidioc_streamoff)
break;
- dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
+ dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
ret=vfd->vidioc_streamoff(file, fh, i);
break;
}
@@ -1624,7 +1958,7 @@ out:
kfree(mbuf);
return err;
}
-
+EXPORT_SYMBOL(video_ioctl2);
static const struct file_operations video_fops;
@@ -1743,6 +2077,7 @@ fail_minor:
mutex_unlock(&videodev_lock);
return ret;
}
+EXPORT_SYMBOL(video_register_device);
/**
* video_unregister_device - unregister a video4linux device
@@ -1762,6 +2097,7 @@ void video_unregister_device(struct video_device *vfd)
device_unregister(&vfd->class_dev);
mutex_unlock(&videodev_lock);
}
+EXPORT_SYMBOL(video_unregister_device);
/*
* Video fs operations
@@ -1806,16 +2142,6 @@ static void __exit videodev_exit(void)
module_init(videodev_init)
module_exit(videodev_exit)
-EXPORT_SYMBOL(video_register_device);
-EXPORT_SYMBOL(video_unregister_device);
-EXPORT_SYMBOL(video_devdata);
-EXPORT_SYMBOL(video_usercopy);
-EXPORT_SYMBOL(video_exclusive_open);
-EXPORT_SYMBOL(video_exclusive_release);
-EXPORT_SYMBOL(video_ioctl2);
-EXPORT_SYMBOL(video_device_alloc);
-EXPORT_SYMBOL(video_device_release);
-
MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h
index 937c4a616c0..498a43c1f2b 100644
--- a/drivers/media/video/zoran.h
+++ b/drivers/media/video/zoran.h
@@ -221,15 +221,15 @@ enum zoran_map_mode {
};
enum gpio_type {
- GPIO_JPEG_SLEEP = 0,
- GPIO_JPEG_RESET,
- GPIO_JPEG_FRAME,
- GPIO_VID_DIR,
- GPIO_VID_EN,
- GPIO_VID_RESET,
- GPIO_CLK_SEL1,
- GPIO_CLK_SEL2,
- GPIO_MAX,
+ ZR_GPIO_JPEG_SLEEP = 0,
+ ZR_GPIO_JPEG_RESET,
+ ZR_GPIO_JPEG_FRAME,
+ ZR_GPIO_VID_DIR,
+ ZR_GPIO_VID_EN,
+ ZR_GPIO_VID_RESET,
+ ZR_GPIO_CLK_SEL1,
+ ZR_GPIO_CLK_SEL2,
+ ZR_GPIO_MAX,
};
enum gpcs_type {
@@ -378,11 +378,11 @@ struct card_info {
u32 jpeg_int; /* JPEG interrupt */
u32 vsync_int; /* VSYNC interrupt */
- s8 gpio[GPIO_MAX];
+ s8 gpio[ZR_GPIO_MAX];
u8 gpcs[GPCS_MAX];
struct vfe_polarity vfe_pol;
- u8 gpio_pol[GPIO_MAX];
+ u8 gpio_pol[ZR_GPIO_MAX];
/* is the /GWS line conected? */
u8 gws_not_connected;
diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c
index 68c7c505587..f97c2069205 100644
--- a/drivers/media/video/zoran_device.c
+++ b/drivers/media/video/zoran_device.c
@@ -250,7 +250,7 @@ void
jpeg_codec_sleep (struct zoran *zr,
int sleep)
{
- GPIO(zr, zr->card.gpio[GPIO_JPEG_SLEEP], !sleep);
+ GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep);
if (!sleep) {
dprintk(3,
KERN_DEBUG
@@ -277,9 +277,9 @@ jpeg_codec_reset (struct zoran *zr)
0);
udelay(2);
} else {
- GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 0);
+ GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0);
udelay(2);
- GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 1);
+ GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1);
udelay(2);
}
@@ -688,7 +688,7 @@ static inline void
set_frame (struct zoran *zr,
int val)
{
- GPIO(zr, zr->card.gpio[GPIO_JPEG_FRAME], val);
+ GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val);
}
static void
@@ -704,8 +704,8 @@ set_videobus_dir (struct zoran *zr,
GPIO(zr, 5, 1);
break;
default:
- GPIO(zr, zr->card.gpio[GPIO_VID_DIR],
- zr->card.gpio_pol[GPIO_VID_DIR] ? !val : val);
+ GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR],
+ zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val);
break;
}
}
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 1fdbb46de7f..1b44784d0ef 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -93,6 +93,8 @@ static struct usb_device_id device_table[] = {
{USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 },
{USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 },
{USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
+ {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
+ {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
{} /* Terminating entry */
};
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index bfda731696f..6b6df867958 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -632,8 +632,7 @@ mpt_deregister(u8 cb_idx)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mpt_event_register - Register protocol-specific event callback
- * handler.
+ * mpt_event_register - Register protocol-specific event callback handler.
* @cb_idx: previously registered (via mpt_register) callback handle
* @ev_cbfunc: callback function
*
@@ -654,8 +653,7 @@ mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mpt_event_deregister - Deregister protocol-specific event callback
- * handler.
+ * mpt_event_deregister - Deregister protocol-specific event callback handler
* @cb_idx: previously registered callback handle
*
* Each protocol-specific driver should call this routine
@@ -765,11 +763,13 @@ mpt_device_driver_deregister(u8 cb_idx)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
- * allocated per MPT adapter.
+ * mpt_get_msg_frame - Obtain an MPT request frame from the pool
* @cb_idx: Handle of registered MPT protocol driver
* @ioc: Pointer to MPT adapter structure
*
+ * Obtain an MPT request frame from the pool (of 1024) that are
+ * allocated per MPT adapter.
+ *
* Returns pointer to a MPT request frame or %NULL if none are available
* or IOC is not active.
*/
@@ -834,13 +834,12 @@ mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mpt_put_msg_frame - Send a protocol specific MPT request frame
- * to a IOC.
+ * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
* @cb_idx: Handle of registered MPT protocol driver
* @ioc: Pointer to MPT adapter structure
* @mf: Pointer to MPT request frame
*
- * This routine posts a MPT request frame to the request post FIFO of a
+ * This routine posts an MPT request frame to the request post FIFO of a
* specific MPT adapter.
*/
void
@@ -868,13 +867,15 @@ mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
}
/**
- * mpt_put_msg_frame_hi_pri - Send a protocol specific MPT request frame
- * to a IOC using hi priority request queue.
+ * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
* @cb_idx: Handle of registered MPT protocol driver
* @ioc: Pointer to MPT adapter structure
* @mf: Pointer to MPT request frame
*
- * This routine posts a MPT request frame to the request post FIFO of a
+ * Send a protocol-specific MPT request frame to an IOC using
+ * hi-priority request queue.
+ *
+ * This routine posts an MPT request frame to the request post FIFO of a
* specific MPT adapter.
**/
void
@@ -1481,15 +1482,15 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
if (pci_enable_device_mem(pdev)) {
- kfree(ioc);
printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
"failed\n", ioc->name);
+ kfree(ioc);
return r;
}
if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
- kfree(ioc);
printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
"MEM failed\n", ioc->name);
+ kfree(ioc);
return r;
}
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index d83ea96fe13..caadc68c300 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -923,7 +923,7 @@ extern struct proc_dir_entry *mpt_proc_root_dir;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* } __KERNEL__ */
-#if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__) || defined(__x86_64__) || defined(__powerpc__)
+#ifdef CONFIG_64BIT
#define CAST_U32_TO_PTR(x) ((void *)(u64)x)
#define CAST_PTR_TO_U32(x) ((u32)(u64)x)
#else
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index f77b329f692..78734e25edd 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -1701,6 +1701,11 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
if (error)
goto out_free_consistent;
+ if (!buffer->NumPhys) {
+ error = -ENODEV;
+ goto out_free_consistent;
+ }
+
/* save config data */
port_info->num_phys = buffer->NumPhys;
port_info->phy_info = kcalloc(port_info->num_phys,
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index af1de0ccee2..0c252f60c4c 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1533,7 +1533,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
*
* Remark: Currently invoked from a non-interrupt thread (_bh).
*
- * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
+ * Note: With old EH code, at most 1 SCSI TaskMgmt function per IOC
* will be active.
*
* Returns 0 for SUCCESS, or %FAILED.
@@ -2537,14 +2537,12 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
/**
* mptscsih_get_scsi_lookup
- *
- * retrieves scmd entry from ScsiLookup[] array list
- *
* @ioc: Pointer to MPT_ADAPTER structure
* @i: index into the array
*
- * Returns the scsi_cmd pointer
+ * retrieves scmd entry from ScsiLookup[] array list
*
+ * Returns the scsi_cmd pointer
**/
static struct scsi_cmnd *
mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
@@ -2561,14 +2559,12 @@ mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
/**
* mptscsih_getclear_scsi_lookup
- *
- * retrieves and clears scmd entry from ScsiLookup[] array list
- *
* @ioc: Pointer to MPT_ADAPTER structure
* @i: index into the array
*
- * Returns the scsi_cmd pointer
+ * retrieves and clears scmd entry from ScsiLookup[] array list
*
+ * Returns the scsi_cmd pointer
**/
static struct scsi_cmnd *
mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index afd82966f9a..13bac53db69 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -48,31 +48,13 @@ struct sm501_devdata {
unsigned int pdev_id;
unsigned int irq;
void __iomem *regs;
+ unsigned int rev;
};
#define MHZ (1000 * 1000)
#ifdef DEBUG
-static const unsigned int misc_div[] = {
- [0] = 1,
- [1] = 2,
- [2] = 4,
- [3] = 8,
- [4] = 16,
- [5] = 32,
- [6] = 64,
- [7] = 128,
- [8] = 3,
- [9] = 6,
- [10] = 12,
- [11] = 24,
- [12] = 48,
- [13] = 96,
- [14] = 192,
- [15] = 384,
-};
-
-static const unsigned int px_div[] = {
+static const unsigned int div_tab[] = {
[0] = 1,
[1] = 2,
[2] = 4,
@@ -101,12 +83,12 @@ static const unsigned int px_div[] = {
static unsigned long decode_div(unsigned long pll2, unsigned long val,
unsigned int lshft, unsigned int selbit,
- unsigned long mask, const unsigned int *dtab)
+ unsigned long mask)
{
if (val & selbit)
pll2 = 288 * MHZ;
- return pll2 / dtab[(val >> lshft) & mask];
+ return pll2 / div_tab[(val >> lshft) & mask];
}
#define fmt_freq(x) ((x) / MHZ), ((x) % MHZ), (x)
@@ -141,10 +123,10 @@ static void sm501_dump_clk(struct sm501_devdata *sm)
}
sdclk0 = (misct & (1<<12)) ? pll2 : 288 * MHZ;
- sdclk0 /= misc_div[((misct >> 8) & 0xf)];
+ sdclk0 /= div_tab[((misct >> 8) & 0xf)];
sdclk1 = (misct & (1<<20)) ? pll2 : 288 * MHZ;
- sdclk1 /= misc_div[((misct >> 16) & 0xf)];
+ sdclk1 /= div_tab[((misct >> 16) & 0xf)];
dev_dbg(sm->dev, "MISCT=%08lx, PM0=%08lx, PM1=%08lx\n",
misct, pm0, pm1);
@@ -158,19 +140,19 @@ static void sm501_dump_clk(struct sm501_devdata *sm)
"P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), "
"M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n",
(pmc & 3 ) == 0 ? '*' : '-',
- fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31, px_div)),
- fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15, misc_div)),
- fmt_freq(decode_div(pll2, pm0, 8, 1<<12, 15, misc_div)),
- fmt_freq(decode_div(pll2, pm0, 0, 1<<4, 15, misc_div)));
+ fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31)),
+ fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15)),
+ fmt_freq(decode_div(pll2, pm0, 8, 1<<12, 15)),
+ fmt_freq(decode_div(pll2, pm0, 0, 1<<4, 15)));
dev_dbg(sm->dev, "PM1[%c]: "
"P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), "
"M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n",
(pmc & 3 ) == 1 ? '*' : '-',
- fmt_freq(decode_div(pll2, pm1, 24, 1<<29, 31, px_div)),
- fmt_freq(decode_div(pll2, pm1, 16, 1<<20, 15, misc_div)),
- fmt_freq(decode_div(pll2, pm1, 8, 1<<12, 15, misc_div)),
- fmt_freq(decode_div(pll2, pm1, 0, 1<<4, 15, misc_div)));
+ fmt_freq(decode_div(pll2, pm1, 24, 1<<29, 31)),
+ fmt_freq(decode_div(pll2, pm1, 16, 1<<20, 15)),
+ fmt_freq(decode_div(pll2, pm1, 8, 1<<12, 15)),
+ fmt_freq(decode_div(pll2, pm1, 0, 1<<4, 15)));
}
static void sm501_dump_regs(struct sm501_devdata *sm)
@@ -436,46 +418,108 @@ struct sm501_clock {
unsigned long mclk;
int divider;
int shift;
+ unsigned int m, n, k;
};
+/* sm501_calc_clock
+ *
+ * Calculates the nearest discrete clock frequency that
+ * can be achieved with the specified input clock.
+ * the maximum divisor is 3 or 5
+ */
+
+static int sm501_calc_clock(unsigned long freq,
+ struct sm501_clock *clock,
+ int max_div,
+ unsigned long mclk,
+ long *best_diff)
+{
+ int ret = 0;
+ int divider;
+ int shift;
+ long diff;
+
+ /* try dividers 1 and 3 for CRT and for panel,
+ try divider 5 for panel only.*/
+
+ for (divider = 1; divider <= max_div; divider += 2) {
+ /* try all 8 shift values.*/
+ for (shift = 0; shift < 8; shift++) {
+ /* Calculate difference to requested clock */
+ diff = sm501fb_round_div(mclk, divider << shift) - freq;
+ if (diff < 0)
+ diff = -diff;
+
+ /* If it is less than the current, use it */
+ if (diff < *best_diff) {
+ *best_diff = diff;
+
+ clock->mclk = mclk;
+ clock->divider = divider;
+ clock->shift = shift;
+ ret = 1;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/* sm501_calc_pll
+ *
+ * Calculates the nearest discrete clock frequency that can be
+ * achieved using the programmable PLL.
+ * the maximum divisor is 3 or 5
+ */
+
+static unsigned long sm501_calc_pll(unsigned long freq,
+ struct sm501_clock *clock,
+ int max_div)
+{
+ unsigned long mclk;
+ unsigned int m, n, k;
+ long best_diff = 999999999;
+
+ /*
+ * The SM502 datasheet doesn't specify the min/max values for M and N.
+ * N = 1 at least doesn't work in practice.
+ */
+ for (m = 2; m <= 255; m++) {
+ for (n = 2; n <= 127; n++) {
+ for (k = 0; k <= 1; k++) {
+ mclk = (24000000UL * m / n) >> k;
+
+ if (sm501_calc_clock(freq, clock, max_div,
+ mclk, &best_diff)) {
+ clock->m = m;
+ clock->n = n;
+ clock->k = k;
+ }
+ }
+ }
+ }
+
+ /* Return best clock. */
+ return clock->mclk / (clock->divider << clock->shift);
+}
+
/* sm501_select_clock
*
- * selects nearest discrete clock frequency the SM501 can achive
+ * Calculates the nearest discrete clock frequency that can be
+ * achieved using the 288MHz and 336MHz PLLs.
* the maximum divisor is 3 or 5
*/
+
static unsigned long sm501_select_clock(unsigned long freq,
struct sm501_clock *clock,
int max_div)
{
unsigned long mclk;
- int divider;
- int shift;
- long diff;
long best_diff = 999999999;
/* Try 288MHz and 336MHz clocks. */
for (mclk = 288000000; mclk <= 336000000; mclk += 48000000) {
- /* try dividers 1 and 3 for CRT and for panel,
- try divider 5 for panel only.*/
-
- for (divider = 1; divider <= max_div; divider += 2) {
- /* try all 8 shift values.*/
- for (shift = 0; shift < 8; shift++) {
- /* Calculate difference to requested clock */
- diff = sm501fb_round_div(mclk, divider << shift) - freq;
- if (diff < 0)
- diff = -diff;
-
- /* If it is less than the current, use it */
- if (diff < best_diff) {
- best_diff = diff;
-
- clock->mclk = mclk;
- clock->divider = divider;
- clock->shift = shift;
- }
- }
- }
+ sm501_calc_clock(freq, clock, max_div, mclk, &best_diff);
}
/* Return best clock. */
@@ -497,6 +541,7 @@ unsigned long sm501_set_clock(struct device *dev,
unsigned long gate = readl(sm->regs + SM501_CURRENT_GATE);
unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK);
unsigned char reg;
+ unsigned int pll_reg = 0;
unsigned long sm501_freq; /* the actual frequency acheived */
struct sm501_clock to;
@@ -511,14 +556,28 @@ unsigned long sm501_set_clock(struct device *dev,
* requested frequency the value must be multiplied by
* 2. This clock also has an additional pre divisor */
- sm501_freq = (sm501_select_clock(2 * req_freq, &to, 5) / 2);
- reg=to.shift & 0x07;/* bottom 3 bits are shift */
- if (to.divider == 3)
- reg |= 0x08; /* /3 divider required */
- else if (to.divider == 5)
- reg |= 0x10; /* /5 divider required */
- if (to.mclk != 288000000)
- reg |= 0x20; /* which mclk pll is source */
+ if (sm->rev >= 0xC0) {
+ /* SM502 -> use the programmable PLL */
+ sm501_freq = (sm501_calc_pll(2 * req_freq,
+ &to, 5) / 2);
+ reg = to.shift & 0x07;/* bottom 3 bits are shift */
+ if (to.divider == 3)
+ reg |= 0x08; /* /3 divider required */
+ else if (to.divider == 5)
+ reg |= 0x10; /* /5 divider required */
+ reg |= 0x40; /* select the programmable PLL */
+ pll_reg = 0x20000 | (to.k << 15) | (to.n << 8) | to.m;
+ } else {
+ sm501_freq = (sm501_select_clock(2 * req_freq,
+ &to, 5) / 2);
+ reg = to.shift & 0x07;/* bottom 3 bits are shift */
+ if (to.divider == 3)
+ reg |= 0x08; /* /3 divider required */
+ else if (to.divider == 5)
+ reg |= 0x10; /* /5 divider required */
+ if (to.mclk != 288000000)
+ reg |= 0x20; /* which mclk pll is source */
+ }
break;
case SM501_CLOCK_V2XCLK:
@@ -579,6 +638,10 @@ unsigned long sm501_set_clock(struct device *dev,
}
writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
+
+ if (pll_reg)
+ writel(pll_reg, sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL);
+
sm501_sync_regs(sm);
dev_info(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
@@ -599,15 +662,24 @@ EXPORT_SYMBOL_GPL(sm501_set_clock);
* finds the closest available frequency for a given clock
*/
-unsigned long sm501_find_clock(int clksrc,
+unsigned long sm501_find_clock(struct device *dev,
+ int clksrc,
unsigned long req_freq)
{
+ struct sm501_devdata *sm = dev_get_drvdata(dev);
unsigned long sm501_freq; /* the frequency achiveable by the 501 */
struct sm501_clock to;
switch (clksrc) {
case SM501_CLOCK_P2XCLK:
- sm501_freq = (sm501_select_clock(2 * req_freq, &to, 5) / 2);
+ if (sm->rev >= 0xC0) {
+ /* SM502 -> use the programmable PLL */
+ sm501_freq = (sm501_calc_pll(2 * req_freq,
+ &to, 5) / 2);
+ } else {
+ sm501_freq = (sm501_select_clock(2 * req_freq,
+ &to, 5) / 2);
+ }
break;
case SM501_CLOCK_V2XCLK:
@@ -914,6 +986,8 @@ static int sm501_init_dev(struct sm501_devdata *sm)
dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n",
sm->regs, devid, (unsigned long)mem_avail >> 20, sm->irq);
+ sm->rev = devid & SM501_DEVICEID_REVMASK;
+
sm501_dump_gate(sm);
ret = device_create_file(sm->dev, &dev_attr_dbg_regs);
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1abc95ca9df..982e27b86d1 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -258,6 +258,23 @@ config THINKPAD_ACPI_BAY
If you are not sure, say Y here.
+config THINKPAD_ACPI_VIDEO
+ bool "Video output control support"
+ depends on THINKPAD_ACPI
+ default y
+ ---help---
+ Allows the thinkpad_acpi driver to provide an interface to control
+ the various video output ports.
+
+ This feature often won't work well, depending on ThinkPad model,
+ display state, video output devices in use, whether there is a X
+ server running, phase of the moon, and the current mood of
+ Schroedinger's cat. If you can use X.org's RandR to control
+ your ThinkPad's video output ports instead of this feature,
+ don't think twice: do it and say N here to save some memory.
+
+ If you are not sure, say Y here.
+
config THINKPAD_ACPI_HOTKEY_POLL
bool "Suport NVRAM polling for hot keys"
depends on THINKPAD_ACPI
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c
index d7aea93081f..74d12b4a3ab 100644
--- a/drivers/misc/acer-wmi.c
+++ b/drivers/misc/acer-wmi.c
@@ -273,6 +273,15 @@ static struct dmi_system_id acer_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "Acer TravelMate 4200",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"),
+ },
+ .driver_data = &quirk_acer_travelmate_2490,
+ },
+ {
+ .callback = dmi_matched,
.ident = "Medion MD 98300",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
diff --git a/drivers/misc/intel_menlow.c b/drivers/misc/intel_menlow.c
index f70984ab1e1..de16e88eb8d 100644
--- a/drivers/misc/intel_menlow.c
+++ b/drivers/misc/intel_menlow.c
@@ -170,10 +170,13 @@ static int intel_menlow_memory_add(struct acpi_device *device)
cdev = thermal_cooling_device_register("Memory controller", device,
&memory_cooling_ops);
- acpi_driver_data(device) = cdev;
- if (!cdev)
- result = -ENODEV;
- else {
+ if (IS_ERR(cdev)) {
+ result = PTR_ERR(cdev);
+ goto end;
+ }
+
+ if (cdev) {
+ acpi_driver_data(device) = cdev;
result = sysfs_create_link(&device->dev.kobj,
&cdev->device.kobj, "thermal_cooling");
if (result)
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index e2c7edd206a..6cb781262f9 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -221,6 +221,7 @@ static struct {
u32 hotkey:1;
u32 hotkey_mask:1;
u32 hotkey_wlsw:1;
+ u32 hotkey_tablet:1;
u32 light:1;
u32 light_status:1;
u32 bright_16levels:1;
@@ -301,6 +302,13 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */
"HKEY", /* all others */
); /* 570 */
+TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */
+ "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */
+ "\\_SB.PCI0.VID0", /* 770e */
+ "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */
+ "\\_SB.PCI0.AGP.VID", /* all others */
+ ); /* R30, R31 */
+
/*************************************************************************
* ACPI helpers
@@ -1053,6 +1061,9 @@ static struct attribute_set *hotkey_dev_attributes;
#define HOTKEY_CONFIG_CRITICAL_END
#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
+/* HKEY.MHKG() return bits */
+#define TP_HOTKEY_TABLET_MASK (1 << 3)
+
static int hotkey_get_wlsw(int *status)
{
if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
@@ -1060,6 +1071,17 @@ static int hotkey_get_wlsw(int *status)
return 0;
}
+static int hotkey_get_tablet_mode(int *status)
+{
+ int s;
+
+ if (!acpi_evalf(hkey_handle, &s, "MHKG", "d"))
+ return -EIO;
+
+ *status = ((s & TP_HOTKEY_TABLET_MASK) != 0);
+ return 0;
+}
+
/*
* Call with hotkey_mutex held
*/
@@ -1154,15 +1176,31 @@ static void tpacpi_input_send_radiosw(void)
{
int wlsw;
- mutex_lock(&tpacpi_inputdev_send_mutex);
-
if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
+ mutex_lock(&tpacpi_inputdev_send_mutex);
+
input_report_switch(tpacpi_inputdev,
SW_RADIO, !!wlsw);
input_sync(tpacpi_inputdev);
+
+ mutex_unlock(&tpacpi_inputdev_send_mutex);
}
+}
+
+static void tpacpi_input_send_tabletsw(void)
+{
+ int state;
+
+ if (tp_features.hotkey_tablet &&
+ !hotkey_get_tablet_mode(&state)) {
+ mutex_lock(&tpacpi_inputdev_send_mutex);
- mutex_unlock(&tpacpi_inputdev_send_mutex);
+ input_report_switch(tpacpi_inputdev,
+ SW_TABLET_MODE, !!state);
+ input_sync(tpacpi_inputdev);
+
+ mutex_unlock(&tpacpi_inputdev_send_mutex);
+ }
}
static void tpacpi_input_send_key(unsigned int scancode)
@@ -1417,6 +1455,14 @@ static void hotkey_poll_setup_safe(int may_warn)
mutex_unlock(&hotkey_mutex);
}
+#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
+
+static void hotkey_poll_setup_safe(int __unused)
+{
+}
+
+#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
+
static int hotkey_inputdev_open(struct input_dev *dev)
{
switch (tpacpi_lifecycle) {
@@ -1444,7 +1490,6 @@ static void hotkey_inputdev_close(struct input_dev *dev)
if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING)
hotkey_poll_setup_safe(0);
}
-#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
/* sysfs hotkey enable ------------------------------------------------- */
static ssize_t hotkey_enable_show(struct device *dev,
@@ -1666,6 +1711,29 @@ static void hotkey_radio_sw_notify_change(void)
"hotkey_radio_sw");
}
+/* sysfs hotkey tablet mode (pollable) --------------------------------- */
+static ssize_t hotkey_tablet_mode_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int res, s;
+ res = hotkey_get_tablet_mode(&s);
+ if (res < 0)
+ return res;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
+}
+
+static struct device_attribute dev_attr_hotkey_tablet_mode =
+ __ATTR(hotkey_tablet_mode, S_IRUGO, hotkey_tablet_mode_show, NULL);
+
+static void hotkey_tablet_mode_notify_change(void)
+{
+ if (tp_features.hotkey_tablet)
+ sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
+ "hotkey_tablet_mode");
+}
+
/* sysfs hotkey report_mode -------------------------------------------- */
static ssize_t hotkey_report_mode_show(struct device *dev,
struct device_attribute *attr,
@@ -1878,7 +1946,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
str_supported(tp_features.hotkey));
if (tp_features.hotkey) {
- hotkey_dev_attributes = create_attr_set(12, NULL);
+ hotkey_dev_attributes = create_attr_set(13, NULL);
if (!hotkey_dev_attributes)
return -ENOMEM;
res = add_many_to_attr_set(hotkey_dev_attributes,
@@ -1957,6 +2025,18 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
&dev_attr_hotkey_radio_sw.attr);
}
+ /* For X41t, X60t, X61t Tablets... */
+ if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
+ tp_features.hotkey_tablet = 1;
+ printk(TPACPI_INFO
+ "possible tablet mode switch found; "
+ "ThinkPad in %s mode\n",
+ (status & TP_HOTKEY_TABLET_MASK)?
+ "tablet" : "laptop");
+ res = add_to_attr_set(hotkey_dev_attributes,
+ &dev_attr_hotkey_tablet_mode.attr);
+ }
+
if (!res)
res = register_attr_set_with_sysfs(
hotkey_dev_attributes,
@@ -2006,6 +2086,10 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
set_bit(EV_SW, tpacpi_inputdev->evbit);
set_bit(SW_RADIO, tpacpi_inputdev->swbit);
}
+ if (tp_features.hotkey_tablet) {
+ set_bit(EV_SW, tpacpi_inputdev->evbit);
+ set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit);
+ }
dbg_printk(TPACPI_DBG_INIT,
"enabling hot key handling\n");
@@ -2023,12 +2107,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
(hotkey_report_mode < 2) ?
"enabled" : "disabled");
-#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
tpacpi_inputdev->open = &hotkey_inputdev_open;
tpacpi_inputdev->close = &hotkey_inputdev_close;
hotkey_poll_setup_safe(1);
-#endif
+ tpacpi_input_send_radiosw();
+ tpacpi_input_send_tabletsw();
}
return (tp_features.hotkey)? 0 : 1;
@@ -2156,11 +2240,15 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
/* 0x5000-0x5FFF: human interface helpers */
switch (hkey) {
case 0x5010: /* Lenovo new BIOS: brightness changed */
- case 0x5009: /* X61t: swivel up (tablet mode) */
- case 0x500a: /* X61t: swivel down (normal mode) */
case 0x500b: /* X61t: tablet pen inserted into bay */
case 0x500c: /* X61t: tablet pen removed from bay */
break;
+ case 0x5009: /* X41t-X61t: swivel up (tablet mode) */
+ case 0x500a: /* X41t-X61t: swivel down (normal mode) */
+ tpacpi_input_send_tabletsw();
+ hotkey_tablet_mode_notify_change();
+ send_acpi_ev = 0;
+ break;
case 0x5001:
case 0x5002:
/* LID switch events. Do not propagate */
@@ -2219,11 +2307,10 @@ static void hotkey_resume(void)
"from firmware\n");
tpacpi_input_send_radiosw();
hotkey_radio_sw_notify_change();
+ hotkey_tablet_mode_notify_change();
hotkey_wakeup_reason_notify_change();
hotkey_wakeup_hotunplug_complete_notify_change();
-#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
hotkey_poll_setup_safe(0);
-#endif
}
/* procfs -------------------------------------------------------------- */
@@ -2676,6 +2763,8 @@ static struct ibm_struct wan_driver_data = {
* Video subdriver
*/
+#ifdef CONFIG_THINKPAD_ACPI_VIDEO
+
enum video_access_mode {
TPACPI_VIDEO_NONE = 0,
TPACPI_VIDEO_570, /* 570 */
@@ -2703,13 +2792,6 @@ static int video_orig_autosw;
static int video_autosw_get(void);
static int video_autosw_set(int enable);
-TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */
- "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */
- "\\_SB.PCI0.VID0", /* 770e */
- "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */
- "\\_SB.PCI0.AGP.VID", /* all others */
- ); /* R30, R31 */
-
TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */
static int __init video_init(struct ibm_init_struct *iibm)
@@ -3019,6 +3101,8 @@ static struct ibm_struct video_driver_data = {
.exit = video_exit,
};
+#endif /* CONFIG_THINKPAD_ACPI_VIDEO */
+
/*************************************************************************
* Light (thinklight) subdriver
*/
@@ -5803,10 +5887,12 @@ static struct ibm_init_struct ibms_init[] __initdata = {
.init = wan_init,
.data = &wan_driver_data,
},
+#ifdef CONFIG_THINKPAD_ACPI_VIDEO
{
.init = video_init,
.data = &video_driver_data,
},
+#endif
{
.init = light_init,
.data = &light_driver_data,
@@ -5918,7 +6004,7 @@ MODULE_PARM_DESC(hotkey_report_mode,
#define TPACPI_PARAM(feature) \
module_param_call(feature, set_ibm_param, NULL, NULL, 0); \
- MODULE_PARM_DESC(feature, "Simulates thinkpad-aci procfs command " \
+ MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \
"at module load, see documentation")
TPACPI_PARAM(hotkey);
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 6ac81e35355..27596046297 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -1000,8 +1000,8 @@ static int __init ubi_init(void)
mutex_unlock(&ubi_devices_mutex);
if (err < 0) {
put_mtd_device(mtd);
- printk(KERN_ERR "UBI error: cannot attach %s\n",
- p->name);
+ printk(KERN_ERR "UBI error: cannot attach mtd%d\n",
+ mtd->index);
goto out_detach;
}
}
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 45771061526..a548c1d28fa 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -217,11 +217,11 @@ struct ubi_volume {
void *upd_buf;
int *eba_tbl;
- int checked:1;
- int corrupted:1;
- int upd_marker:1;
- int updating:1;
- int changing_leb:1;
+ unsigned int checked:1;
+ unsigned int corrupted:1;
+ unsigned int upd_marker:1;
+ unsigned int updating:1;
+ unsigned int changing_leb:1;
#ifdef CONFIG_MTD_UBI_GLUEBI
/*
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index a3ca2257e60..5be58d85c63 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -376,7 +376,9 @@ out_sysfs:
get_device(&vol->dev);
volume_sysfs_close(vol);
out_gluebi:
- ubi_destroy_gluebi(vol);
+ if (ubi_destroy_gluebi(vol))
+ dbg_err("cannot destroy gluebi for volume %d:%d",
+ ubi->ubi_num, vol_id);
out_cdev:
cdev_del(&vol->cdev);
out_mapping:
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 56fc3fbce83..af36b12be27 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -519,6 +519,7 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
if (ubi->autoresize_vol_id != -1) {
ubi_err("more then one auto-resize volume (%d "
"and %d)", ubi->autoresize_vol_id, i);
+ kfree(vol);
return -EINVAL;
}
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index eef6fecfff2..be6e918456d 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -168,7 +168,7 @@ static int debug = -1;
* Warning: 64K ring has hardware issues and may lock up.
*/
#if defined(CONFIG_SH_DREAMCAST)
-#define RX_BUF_IDX 1 /* 16K ring */
+#define RX_BUF_IDX 0 /* 8K ring */
#else
#define RX_BUF_IDX 2 /* 32K ring */
#endif
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 50c2b60e1fe..a0f0e605d63 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -90,6 +90,11 @@ config MACVLAN
This allows one to create virtual interfaces that map packets to
or from specific MAC addresses to a particular interface.
+ Macvlan devices can be added using the "ip" command from the
+ iproute2 package starting with the iproute2-2.6.23 release:
+
+ "ip link add link <real dev> [ address MAC ] [ NAME ] type macvlan"
+
To compile this driver as a module, choose M here: the module
will be called macvlan.
@@ -931,6 +936,14 @@ config ENC28J60_WRITEVERIFY
Enable the verify after the buffer write useful for debugging purpose.
If unsure, say N.
+config DM9000_DEBUGLEVEL
+ int "DM9000 maximum debug level"
+ depends on DM9000
+ default 4
+ help
+ The maximum level of debugging code compiled into the DM9000
+ driver.
+
config SMC911X
tristate "SMSC LAN911[5678] support"
select CRC32
@@ -2352,6 +2365,17 @@ config GELIC_NET
To compile this driver as a module, choose M here: the
module will be called ps3_gelic.
+config GELIC_WIRELESS
+ bool "PS3 Wireless support"
+ depends on GELIC_NET
+ select WIRELESS_EXT
+ help
+ This option adds the support for the wireless feature of PS3.
+ If you have the wireless-less model of PS3 or have no plan to
+ use wireless feature, disabling this option saves memory. As
+ the driver automatically distinguishes the models, you can
+ safely enable this option even if you have a wireless-less model.
+
config GIANFAR
tristate "Gianfar Ethernet"
depends on FSL_SOC
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 9fc7794e88e..3b1ea321dc0 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -70,7 +70,8 @@ obj-$(CONFIG_BNX2X) += bnx2x.o
spidernet-y += spider_net.o spider_net_ethtool.o
obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
-ps3_gelic-objs += ps3_gelic_net.o
+gelic_wireless-$(CONFIG_GELIC_WIRELESS) += ps3_gelic_wireless.o
+ps3_gelic-objs += ps3_gelic_net.o $(gelic_wireless-y)
obj-$(CONFIG_TC35815) += tc35815.o
obj-$(CONFIG_SKGE) += skge.o
obj-$(CONFIG_SKY2) += sky2.o
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 471c7f3e8a4..15853be4680 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -56,8 +56,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.7.3"
-#define DRV_MODULE_RELDATE "January 29, 2008"
+#define DRV_MODULE_VERSION "1.7.4"
+#define DRV_MODULE_RELDATE "February 18, 2008"
#define RUN_AT(x) (jiffies + (x))
@@ -1273,14 +1273,20 @@ bnx2_set_link(struct bnx2 *bp)
if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
(CHIP_NUM(bp) == CHIP_NUM_5706)) {
- u32 val;
+ u32 val, an_dbg;
if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
bnx2_5706s_force_link_dn(bp, 0);
bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
}
val = REG_RD(bp, BNX2_EMAC_STATUS);
- if (val & BNX2_EMAC_STATUS_LINK)
+
+ bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
+ bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
+ bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
+
+ if ((val & BNX2_EMAC_STATUS_LINK) &&
+ !(an_dbg & MISC_SHDW_AN_DBG_NOSYNC))
bmsr |= BMSR_LSTATUS;
else
bmsr &= ~BMSR_LSTATUS;
@@ -5356,11 +5362,15 @@ bnx2_test_intr(struct bnx2 *bp)
return -ENODEV;
}
+/* Determining link for parallel detection. */
static int
bnx2_5706_serdes_has_link(struct bnx2 *bp)
{
u32 mode_ctl, an_dbg, exp;
+ if (bp->phy_flags & BNX2_PHY_FLAG_NO_PARALLEL)
+ return 0;
+
bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_MODE_CTL);
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &mode_ctl);
@@ -5390,13 +5400,6 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
int check_link = 1;
spin_lock(&bp->phy_lock);
- if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
- bnx2_5706s_force_link_dn(bp, 0);
- bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
- spin_unlock(&bp->phy_lock);
- return;
- }
-
if (bp->serdes_an_pending) {
bp->serdes_an_pending--;
check_link = 0;
@@ -5420,7 +5423,6 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
(bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT)) {
u32 phy2;
- check_link = 0;
bnx2_write_phy(bp, 0x17, 0x0f01);
bnx2_read_phy(bp, 0x15, &phy2);
if (phy2 & 0x20) {
@@ -5435,17 +5437,21 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
} else
bp->current_interval = bp->timer_interval;
- if (bp->link_up && (bp->autoneg & AUTONEG_SPEED) && check_link) {
+ if (check_link) {
u32 val;
bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
- if (val & MISC_SHDW_AN_DBG_NOSYNC) {
- bnx2_5706s_force_link_dn(bp, 1);
- bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN;
- }
+ if (bp->link_up && (val & MISC_SHDW_AN_DBG_NOSYNC)) {
+ if (!(bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN)) {
+ bnx2_5706s_force_link_dn(bp, 1);
+ bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN;
+ } else
+ bnx2_set_link(bp);
+ } else if (!bp->link_up && !(val & MISC_SHDW_AN_DBG_NOSYNC))
+ bnx2_set_link(bp);
}
spin_unlock(&bp->phy_lock);
}
@@ -7326,7 +7332,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->flags |= BNX2_FLAG_NO_WOL;
bp->wol = 0;
}
- if (CHIP_NUM(bp) != CHIP_NUM_5706) {
+ if (CHIP_NUM(bp) == CHIP_NUM_5706) {
+ /* Don't do parallel detect on this board because of
+ * some board problems. The link will not go down
+ * if we do parallel detect.
+ */
+ if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
+ pdev->subsystem_device == 0x310c)
+ bp->phy_flags |= BNX2_PHY_FLAG_NO_PARALLEL;
+ } else {
bp->phy_addr = 2;
if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
bp->phy_flags |= BNX2_PHY_FLAG_2_5G_CAPABLE;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 3aa0364942e..1eaf5bb3d9c 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -6673,6 +6673,7 @@ struct bnx2 {
#define BNX2_PHY_FLAG_DIS_EARLY_DAC 0x00000400
#define BNX2_PHY_FLAG_REMOTE_PHY_CAP 0x00000800
#define BNX2_PHY_FLAG_FORCED_DOWN 0x00001000
+#define BNX2_PHY_FLAG_NO_PARALLEL 0x00002000
u32 mii_bmcr;
u32 mii_bmsr;
diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c
index afc7f34b1dc..8af142ccf37 100644
--- a/drivers/net/bnx2x.c
+++ b/drivers/net/bnx2x.c
@@ -1,6 +1,6 @@
/* bnx2x.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 Broadcom Corporation
*
* 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
@@ -10,13 +10,13 @@
* Based on code from Michael Chan's bnx2 driver
* UDP CSUM errata workaround by Arik Gendelman
* Slowpath rework by Vladislav Zolotarov
- * Statistics and Link managment by Yitchak Gertner
+ * Statistics and Link management by Yitchak Gertner
*
*/
/* define this to make the driver freeze on error
* to allow getting debug info
- * (you will need to reboot afterwords)
+ * (you will need to reboot afterwards)
*/
/*#define BNX2X_STOP_ON_ERROR*/
@@ -63,22 +63,21 @@
#include "bnx2x.h"
#include "bnx2x_init.h"
-#define DRV_MODULE_VERSION "0.40.15"
-#define DRV_MODULE_RELDATE "$DateTime: 2007/11/15 07:28:37 $"
-#define BNX2X_BC_VER 0x040009
+#define DRV_MODULE_VERSION "1.40.22"
+#define DRV_MODULE_RELDATE "2007/11/27"
+#define BNX2X_BC_VER 0x040200
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (5*HZ)
static char version[] __devinitdata =
- "Broadcom NetXtreme II 577xx 10Gigabit Ethernet Driver "
+ "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver "
DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Eliezer Tamir <eliezert@broadcom.com>");
MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
-MODULE_INFO(cvs_version, "$Revision: #356 $");
static int use_inta;
static int poll;
@@ -94,8 +93,8 @@ module_param(debug, int, 0);
MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
MODULE_PARM_DESC(poll, "use polling (for debug)");
MODULE_PARM_DESC(onefunc, "enable only first function");
-MODULE_PARM_DESC(nomcp, "ignore managment CPU (Implies onefunc)");
-MODULE_PARM_DESC(debug, "defualt debug msglevel");
+MODULE_PARM_DESC(nomcp, "ignore management CPU (Implies onefunc)");
+MODULE_PARM_DESC(debug, "default debug msglevel");
#ifdef BNX2X_MULTI
module_param(use_multi, int, 0);
@@ -298,8 +297,7 @@ static void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
static int bnx2x_mc_assert(struct bnx2x *bp)
{
- int i, j;
- int rc = 0;
+ int i, j, rc = 0;
char last_idx;
const char storm[] = {"XTCU"};
const u32 intmem_base[] = {
@@ -313,8 +311,9 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
for (i = 0; i < 4; i++) {
last_idx = REG_RD8(bp, XSTORM_ASSERT_LIST_INDEX_OFFSET +
intmem_base[i]);
- BNX2X_ERR("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n",
- storm[i], last_idx);
+ if (last_idx)
+ BNX2X_LOG("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n",
+ storm[i], last_idx);
/* print the asserts */
for (j = 0; j < STROM_ASSERT_ARRAY_SIZE; j++) {
@@ -330,7 +329,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
intmem_base[i]);
if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
- BNX2X_ERR("DATA %cSTORM_ASSERT_INDEX 0x%x ="
+ BNX2X_LOG("DATA %cSTORM_ASSERT_INDEX 0x%x ="
" 0x%08x 0x%08x 0x%08x 0x%08x\n",
storm[i], j, row3, row2, row1, row0);
rc++;
@@ -341,6 +340,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
}
return rc;
}
+
static void bnx2x_fw_dump(struct bnx2x *bp)
{
u32 mark, offset;
@@ -348,21 +348,22 @@ static void bnx2x_fw_dump(struct bnx2x *bp)
int word;
mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
- printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n", mark);
+ mark = ((mark + 0x3) & ~0x3);
+ printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n" KERN_ERR, mark);
for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) {
for (word = 0; word < 8; word++)
data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
offset + 4*word));
data[8] = 0x0;
- printk(KERN_ERR PFX "%s", (char *)data);
+ printk(KERN_CONT "%s", (char *)data);
}
for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) {
for (word = 0; word < 8; word++)
data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
offset + 4*word));
data[8] = 0x0;
- printk(KERN_ERR PFX "%s", (char *)data);
+ printk(KERN_CONT "%s", (char *)data);
}
printk("\n" KERN_ERR PFX "end of fw dump\n");
}
@@ -427,10 +428,10 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
}
}
- BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_t_idx(%u)"
- " def_x_idx(%u) def_att_idx(%u) attn_state(%u)"
+ BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)"
+ " def_t_idx(%u) def_att_idx(%u) attn_state(%u)"
" spq_prod_idx(%u)\n",
- bp->def_c_idx, bp->def_u_idx, bp->def_t_idx, bp->def_x_idx,
+ bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
@@ -441,7 +442,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n");
}
-static void bnx2x_enable_int(struct bnx2x *bp)
+static void bnx2x_int_enable(struct bnx2x *bp)
{
int port = bp->port;
u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
@@ -454,18 +455,26 @@ static void bnx2x_enable_int(struct bnx2x *bp)
HC_CONFIG_0_REG_ATTN_BIT_EN_0);
} else {
val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+ HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
HC_CONFIG_0_REG_INT_LINE_EN_0 |
HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+
+ /* Errata A0.158 workaround */
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
+ val, port, addr, msix);
+
+ REG_WR(bp, addr, val);
+
val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
}
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) msi %d\n",
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
val, port, addr, msix);
REG_WR(bp, addr, val);
}
-static void bnx2x_disable_int(struct bnx2x *bp)
+static void bnx2x_int_disable(struct bnx2x *bp)
{
int port = bp->port;
u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
@@ -484,15 +493,15 @@ static void bnx2x_disable_int(struct bnx2x *bp)
BNX2X_ERR("BUG! proper val not read from IGU!\n");
}
-static void bnx2x_disable_int_sync(struct bnx2x *bp)
+static void bnx2x_int_disable_sync(struct bnx2x *bp)
{
int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
int i;
atomic_inc(&bp->intr_sem);
- /* prevent the HW from sending interrupts*/
- bnx2x_disable_int(bp);
+ /* prevent the HW from sending interrupts */
+ bnx2x_int_disable(bp);
/* make sure all ISRs are done */
if (msix) {
@@ -775,6 +784,7 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
mb(); /* force bnx2x_wait_ramrod to see the change */
return;
}
+
switch (command | bp->state) {
case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT):
DP(NETIF_MSG_IFUP, "got setup ramrod\n");
@@ -787,20 +797,20 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
fp->state = BNX2X_FP_STATE_HALTED;
break;
- case (RAMROD_CMD_ID_ETH_PORT_DEL | BNX2X_STATE_CLOSING_WAIT4_DELETE):
- DP(NETIF_MSG_IFDOWN, "got delete ramrod\n");
- bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
- break;
-
case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid);
- bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_DELETED;
+ DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n",
+ cid);
+ bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
break;
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
break;
+ case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
+ DP(NETIF_MSG_IFUP, "got (un)set mac ramrod\n");
+ break;
+
default:
BNX2X_ERR("unexpected ramrod (%d) state is %x\n",
command, bp->state);
@@ -1179,12 +1189,175 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
return val;
}
+static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
+{
+ u32 cnt;
+ u32 lock_status;
+ u32 resource_bit = (1 << resource);
+ u8 func = bp->port;
+
+ /* Validating that the resource is within range */
+ if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
+ DP(NETIF_MSG_HW,
+ "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
+ resource, HW_LOCK_MAX_RESOURCE_VALUE);
+ return -EINVAL;
+ }
+
+ /* Validating that the resource is not already taken */
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+ if (lock_status & resource_bit) {
+ DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
+ lock_status, resource_bit);
+ return -EEXIST;
+ }
+
+ /* Try for 1 second every 5ms */
+ for (cnt = 0; cnt < 200; cnt++) {
+ /* Try to acquire the lock */
+ REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8 + 4,
+ resource_bit);
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+ if (lock_status & resource_bit)
+ return 0;
+
+ msleep(5);
+ }
+ DP(NETIF_MSG_HW, "Timeout\n");
+ return -EAGAIN;
+}
+
+static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource)
+{
+ u32 lock_status;
+ u32 resource_bit = (1 << resource);
+ u8 func = bp->port;
+
+ /* Validating that the resource is within range */
+ if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
+ DP(NETIF_MSG_HW,
+ "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
+ resource, HW_LOCK_MAX_RESOURCE_VALUE);
+ return -EINVAL;
+ }
+
+ /* Validating that the resource is currently taken */
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+ if (!(lock_status & resource_bit)) {
+ DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
+ lock_status, resource_bit);
+ return -EFAULT;
+ }
+
+ REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8, resource_bit);
+ return 0;
+}
+
+static int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
+{
+ /* The GPIO should be swapped if swap register is set and active */
+ int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
+ REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ bp->port;
+ int gpio_shift = gpio_num +
+ (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+ u32 gpio_mask = (1 << gpio_shift);
+ u32 gpio_reg;
+
+ if (gpio_num > MISC_REGISTERS_GPIO_3) {
+ BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+ return -EINVAL;
+ }
+
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+ /* read GPIO and mask except the float bits */
+ gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT);
+
+ switch (mode) {
+ case MISC_REGISTERS_GPIO_OUTPUT_LOW:
+ DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n",
+ gpio_num, gpio_shift);
+ /* clear FLOAT and set CLR */
+ gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS);
+ break;
+
+ case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
+ DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n",
+ gpio_num, gpio_shift);
+ /* clear FLOAT and set SET */
+ gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS);
+ break;
+
+ case MISC_REGISTERS_GPIO_INPUT_HI_Z :
+ DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n",
+ gpio_num, gpio_shift);
+ /* set FLOAT */
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+ break;
+
+ default:
+ break;
+ }
+
+ REG_WR(bp, MISC_REG_GPIO, gpio_reg);
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_GPIO);
+
+ return 0;
+}
+
+static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
+{
+ u32 spio_mask = (1 << spio_num);
+ u32 spio_reg;
+
+ if ((spio_num < MISC_REGISTERS_SPIO_4) ||
+ (spio_num > MISC_REGISTERS_SPIO_7)) {
+ BNX2X_ERR("Invalid SPIO %d\n", spio_num);
+ return -EINVAL;
+ }
+
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_SPIO);
+ /* read SPIO and mask except the float bits */
+ spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT);
+
+ switch (mode) {
+ case MISC_REGISTERS_SPIO_OUTPUT_LOW :
+ DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num);
+ /* clear FLOAT and set CLR */
+ spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+ spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS);
+ break;
+
+ case MISC_REGISTERS_SPIO_OUTPUT_HIGH :
+ DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num);
+ /* clear FLOAT and set SET */
+ spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+ spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_SET_POS);
+ break;
+
+ case MISC_REGISTERS_SPIO_INPUT_HI_Z:
+ DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num);
+ /* set FLOAT */
+ spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+ break;
+
+ default:
+ break;
+ }
+
+ REG_WR(bp, MISC_REG_SPIO, spio_reg);
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_SPIO);
+
+ return 0;
+}
+
static int bnx2x_mdio22_write(struct bnx2x *bp, u32 reg, u32 val)
{
- int rc;
- u32 tmp, i;
int port = bp->port;
u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ u32 tmp;
+ int i, rc;
/* DP(NETIF_MSG_HW, "phy_addr 0x%x reg 0x%x val 0x%08x\n",
bp->phy_addr, reg, val); */
@@ -1236,8 +1409,8 @@ static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val)
{
int port = bp->port;
u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 val, i;
- int rc;
+ u32 val;
+ int i, rc;
if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
@@ -1286,58 +1459,54 @@ static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val)
return rc;
}
-static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
+static int bnx2x_mdio45_ctrl_write(struct bnx2x *bp, u32 mdio_ctrl,
+ u32 phy_addr, u32 reg, u32 addr, u32 val)
{
- int rc = 0;
- u32 tmp, i;
- int port = bp->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- tmp &= ~EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
- REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
- }
+ u32 tmp;
+ int i, rc = 0;
- /* set clause 45 mode */
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- tmp |= EMAC_MDIO_MODE_CLAUSE_45;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
+ /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
+ * (a value of 49==0x31) and make sure that the AUTO poll is off
+ */
+ tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ tmp &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
+ tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
+ (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
+ REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ udelay(40);
/* address */
- tmp = ((bp->phy_addr << 21) | (reg << 16) | addr |
+ tmp = ((phy_addr << 21) | (reg << 16) | addr |
EMAC_MDIO_COMM_COMMAND_ADDRESS |
EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
for (i = 0; i < 50; i++) {
udelay(10);
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+ tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
}
}
-
if (tmp & EMAC_MDIO_COMM_START_BUSY) {
BNX2X_ERR("write phy register failed\n");
rc = -EBUSY;
+
} else {
/* data */
- tmp = ((bp->phy_addr << 21) | (reg << 16) | val |
+ tmp = ((phy_addr << 21) | (reg << 16) | val |
EMAC_MDIO_COMM_COMMAND_WRITE_45 |
EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
for (i = 0; i < 50; i++) {
udelay(10);
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+ tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
@@ -1351,75 +1520,78 @@ static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
}
}
- /* unset clause 45 mode */
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- tmp &= ~EMAC_MDIO_MODE_CLAUSE_45;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+ /* unset clause 45 mode, set the MDIO clock to a faster value
+ * (0x13 => 6.25Mhz) and restore the AUTO poll if needed
+ */
+ tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ tmp &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT);
+ tmp |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
+ if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG)
tmp |= EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
- }
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
return rc;
}
-static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr,
- u32 *ret_val)
+static int bnx2x_mdio45_write(struct bnx2x *bp, u32 phy_addr, u32 reg,
+ u32 addr, u32 val)
{
- int port = bp->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 val, i;
- int rc = 0;
+ u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+ return bnx2x_mdio45_ctrl_write(bp, emac_base, phy_addr,
+ reg, addr, val);
+}
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- val &= ~EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
- REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
- }
+static int bnx2x_mdio45_ctrl_read(struct bnx2x *bp, u32 mdio_ctrl,
+ u32 phy_addr, u32 reg, u32 addr,
+ u32 *ret_val)
+{
+ u32 val;
+ int i, rc = 0;
- /* set clause 45 mode */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- val |= EMAC_MDIO_MODE_CLAUSE_45;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
+ /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
+ * (a value of 49==0x31) and make sure that the AUTO poll is off
+ */
+ val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ val &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
+ val |= (EMAC_MDIO_MODE_CLAUSE_45 |
+ (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
+ REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ udelay(40);
/* address */
- val = ((bp->phy_addr << 21) | (reg << 16) | addr |
+ val = ((phy_addr << 21) | (reg << 16) | addr |
EMAC_MDIO_COMM_COMMAND_ADDRESS |
EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
for (i = 0; i < 50; i++) {
udelay(10);
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+ val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
}
}
-
if (val & EMAC_MDIO_COMM_START_BUSY) {
BNX2X_ERR("read phy register failed\n");
*ret_val = 0;
rc = -EBUSY;
+
} else {
/* data */
- val = ((bp->phy_addr << 21) | (reg << 16) |
+ val = ((phy_addr << 21) | (reg << 16) |
EMAC_MDIO_COMM_COMMAND_READ_45 |
EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
for (i = 0; i < 50; i++) {
udelay(10);
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+ val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
val &= EMAC_MDIO_COMM_DATA;
break;
@@ -1436,31 +1608,39 @@ static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr,
*ret_val = val;
}
- /* unset clause 45 mode */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- val &= ~EMAC_MDIO_MODE_CLAUSE_45;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+ /* unset clause 45 mode, set the MDIO clock to a faster value
+ * (0x13 => 6.25Mhz) and restore the AUTO poll if needed
+ */
+ val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ val &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT);
+ val |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
+ if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG)
val |= EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
- }
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
return rc;
}
-static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
+static int bnx2x_mdio45_read(struct bnx2x *bp, u32 phy_addr, u32 reg,
+ u32 addr, u32 *ret_val)
+{
+ u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
+ return bnx2x_mdio45_ctrl_read(bp, emac_base, phy_addr,
+ reg, addr, ret_val);
+}
+
+static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 phy_addr, u32 reg,
+ u32 addr, u32 val)
{
int i;
u32 rd_val;
might_sleep();
for (i = 0; i < 10; i++) {
- bnx2x_mdio45_write(bp, reg, addr, val);
+ bnx2x_mdio45_write(bp, phy_addr, reg, addr, val);
msleep(5);
- bnx2x_mdio45_read(bp, reg, addr, &rd_val);
+ bnx2x_mdio45_read(bp, phy_addr, reg, addr, &rd_val);
/* if the read value is not the same as the value we wrote,
we should write it again */
if (rd_val == val)
@@ -1471,18 +1651,81 @@ static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
}
/*
- * link managment
+ * link management
*/
+static void bnx2x_pause_resolve(struct bnx2x *bp, u32 pause_result)
+{
+ switch (pause_result) { /* ASYM P ASYM P */
+ case 0xb: /* 1 0 1 1 */
+ bp->flow_ctrl = FLOW_CTRL_TX;
+ break;
+
+ case 0xe: /* 1 1 1 0 */
+ bp->flow_ctrl = FLOW_CTRL_RX;
+ break;
+
+ case 0x5: /* 0 1 0 1 */
+ case 0x7: /* 0 1 1 1 */
+ case 0xd: /* 1 1 0 1 */
+ case 0xf: /* 1 1 1 1 */
+ bp->flow_ctrl = FLOW_CTRL_BOTH;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static u8 bnx2x_ext_phy_resove_fc(struct bnx2x *bp)
+{
+ u32 ext_phy_addr;
+ u32 ld_pause; /* local */
+ u32 lp_pause; /* link partner */
+ u32 an_complete; /* AN complete */
+ u32 pause_result;
+ u8 ret = 0;
+
+ ext_phy_addr = ((bp->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+ /* read twice */
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_STATUS, &an_complete);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_STATUS, &an_complete);
+
+ if (an_complete & EXT_PHY_KR_AUTO_NEG_COMPLETE) {
+ ret = 1;
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_AUTO_NEG_ADVERT, &ld_pause);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_LP_AUTO_NEG, &lp_pause);
+ pause_result = (ld_pause &
+ EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 8;
+ pause_result |= (lp_pause &
+ EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 10;
+ DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
+ pause_result);
+ bnx2x_pause_resolve(bp, pause_result);
+ }
+ return ret;
+}
+
static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status)
{
- u32 ld_pause; /* local driver */
- u32 lp_pause; /* link partner */
+ u32 ld_pause; /* local driver */
+ u32 lp_pause; /* link partner */
u32 pause_result;
bp->flow_ctrl = 0;
- /* reolve from gp_status in case of AN complete and not sgmii */
+ /* resolve from gp_status in case of AN complete and not sgmii */
if ((bp->req_autoneg & AUTONEG_FLOW_CTRL) &&
(gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
(!(bp->phy_flags & PHY_SGMII_FLAG)) &&
@@ -1499,45 +1742,57 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status)
pause_result |= (lp_pause &
MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
+ bnx2x_pause_resolve(bp, pause_result);
+ } else if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) ||
+ !(bnx2x_ext_phy_resove_fc(bp))) {
+ /* forced speed */
+ if (bp->req_autoneg & AUTONEG_FLOW_CTRL) {
+ switch (bp->req_flow_ctrl) {
+ case FLOW_CTRL_AUTO:
+ if (bp->dev->mtu <= 4500)
+ bp->flow_ctrl = FLOW_CTRL_BOTH;
+ else
+ bp->flow_ctrl = FLOW_CTRL_TX;
+ break;
- switch (pause_result) { /* ASYM P ASYM P */
- case 0xb: /* 1 0 1 1 */
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case 0xe: /* 1 1 1 0 */
- bp->flow_ctrl = FLOW_CTRL_RX;
- break;
+ case FLOW_CTRL_TX:
+ bp->flow_ctrl = FLOW_CTRL_TX;
+ break;
- case 0x5: /* 0 1 0 1 */
- case 0x7: /* 0 1 1 1 */
- case 0xd: /* 1 1 0 1 */
- case 0xf: /* 1 1 1 1 */
- bp->flow_ctrl = FLOW_CTRL_BOTH;
- break;
+ case FLOW_CTRL_RX:
+ if (bp->dev->mtu <= 4500)
+ bp->flow_ctrl = FLOW_CTRL_RX;
+ break;
- default:
- break;
- }
+ case FLOW_CTRL_BOTH:
+ if (bp->dev->mtu <= 4500)
+ bp->flow_ctrl = FLOW_CTRL_BOTH;
+ else
+ bp->flow_ctrl = FLOW_CTRL_TX;
+ break;
- } else { /* forced mode */
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- if (bp->dev->mtu <= 4500)
- bp->flow_ctrl = FLOW_CTRL_BOTH;
- else
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
+ case FLOW_CTRL_NONE:
+ default:
+ break;
+ }
+ } else { /* forced mode */
+ switch (bp->req_flow_ctrl) {
+ case FLOW_CTRL_AUTO:
+ DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while"
+ " req_autoneg 0x%x\n",
+ bp->req_flow_ctrl, bp->req_autoneg);
+ break;
- case FLOW_CTRL_TX:
- case FLOW_CTRL_RX:
- case FLOW_CTRL_BOTH:
- bp->flow_ctrl = bp->req_flow_ctrl;
- break;
+ case FLOW_CTRL_TX:
+ case FLOW_CTRL_RX:
+ case FLOW_CTRL_BOTH:
+ bp->flow_ctrl = bp->req_flow_ctrl;
+ break;
- case FLOW_CTRL_NONE:
- default:
- break;
+ case FLOW_CTRL_NONE:
+ default:
+ break;
+ }
}
}
DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", bp->flow_ctrl);
@@ -1548,9 +1803,9 @@ static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status)
bp->link_status = 0;
if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
- DP(NETIF_MSG_LINK, "link up\n");
+ DP(NETIF_MSG_LINK, "phy link up\n");
- bp->link_up = 1;
+ bp->phy_link_up = 1;
bp->link_status |= LINK_STATUS_LINK_UP;
if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
@@ -1659,20 +1914,20 @@ static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status)
bp->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
} else { /* link_down */
- DP(NETIF_MSG_LINK, "link down\n");
+ DP(NETIF_MSG_LINK, "phy link down\n");
- bp->link_up = 0;
+ bp->phy_link_up = 0;
bp->line_speed = 0;
bp->duplex = DUPLEX_FULL;
bp->flow_ctrl = 0;
}
- DP(NETIF_MSG_LINK, "gp_status 0x%x link_up %d\n"
+ DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %d\n"
DP_LEVEL " line_speed %d duplex %d flow_ctrl 0x%x"
" link_status 0x%x\n",
- gp_status, bp->link_up, bp->line_speed, bp->duplex, bp->flow_ctrl,
- bp->link_status);
+ gp_status, bp->phy_link_up, bp->line_speed, bp->duplex,
+ bp->flow_ctrl, bp->link_status);
}
static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g)
@@ -1680,40 +1935,40 @@ static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g)
int port = bp->port;
/* first reset all status
- * we asume only one line will be change at a time */
+ * we assume only one line will be change at a time */
bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_XGXS0_LINK_STATUS |
- NIG_SERDES0_LINK_STATUS |
- NIG_STATUS_INTERRUPT_XGXS0_LINK10G));
- if (bp->link_up) {
+ (NIG_STATUS_XGXS0_LINK10G |
+ NIG_STATUS_XGXS0_LINK_STATUS |
+ NIG_STATUS_SERDES0_LINK_STATUS));
+ if (bp->phy_link_up) {
if (is_10g) {
/* Disable the 10G link interrupt
* by writing 1 to the status register
*/
- DP(NETIF_MSG_LINK, "10G XGXS link up\n");
+ DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
bnx2x_bits_en(bp,
NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_STATUS_INTERRUPT_XGXS0_LINK10G);
+ NIG_STATUS_XGXS0_LINK10G);
} else if (bp->phy_flags & PHY_XGXS_FLAG) {
/* Disable the link interrupt
* by writing 1 to the relevant lane
* in the status register
*/
- DP(NETIF_MSG_LINK, "1G XGXS link up\n");
+ DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
bnx2x_bits_en(bp,
NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
((1 << bp->ser_lane) <<
- NIG_XGXS0_LINK_STATUS_SIZE));
+ NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
} else { /* SerDes */
- DP(NETIF_MSG_LINK, "SerDes link up\n");
+ DP(NETIF_MSG_LINK, "SerDes phy link up\n");
/* Disable the link interrupt
* by writing 1 to the status register
*/
bnx2x_bits_en(bp,
NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_SERDES0_LINK_STATUS);
+ NIG_STATUS_SERDES0_LINK_STATUS);
}
} else { /* link_down */
@@ -1724,91 +1979,182 @@ static int bnx2x_ext_phy_is_link_up(struct bnx2x *bp)
{
u32 ext_phy_type;
u32 ext_phy_addr;
- u32 local_phy;
- u32 val = 0;
+ u32 val1 = 0, val2;
u32 rx_sd, pcs_status;
if (bp->phy_flags & PHY_XGXS_FLAG) {
- local_phy = bp->phy_addr;
ext_phy_addr = ((bp->ext_phy_config &
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- bp->phy_addr = (u8)ext_phy_addr;
ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
DP(NETIF_MSG_LINK, "XGXS Direct\n");
- val = 1;
+ val1 = 1;
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
DP(NETIF_MSG_LINK, "XGXS 8705\n");
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val);
- DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val);
-
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val);
- DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val);
-
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_WIS_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_WIS_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
- val = (rx_sd & 0x1);
+ DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
+ val1 = (rx_sd & 0x1);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
DP(NETIF_MSG_LINK, "XGXS 8706\n");
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val);
- DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val);
-
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val);
- DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val);
-
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_PCS_DEVAD,
- EXT_PHY_OPT_PCS_STATUS, &pcs_status);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PCS_DEVAD,
+ EXT_PHY_OPT_PCS_STATUS, &pcs_status);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_AN_LINK_STATUS, &val2);
+
DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
- " pcs_status 0x%x\n", rx_sd, pcs_status);
- /* link is up if both bit 0 of pmd_rx and
- * bit 0 of pcs_status are set
+ " pcs_status 0x%x 1Gbps link_status 0x%x 0x%x\n",
+ rx_sd, pcs_status, val2, (val2 & (1<<1)));
+ /* link is up if both bit 0 of pmd_rx_sd and
+ * bit 0 of pcs_status are set, or if the autoneg bit
+ 1 is set
*/
- val = (rx_sd & pcs_status);
+ val1 = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+
+ /* clear the interrupt LASI status register */
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PCS_DEVAD,
+ EXT_PHY_KR_LASI_STATUS, &val2);
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PCS_DEVAD,
+ EXT_PHY_KR_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "KR LASI status 0x%x->0x%x\n",
+ val2, val1);
+ /* Check the LASI */
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0x9003, &val2);
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0x9003, &val1);
+ DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
+ val2, val1);
+ /* Check the link status */
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PCS_DEVAD,
+ EXT_PHY_KR_PCS_STATUS, &val2);
+ DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
+ /* Check the link status on 1.1.2 */
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_KR_STATUS, &val2);
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_KR_STATUS, &val1);
+ DP(NETIF_MSG_LINK,
+ "KR PMA status 0x%x->0x%x\n", val2, val1);
+ val1 = ((val1 & 4) == 4);
+ /* If 1G was requested assume the link is up */
+ if (!(bp->req_autoneg & AUTONEG_SPEED) &&
+ (bp->req_line_speed == SPEED_1000))
+ val1 = 1;
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val2);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK,
+ "10G-base-T LASI status 0x%x->0x%x\n", val2, val1);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_KR_STATUS, &val2);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_KR_STATUS, &val1);
+ DP(NETIF_MSG_LINK,
+ "10G-base-T PMA status 0x%x->0x%x\n", val2, val1);
+ val1 = ((val1 & 4) == 4);
+ /* if link is up
+ * print the AN outcome of the SFX7101 PHY
+ */
+ if (val1) {
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ 0x21, &val2);
+ DP(NETIF_MSG_LINK,
+ "SFX7101 AN status 0x%x->%s\n", val2,
+ (val2 & (1<<14)) ? "Master" : "Slave");
+ }
break;
default:
DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
bp->ext_phy_config);
- val = 0;
+ val1 = 0;
break;
}
- bp->phy_addr = local_phy;
} else { /* SerDes */
ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
switch (ext_phy_type) {
case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
DP(NETIF_MSG_LINK, "SerDes Direct\n");
- val = 1;
+ val1 = 1;
break;
case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
DP(NETIF_MSG_LINK, "SerDes 5482\n");
- val = 1;
+ val1 = 1;
break;
default:
DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
bp->ext_phy_config);
- val = 0;
+ val1 = 0;
break;
}
}
- return val;
+ return val1;
}
static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
@@ -1819,7 +2165,7 @@ static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
u32 wb_write[2];
u32 val;
- DP(NETIF_MSG_LINK, "enableing BigMAC\n");
+ DP(NETIF_MSG_LINK, "enabling BigMAC\n");
/* reset and unreset the BigMac */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
@@ -1933,6 +2279,35 @@ static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
bp->stats_state = STATS_STATE_ENABLE;
}
+static void bnx2x_bmac_rx_disable(struct bnx2x *bp)
+{
+ int port = bp->port;
+ u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
+ NIG_REG_INGRESS_BMAC0_MEM;
+ u32 wb_write[2];
+
+ /* Only if the bmac is out of reset */
+ if (REG_RD(bp, MISC_REG_RESET_REG_2) &
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)) {
+ /* Clear Rx Enable bit in BMAC_CONTROL register */
+#ifdef BNX2X_DMAE_RD
+ bnx2x_read_dmae(bp, bmac_addr +
+ BIGMAC_REGISTER_BMAC_CONTROL, 2);
+ wb_write[0] = *bnx2x_sp(bp, wb_data[0]);
+ wb_write[1] = *bnx2x_sp(bp, wb_data[1]);
+#else
+ wb_write[0] = REG_RD(bp,
+ bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL);
+ wb_write[1] = REG_RD(bp,
+ bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL + 4);
+#endif
+ wb_write[0] &= ~BMAC_CONTROL_RX_ENABLE;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
+ wb_write, 2);
+ msleep(1);
+ }
+}
+
static void bnx2x_emac_enable(struct bnx2x *bp)
{
int port = bp->port;
@@ -1940,7 +2315,7 @@ static void bnx2x_emac_enable(struct bnx2x *bp)
u32 val;
int timeout;
- DP(NETIF_MSG_LINK, "enableing EMAC\n");
+ DP(NETIF_MSG_LINK, "enabling EMAC\n");
/* reset and unreset the emac core */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
(MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
@@ -2033,7 +2408,7 @@ static void bnx2x_emac_enable(struct bnx2x *bp)
EMAC_TX_MODE_EXT_PAUSE_EN);
}
- /* KEEP_VLAN_TAG, promiscous */
+ /* KEEP_VLAN_TAG, promiscuous */
val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
EMAC_WR(EMAC_REG_EMAC_RX_MODE, val);
@@ -2161,7 +2536,6 @@ static void bnx2x_pbf_update(struct bnx2x *bp)
u32 count = 1000;
u32 pause = 0;
-
/* disable port */
REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
@@ -2232,7 +2606,7 @@ static void bnx2x_pbf_update(struct bnx2x *bp)
static void bnx2x_update_mng(struct bnx2x *bp)
{
if (!nomcp)
- SHMEM_WR(bp, drv_fw_mb[bp->port].link_status,
+ SHMEM_WR(bp, port_mb[bp->port].link_status,
bp->link_status);
}
@@ -2294,19 +2668,19 @@ static void bnx2x_link_down(struct bnx2x *bp)
DP(BNX2X_MSG_STATS, "stats_state - STOP\n");
}
- /* indicate link down */
+ /* indicate no mac active */
bp->phy_flags &= ~(PHY_BMAC_FLAG | PHY_EMAC_FLAG);
- /* reset BigMac */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+ /* update shared memory */
+ bnx2x_update_mng(bp);
- /* ignore drain flag interrupt */
/* activate nig drain */
NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
- /* update shared memory */
- bnx2x_update_mng(bp);
+ /* reset BigMac */
+ bnx2x_bmac_rx_disable(bp);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
/* indicate link down */
bnx2x_link_report(bp);
@@ -2317,14 +2691,15 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp);
/* This function is called upon link interrupt */
static void bnx2x_link_update(struct bnx2x *bp)
{
- u32 gp_status;
int port = bp->port;
int i;
+ u32 gp_status;
int link_10g;
- DP(NETIF_MSG_LINK, "port %x, is xgxs %x, stat_mask 0x%x,"
+ DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x,"
" int_mask 0x%x, saved_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
- " 10G %x, XGXS_LINK %x\n", port, (bp->phy_flags & PHY_XGXS_FLAG),
+ " 10G %x, XGXS_LINK %x\n", port,
+ (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), bp->nig_mask,
REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
@@ -2336,7 +2711,7 @@ static void bnx2x_link_update(struct bnx2x *bp)
might_sleep();
MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_GP_STATUS);
/* avoid fast toggling */
- for (i = 0 ; i < 10 ; i++) {
+ for (i = 0; i < 10; i++) {
msleep(10);
bnx2x_mdio22_read(bp, MDIO_GP_STATUS_TOP_AN_STATUS1,
&gp_status);
@@ -2351,7 +2726,8 @@ static void bnx2x_link_update(struct bnx2x *bp)
bnx2x_link_int_ack(bp, link_10g);
/* link is up only if both local phy and external phy are up */
- if (bp->link_up && bnx2x_ext_phy_is_link_up(bp)) {
+ bp->link_up = (bp->phy_link_up && bnx2x_ext_phy_is_link_up(bp));
+ if (bp->link_up) {
if (link_10g) {
bnx2x_bmac_enable(bp, 0);
bnx2x_leds_set(bp, SPEED_10000);
@@ -2427,7 +2803,9 @@ static void bnx2x_reset_unicore(struct bnx2x *bp)
}
}
- BNX2X_ERR("BUG! unicore is still in reset!\n");
+ BNX2X_ERR("BUG! %s (0x%x) is still in reset!\n",
+ (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
+ bp->phy_addr);
}
static void bnx2x_set_swap_lanes(struct bnx2x *bp)
@@ -2475,12 +2853,12 @@ static void bnx2x_set_parallel_detection(struct bnx2x *bp)
MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_10G_PARALLEL_DETECT);
bnx2x_mdio22_write(bp,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
bnx2x_mdio22_read(bp,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
- &control2);
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+ &control2);
if (bp->autoneg & AUTONEG_PARALLEL) {
control2 |=
@@ -2490,8 +2868,14 @@ static void bnx2x_set_parallel_detection(struct bnx2x *bp)
~MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
}
bnx2x_mdio22_write(bp,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
- control2);
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+ control2);
+
+ /* Disable parallel detection of HiG */
+ MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2);
+ bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
+ MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
+ MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
}
}
@@ -2625,7 +3009,7 @@ static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x *bp)
MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G);
/* set extended capabilities */
- if (bp->advertising & ADVERTISED_2500baseT_Full)
+ if (bp->advertising & ADVERTISED_2500baseX_Full)
val |= MDIO_OVER_1G_UP1_2_5G;
if (bp->advertising & ADVERTISED_10000baseT_Full)
val |= MDIO_OVER_1G_UP1_10G;
@@ -2641,20 +3025,91 @@ static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x *bp)
/* for AN, we are always publishing full duplex */
an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
- /* set pause */
- switch (bp->pause_mode) {
- case PAUSE_SYMMETRIC:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
- break;
- case PAUSE_ASYMMETRIC:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
- break;
- case PAUSE_BOTH:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- break;
- case PAUSE_NONE:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
- break;
+ /* resolve pause mode and advertisement
+ * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
+ if (bp->req_autoneg & AUTONEG_FLOW_CTRL) {
+ switch (bp->req_flow_ctrl) {
+ case FLOW_CTRL_AUTO:
+ if (bp->dev->mtu <= 4500) {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ bp->advertising |= (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ } else {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ bp->advertising |= ADVERTISED_Asym_Pause;
+ }
+ break;
+
+ case FLOW_CTRL_TX:
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ bp->advertising |= ADVERTISED_Asym_Pause;
+ break;
+
+ case FLOW_CTRL_RX:
+ if (bp->dev->mtu <= 4500) {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ bp->advertising |= (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ } else {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+ bp->advertising &= ~(ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ }
+ break;
+
+ case FLOW_CTRL_BOTH:
+ if (bp->dev->mtu <= 4500) {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ bp->advertising |= (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ } else {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ bp->advertising |= ADVERTISED_Asym_Pause;
+ }
+ break;
+
+ case FLOW_CTRL_NONE:
+ default:
+ an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+ bp->advertising &= ~(ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ break;
+ }
+ } else { /* forced mode */
+ switch (bp->req_flow_ctrl) {
+ case FLOW_CTRL_AUTO:
+ DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while"
+ " req_autoneg 0x%x\n",
+ bp->req_flow_ctrl, bp->req_autoneg);
+ break;
+
+ case FLOW_CTRL_TX:
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ bp->advertising |= ADVERTISED_Asym_Pause;
+ break;
+
+ case FLOW_CTRL_RX:
+ case FLOW_CTRL_BOTH:
+ an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ bp->advertising |= (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ break;
+
+ case FLOW_CTRL_NONE:
+ default:
+ an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+ bp->advertising &= ~(ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ break;
+ }
}
MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
@@ -2752,47 +3207,162 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x *bp)
static void bnx2x_link_int_enable(struct bnx2x *bp)
{
int port = bp->port;
+ u32 ext_phy_type;
+ u32 mask;
/* setting the status to report on link up
for either XGXS or SerDes */
bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_XGXS0_LINK_STATUS |
- NIG_STATUS_INTERRUPT_XGXS0_LINK10G |
- NIG_SERDES0_LINK_STATUS));
+ (NIG_STATUS_XGXS0_LINK10G |
+ NIG_STATUS_XGXS0_LINK_STATUS |
+ NIG_STATUS_SERDES0_LINK_STATUS));
if (bp->phy_flags & PHY_XGXS_FLAG) {
- /* TBD -
- * in force mode (not AN) we can enable just the relevant
- * interrupt
- * Even in AN we might enable only one according to the AN
- * speed mask
- */
- bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- (NIG_MASK_XGXS0_LINK_STATUS |
- NIG_MASK_XGXS0_LINK10G));
- DP(NETIF_MSG_LINK, "enable XGXS interrupt\n");
+ mask = (NIG_MASK_XGXS0_LINK10G |
+ NIG_MASK_XGXS0_LINK_STATUS);
+ DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
+ ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+ if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+ (ext_phy_type !=
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
+ mask |= NIG_MASK_MI_INT;
+ DP(NETIF_MSG_LINK, "enabled external phy int\n");
+ }
} else { /* SerDes */
- bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- NIG_MASK_SERDES0_LINK_STATUS);
- DP(NETIF_MSG_LINK, "enable SerDes interrupt\n");
+ mask = NIG_MASK_SERDES0_LINK_STATUS;
+ DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
+ ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
+ if ((ext_phy_type !=
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
+ (ext_phy_type !=
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
+ mask |= NIG_MASK_MI_INT;
+ DP(NETIF_MSG_LINK, "enabled external phy int\n");
+ }
}
+ bnx2x_bits_en(bp,
+ NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+ mask);
+ DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x,"
+ " int_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
+ " 10G %x, XGXS_LINK %x\n", port,
+ (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
+ REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
+ REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+ REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
+ REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c),
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)
+ );
+}
+
+static void bnx2x_bcm8072_external_rom_boot(struct bnx2x *bp)
+{
+ u32 ext_phy_addr = ((bp->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 fw_ver1, fw_ver2;
+
+ /* Need to wait 200ms after reset */
+ msleep(200);
+ /* Boot port from external ROM
+ * Set ser_boot_ctl bit in the MISC_CTRL1 register
+ */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ EXT_PHY_KR_MISC_CTRL1, 0x0001);
+
+ /* Reset internal microprocessor */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+ EXT_PHY_KR_ROM_RESET_INTERNAL_MP);
+ /* set micro reset = 0 */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+ EXT_PHY_KR_ROM_MICRO_RESET);
+ /* Reset internal microprocessor */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+ EXT_PHY_KR_ROM_RESET_INTERNAL_MP);
+ /* wait for 100ms for code download via SPI port */
+ msleep(100);
+
+ /* Clear ser_boot_ctl bit */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ EXT_PHY_KR_MISC_CTRL1, 0x0000);
+ /* Wait 100ms */
+ msleep(100);
+
+ /* Print the PHY FW version */
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0xca19, &fw_ver1);
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0xca1a, &fw_ver2);
+ DP(NETIF_MSG_LINK,
+ "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+}
+
+static void bnx2x_bcm8072_force_10G(struct bnx2x *bp)
+{
+ u32 ext_phy_addr = ((bp->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+ /* Force KR or KX */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL,
+ 0x2040);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL2,
+ 0x000b);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_PMD_CTRL,
+ 0x0000);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD, EXT_PHY_KR_CTRL,
+ 0x0000);
}
static void bnx2x_ext_phy_init(struct bnx2x *bp)
{
- int port = bp->port;
u32 ext_phy_type;
u32 ext_phy_addr;
- u32 local_phy;
+ u32 cnt;
+ u32 ctrl;
+ u32 val = 0;
if (bp->phy_flags & PHY_XGXS_FLAG) {
- local_phy = bp->phy_addr;
ext_phy_addr = ((bp->ext_phy_config &
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+ /* Make sure that the soft reset is off (expect for the 8072:
+ * due to the lock, it will be done inside the specific
+ * handling)
+ */
+ if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)) {
+ /* Wait for soft reset to get cleared upto 1 sec */
+ for (cnt = 0; cnt < 1000; cnt++) {
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_CNTL, &ctrl);
+ if (!(ctrl & (1<<15)))
+ break;
+ msleep(1);
+ }
+ DP(NETIF_MSG_LINK,
+ "control reg 0x%x (after %d ms)\n", ctrl, cnt);
+ }
+
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
DP(NETIF_MSG_LINK, "XGXS Direct\n");
@@ -2800,49 +3370,235 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp)
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
DP(NETIF_MSG_LINK, "XGXS 8705\n");
- bnx2x_bits_en(bp,
- NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- NIG_MASK_MI_INT);
- DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
- bp->phy_addr = ext_phy_type;
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_PMD_MISC_CNTL,
0x8288);
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_PHY_IDENTIFIER,
0x7fbf);
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_CMU_PLL_BYPASS,
0x0100);
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_WIS_DEVAD,
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_WIS_DEVAD,
EXT_PHY_OPT_LASI_CNTL, 0x1);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
DP(NETIF_MSG_LINK, "XGXS 8706\n");
- bnx2x_bits_en(bp,
- NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- NIG_MASK_MI_INT);
- DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
-
- bp->phy_addr = ext_phy_type;
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_PMD_DIGITAL_CNT,
- 0x400);
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+
+ if (!(bp->req_autoneg & AUTONEG_SPEED)) {
+ /* Force speed */
+ if (bp->req_line_speed == SPEED_10000) {
+ DP(NETIF_MSG_LINK,
+ "XGXS 8706 force 10Gbps\n");
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_PMD_DIGITAL_CNT,
+ 0x400);
+ } else {
+ /* Force 1Gbps */
+ DP(NETIF_MSG_LINK,
+ "XGXS 8706 force 1Gbps\n");
+
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_CNTL,
+ 0x0040);
+
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_CNTL2,
+ 0x000D);
+ }
+
+ /* Enable LASI */
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_CNTL,
+ 0x1);
+ } else {
+ /* AUTONEG */
+ /* Allow CL37 through CL73 */
+ DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_AN_CL37_CL73,
+ 0x040c);
+
+ /* Enable Full-Duplex advertisment on CL37 */
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_AN_CL37_FD,
+ 0x0020);
+ /* Enable CL37 AN */
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_AN_CL37_AN,
+ 0x1000);
+ /* Advertise 10G/1G support */
+ if (bp->advertising &
+ ADVERTISED_1000baseT_Full)
+ val = (1<<5);
+ if (bp->advertising &
+ ADVERTISED_10000baseT_Full)
+ val |= (1<<7);
+
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_AN_ADV, val);
+ /* Enable LASI */
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_CNTL,
+ 0x1);
+
+ /* Enable clause 73 AN */
+ bnx2x_mdio45_write(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_CNTL,
+ 0x1200);
+ }
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ /* Wait for soft reset to get cleared upto 1 sec */
+ for (cnt = 0; cnt < 1000; cnt++) {
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_CNTL, &ctrl);
+ if (!(ctrl & (1<<15)))
+ break;
+ msleep(1);
+ }
+ DP(NETIF_MSG_LINK,
+ "8072 control reg 0x%x (after %d ms)\n",
+ ctrl, cnt);
+
+ bnx2x_bcm8072_external_rom_boot(bp);
+ DP(NETIF_MSG_LINK, "Finshed loading 8072 KR ROM\n");
+
+ /* enable LASI */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0x9000, 0x0400);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ EXT_PHY_KR_LASI_CNTL, 0x0004);
+
+ /* If this is forced speed, set to KR or KX
+ * (all other are not supported)
+ */
+ if (!(bp->req_autoneg & AUTONEG_SPEED)) {
+ if (bp->req_line_speed == SPEED_10000) {
+ bnx2x_bcm8072_force_10G(bp);
+ DP(NETIF_MSG_LINK,
+ "Forced speed 10G on 8072\n");
+ /* unlock */
+ bnx2x_hw_unlock(bp,
+ HW_LOCK_RESOURCE_8072_MDIO);
+ break;
+ } else
+ val = (1<<5);
+ } else {
+
+ /* Advertise 10G/1G support */
+ if (bp->advertising &
+ ADVERTISED_1000baseT_Full)
+ val = (1<<5);
+ if (bp->advertising &
+ ADVERTISED_10000baseT_Full)
+ val |= (1<<7);
+ }
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ 0x11, val);
+ /* Add support for CL37 ( passive mode ) I */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ 0x8370, 0x040c);
+ /* Add support for CL37 ( passive mode ) II */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ 0xffe4, 0x20);
+ /* Add support for CL37 ( passive mode ) III */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ 0xffe0, 0x1000);
+ /* Restart autoneg */
+ msleep(500);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_CTRL, 0x1200);
+ DP(NETIF_MSG_LINK, "8072 Autoneg Restart: "
+ "1G %ssupported 10G %ssupported\n",
+ (val & (1<<5)) ? "" : "not ",
+ (val & (1<<7)) ? "" : "not ");
+
+ /* unlock */
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ DP(NETIF_MSG_LINK,
+ "Setting the SFX7101 LASI indication\n");
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_LASI_CNTL, 0x1);
+ DP(NETIF_MSG_LINK,
+ "Setting the SFX7101 LED to blink on traffic\n");
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ 0xC007, (1<<3));
+
+ /* read modify write pause advertizing */
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_AUTO_NEG_ADVERT, &val);
+ val &= ~EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH;
+ /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+ if (bp->advertising & ADVERTISED_Pause)
+ val |= EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE;
+
+ if (bp->advertising & ADVERTISED_Asym_Pause) {
+ val |=
+ EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC;
+ }
+ DP(NETIF_MSG_LINK, "SFX7101 AN advertize 0x%x\n", val);
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_AUTO_NEG_ADVERT, val);
+ /* Restart autoneg */
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_CTRL, &val);
+ val |= 0x200;
+ bnx2x_mdio45_write(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_CTRL, val);
break;
default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- bp->ext_phy_config);
+ BNX2X_ERR("BAD XGXS ext_phy_config 0x%x\n",
+ bp->ext_phy_config);
break;
}
- bp->phy_addr = local_phy;
} else { /* SerDes */
-/* ext_phy_addr = ((bp->ext_phy_config &
+/* ext_phy_addr = ((bp->ext_phy_config &
PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >>
PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT);
*/
@@ -2854,10 +3610,6 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp)
case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
DP(NETIF_MSG_LINK, "SerDes 5482\n");
- bnx2x_bits_en(bp,
- NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- NIG_MASK_MI_INT);
- DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
break;
default:
@@ -2871,8 +3623,22 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp)
static void bnx2x_ext_phy_reset(struct bnx2x *bp)
{
u32 ext_phy_type;
- u32 ext_phy_addr;
- u32 local_phy;
+ u32 ext_phy_addr = ((bp->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK);
+
+ /* The PHY reset is controled by GPIO 1
+ * Give it 1ms of reset pulse
+ */
+ if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) &&
+ (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) {
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ msleep(1);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+ }
if (bp->phy_flags & PHY_XGXS_FLAG) {
ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
@@ -2883,15 +3649,24 @@ static void bnx2x_ext_phy_reset(struct bnx2x *bp)
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8705/6\n");
- local_phy = bp->phy_addr;
- ext_phy_addr = ((bp->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- bp->phy_addr = (u8)ext_phy_addr;
- bnx2x_mdio45_write(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
+ bnx2x_mdio45_write(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_CNTL, 0xa040);
- bp->phy_addr = local_phy;
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ DP(NETIF_MSG_LINK, "XGXS 8072\n");
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0, 1<<15);
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
break;
default:
@@ -2930,6 +3705,7 @@ static void bnx2x_link_initialize(struct bnx2x *bp)
NIG_MASK_SERDES0_LINK_STATUS |
NIG_MASK_MI_INT));
+ /* Activate the external PHY */
bnx2x_ext_phy_reset(bp);
bnx2x_set_aer_mmd(bp);
@@ -2994,13 +3770,13 @@ static void bnx2x_link_initialize(struct bnx2x *bp)
/* AN enabled */
bnx2x_set_brcm_cl37_advertisment(bp);
- /* program duplex & pause advertisment (for aneg) */
+ /* program duplex & pause advertisement (for aneg) */
bnx2x_set_ieee_aneg_advertisment(bp);
/* enable autoneg */
bnx2x_set_autoneg(bp);
- /* enalbe and restart AN */
+ /* enable and restart AN */
bnx2x_restart_autoneg(bp);
}
@@ -3010,11 +3786,11 @@ static void bnx2x_link_initialize(struct bnx2x *bp)
bnx2x_initialize_sgmii_process(bp);
}
- /* enable the interrupt */
- bnx2x_link_int_enable(bp);
-
/* init ext phy and enable link state int */
bnx2x_ext_phy_init(bp);
+
+ /* enable the interrupt */
+ bnx2x_link_int_enable(bp);
}
static void bnx2x_phy_deassert(struct bnx2x *bp)
@@ -3073,6 +3849,11 @@ static int bnx2x_phy_init(struct bnx2x *bp)
static void bnx2x_link_reset(struct bnx2x *bp)
{
int port = bp->port;
+ u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK);
+
+ /* update shared memory */
+ bp->link_status = 0;
+ bnx2x_update_mng(bp);
/* disable attentions */
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
@@ -3081,21 +3862,45 @@ static void bnx2x_link_reset(struct bnx2x *bp)
NIG_MASK_SERDES0_LINK_STATUS |
NIG_MASK_MI_INT));
- bnx2x_ext_phy_reset(bp);
+ /* activate nig drain */
+ NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+
+ /* disable nig egress interface */
+ NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0);
+ NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
+
+ /* Stop BigMac rx */
+ bnx2x_bmac_rx_disable(bp);
+
+ /* disable emac */
+ NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+ msleep(10);
+
+ /* The PHY reset is controled by GPIO 1
+ * Hold it as output low
+ */
+ if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) &&
+ (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) {
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ DP(NETIF_MSG_LINK, "reset external PHY\n");
+ }
/* reset the SerDes/XGXS */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
(0x1ff << (port*16)));
- /* reset EMAC / BMAC and disable NIG interfaces */
- NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0);
- NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0);
+ /* reset BigMac */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
- NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0);
+ /* disable nig ingress interface */
+ NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0);
NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0);
- NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
- NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+ /* set link down */
+ bp->link_up = 0;
}
#ifdef BNX2X_XGXS_LB
@@ -3158,7 +3963,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
int port = bp->port;
DP(NETIF_MSG_TIMER,
- "spe (%x:%x) command %x hw_cid %x data (%x:%x) left %x\n",
+ "spe (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n",
(u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) +
(void *)bp->spq_prod_bd - (void *)bp->spq), command,
HW_CID(bp, cid), data_hi, data_lo, bp->spq_left);
@@ -3176,6 +3981,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
bnx2x_panic();
return -EBUSY;
}
+
/* CID needs port number to be encoded int it */
bp->spq_prod_bd->hdr.conn_and_cmd_data =
cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
@@ -3282,8 +4088,8 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
u32 igu_addr = (IGU_ADDR_ATTN_BITS_SET + IGU_PORT_BASE * port) * 8;
u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
MISC_REG_AEU_MASK_ATTN_FUNC_0;
- u32 nig_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
- NIG_REG_MASK_INTERRUPT_PORT0;
+ u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
+ NIG_REG_MASK_INTERRUPT_PORT0;
if (~bp->aeu_mask & (asserted & 0xff))
BNX2X_ERR("IGU ERROR\n");
@@ -3301,15 +4107,11 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
if (asserted & ATTN_HARD_WIRED_MASK) {
if (asserted & ATTN_NIG_FOR_FUNC) {
- u32 nig_status_port;
- u32 nig_int_addr = port ?
- NIG_REG_STATUS_INTERRUPT_PORT1 :
- NIG_REG_STATUS_INTERRUPT_PORT0;
- bp->nig_mask = REG_RD(bp, nig_mask_addr);
- REG_WR(bp, nig_mask_addr, 0);
+ /* save nig interrupt mask */
+ bp->nig_mask = REG_RD(bp, nig_int_mask_addr);
+ REG_WR(bp, nig_int_mask_addr, 0);
- nig_status_port = REG_RD(bp, nig_int_addr);
bnx2x_link_update(bp);
/* handle unicore attn? */
@@ -3362,15 +4164,132 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
/* now set back the mask */
if (asserted & ATTN_NIG_FOR_FUNC)
- REG_WR(bp, nig_mask_addr, bp->nig_mask);
+ REG_WR(bp, nig_int_mask_addr, bp->nig_mask);
}
-static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
+static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
{
int port = bp->port;
- int index;
+ int reg_offset;
+ u32 val;
+
+ if (attn & AEU_INPUTS_ATTN_BITS_SPIO5) {
+
+ reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
+ MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+
+ val = REG_RD(bp, reg_offset);
+ val &= ~AEU_INPUTS_ATTN_BITS_SPIO5;
+ REG_WR(bp, reg_offset, val);
+
+ BNX2X_ERR("SPIO5 hw attention\n");
+
+ switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+ case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ /* Fan failure attention */
+
+ /* The PHY reset is controled by GPIO 1 */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ /* Low power mode is controled by GPIO 2 */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ /* mark the failure */
+ bp->ext_phy_config &=
+ ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
+ bp->ext_phy_config |=
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
+ SHMEM_WR(bp,
+ dev_info.port_hw_config[port].
+ external_phy_config,
+ bp->ext_phy_config);
+ /* log the failure */
+ printk(KERN_ERR PFX "Fan Failure on Network"
+ " Controller %s has caused the driver to"
+ " shutdown the card to prevent permanent"
+ " damage. Please contact Dell Support for"
+ " assistance\n", bp->dev->name);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
+{
+ u32 val;
+
+ if (attn & BNX2X_DOORQ_ASSERT) {
+
+ val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
+ BNX2X_ERR("DB hw attention 0x%x\n", val);
+ /* DORQ discard attention */
+ if (val & 0x2)
+ BNX2X_ERR("FATAL error from DORQ\n");
+ }
+}
+
+static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn)
+{
+ u32 val;
+
+ if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) {
+
+ val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR);
+ BNX2X_ERR("CFC hw attention 0x%x\n", val);
+ /* CFC error attention */
+ if (val & 0x2)
+ BNX2X_ERR("FATAL error from CFC\n");
+ }
+
+ if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) {
+
+ val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0);
+ BNX2X_ERR("PXP hw attention 0x%x\n", val);
+ /* RQ_USDMDP_FIFO_OVERFLOW */
+ if (val & 0x18000)
+ BNX2X_ERR("FATAL error from PXP\n");
+ }
+}
+
+static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
+{
+ if (attn & EVEREST_GEN_ATTN_IN_USE_MASK) {
+
+ if (attn & BNX2X_MC_ASSERT_BITS) {
+
+ BNX2X_ERR("MC assert!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_7, 0);
+ bnx2x_panic();
+
+ } else if (attn & BNX2X_MCP_ASSERT) {
+
+ BNX2X_ERR("MCP assert!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_11, 0);
+ bnx2x_mc_assert(bp);
+
+ } else
+ BNX2X_ERR("Unknown HW assert! (attn 0x%x)\n", attn);
+ }
+
+ if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) {
+
+ REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff);
+ BNX2X_ERR("LATCHED attention 0x%x (masked)\n", attn);
+ }
+}
+
+static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
+{
struct attn_route attn;
struct attn_route group_mask;
+ int port = bp->port;
+ int index;
u32 reg_addr;
u32 val;
@@ -3391,64 +4310,14 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
DP(NETIF_MSG_HW, "group[%d]: %llx\n", index,
(unsigned long long)group_mask.sig[0]);
- if (attn.sig[3] & group_mask.sig[3] &
- EVEREST_GEN_ATTN_IN_USE_MASK) {
-
- if (attn.sig[3] & BNX2X_MC_ASSERT_BITS) {
-
- BNX2X_ERR("MC assert!\n");
- bnx2x_panic();
-
- } else if (attn.sig[3] & BNX2X_MCP_ASSERT) {
-
- BNX2X_ERR("MCP assert!\n");
- REG_WR(bp,
- MISC_REG_AEU_GENERAL_ATTN_11, 0);
- bnx2x_mc_assert(bp);
-
- } else {
- BNX2X_ERR("UNKOWEN HW ASSERT!\n");
- }
- }
-
- if (attn.sig[1] & group_mask.sig[1] &
- BNX2X_DOORQ_ASSERT) {
-
- val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
- BNX2X_ERR("DB hw attention 0x%x\n", val);
- /* DORQ discard attention */
- if (val & 0x2)
- BNX2X_ERR("FATAL error from DORQ\n");
- }
-
- if (attn.sig[2] & group_mask.sig[2] &
- AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) {
-
- val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR);
- BNX2X_ERR("CFC hw attention 0x%x\n", val);
- /* CFC error attention */
- if (val & 0x2)
- BNX2X_ERR("FATAL error from CFC\n");
- }
-
- if (attn.sig[2] & group_mask.sig[2] &
- AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) {
-
- val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0);
- BNX2X_ERR("PXP hw attention 0x%x\n", val);
- /* RQ_USDMDP_FIFO_OVERFLOW */
- if (val & 0x18000)
- BNX2X_ERR("FATAL error from PXP\n");
- }
-
- if (attn.sig[3] & group_mask.sig[3] &
- EVEREST_LATCHED_ATTN_IN_USE_MASK) {
-
- REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL,
- 0x7ff);
- DP(NETIF_MSG_HW, "got latched bits 0x%x\n",
- attn.sig[3]);
- }
+ bnx2x_attn_int_deasserted3(bp,
+ attn.sig[3] & group_mask.sig[3]);
+ bnx2x_attn_int_deasserted1(bp,
+ attn.sig[1] & group_mask.sig[1]);
+ bnx2x_attn_int_deasserted2(bp,
+ attn.sig[2] & group_mask.sig[2]);
+ bnx2x_attn_int_deasserted0(bp,
+ attn.sig[0] & group_mask.sig[0]);
if ((attn.sig[0] & group_mask.sig[0] &
HW_INTERRUT_ASSERT_SET_0) ||
@@ -3456,7 +4325,15 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
HW_INTERRUT_ASSERT_SET_1) ||
(attn.sig[2] & group_mask.sig[2] &
HW_INTERRUT_ASSERT_SET_2))
- BNX2X_ERR("FATAL HW block attention\n");
+ BNX2X_ERR("FATAL HW block attention"
+ " set0 0x%x set1 0x%x"
+ " set2 0x%x\n",
+ (attn.sig[0] & group_mask.sig[0] &
+ HW_INTERRUT_ASSERT_SET_0),
+ (attn.sig[1] & group_mask.sig[1] &
+ HW_INTERRUT_ASSERT_SET_1),
+ (attn.sig[2] & group_mask.sig[2] &
+ HW_INTERRUT_ASSERT_SET_2));
if ((attn.sig[0] & group_mask.sig[0] &
HW_PRTY_ASSERT_SET_0) ||
@@ -3464,7 +4341,7 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
HW_PRTY_ASSERT_SET_1) ||
(attn.sig[2] & group_mask.sig[2] &
HW_PRTY_ASSERT_SET_2))
- BNX2X_ERR("FATAL HW block parity atention\n");
+ BNX2X_ERR("FATAL HW block parity attention\n");
}
}
@@ -3529,7 +4406,7 @@ static void bnx2x_sp_task(struct work_struct *work)
/* Return here if interrupt is disabled */
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
+ DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n");
return;
}
@@ -3539,12 +4416,11 @@ static void bnx2x_sp_task(struct work_struct *work)
DP(NETIF_MSG_INTR, "got a slowpath interrupt (updated %x)\n", status);
- if (status & 0x1) {
- /* HW attentions */
+ /* HW attentions */
+ if (status & 0x1)
bnx2x_attn_int(bp);
- }
- /* CStorm events: query_stats, cfc delete ramrods */
+ /* CStorm events: query_stats, port delete ramrod */
if (status & 0x2)
bp->stat_pending = 0;
@@ -3558,6 +4434,7 @@ static void bnx2x_sp_task(struct work_struct *work)
IGU_INT_NOP, 1);
bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx),
IGU_INT_ENABLE, 1);
+
}
static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
@@ -3567,11 +4444,11 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
/* Return here if interrupt is disabled */
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
+ DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n");
return IRQ_HANDLED;
}
- bnx2x_ack_sb(bp, 16, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
+ bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -3906,7 +4783,7 @@ static void bnx2x_stop_stats(struct bnx2x *bp)
while (bp->stats_state != STATS_STATE_DISABLE) {
if (!timeout) {
- BNX2X_ERR("timeout wating for stats stop\n");
+ BNX2X_ERR("timeout waiting for stats stop\n");
break;
}
timeout--;
@@ -4173,39 +5050,37 @@ static void bnx2x_update_net_stats(struct bnx2x *bp)
nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi);
- nstats->tx_bytes =
- bnx2x_hilo(&estats->total_bytes_transmitted_hi);
+ nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
- nstats->rx_dropped = estats->checksum_discard +
- estats->mac_discard;
+ nstats->rx_dropped = estats->checksum_discard + estats->mac_discard;
nstats->tx_dropped = 0;
nstats->multicast =
bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
- nstats->collisions =
- estats->single_collision_transmit_frames +
- estats->multiple_collision_transmit_frames +
- estats->late_collision_frames +
- estats->excessive_collision_frames;
+ nstats->collisions = estats->single_collision_transmit_frames +
+ estats->multiple_collision_transmit_frames +
+ estats->late_collision_frames +
+ estats->excessive_collision_frames;
nstats->rx_length_errors = estats->runt_packets_received +
estats->jabber_packets_received;
- nstats->rx_over_errors = estats->no_buff_discard;
+ nstats->rx_over_errors = estats->brb_discard +
+ estats->brb_truncate_discard;
nstats->rx_crc_errors = estats->crc_receive_errors;
nstats->rx_frame_errors = estats->alignment_errors;
- nstats->rx_fifo_errors = estats->brb_discard +
- estats->brb_truncate_discard;
+ nstats->rx_fifo_errors = estats->no_buff_discard;
nstats->rx_missed_errors = estats->xxoverflow_discard;
nstats->rx_errors = nstats->rx_length_errors +
nstats->rx_over_errors +
nstats->rx_crc_errors +
nstats->rx_frame_errors +
- nstats->rx_fifo_errors;
+ nstats->rx_fifo_errors +
+ nstats->rx_missed_errors;
nstats->tx_aborted_errors = estats->late_collision_frames +
- estats->excessive_collision_frames;
+ estats->excessive_collision_frames;
nstats->tx_carrier_errors = estats->false_carrier_detections;
nstats->tx_fifo_errors = 0;
nstats->tx_heartbeat_errors = 0;
@@ -4334,7 +5209,7 @@ static void bnx2x_timer(unsigned long data)
return;
if (atomic_read(&bp->intr_sem) != 0)
- goto bnx2x_restart_timer;
+ goto timer_restart;
if (poll) {
struct bnx2x_fastpath *fp = &bp->fp[0];
@@ -4344,7 +5219,7 @@ static void bnx2x_timer(unsigned long data)
rc = bnx2x_rx_int(fp, 1000);
}
- if (!nomcp && (bp->bc_ver >= 0x040003)) {
+ if (!nomcp) {
int port = bp->port;
u32 drv_pulse;
u32 mcp_pulse;
@@ -4353,9 +5228,9 @@ static void bnx2x_timer(unsigned long data)
bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK;
/* TBD - add SYSTEM_TIME */
drv_pulse = bp->fw_drv_pulse_wr_seq;
- SHMEM_WR(bp, drv_fw_mb[port].drv_pulse_mb, drv_pulse);
+ SHMEM_WR(bp, func_mb[port].drv_pulse_mb, drv_pulse);
- mcp_pulse = (SHMEM_RD(bp, drv_fw_mb[port].mcp_pulse_mb) &
+ mcp_pulse = (SHMEM_RD(bp, func_mb[port].mcp_pulse_mb) &
MCP_PULSE_SEQ_MASK);
/* The delta between driver pulse and mcp response
* should be 1 (before mcp response) or 0 (after mcp response)
@@ -4369,11 +5244,11 @@ static void bnx2x_timer(unsigned long data)
}
if (bp->stats_state == STATS_STATE_DISABLE)
- goto bnx2x_restart_timer;
+ goto timer_restart;
bnx2x_update_stats(bp);
-bnx2x_restart_timer:
+timer_restart:
mod_timer(&bp->timer, jiffies + bp->current_interval);
}
@@ -4438,6 +5313,9 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
atten_status_block);
def_sb->atten_status_block.status_block_id = id;
+ bp->def_att_idx = 0;
+ bp->attn_state = 0;
+
reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
@@ -4472,6 +5350,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
u_def_status_block);
def_sb->u_def_status_block.status_block_id = id;
+ bp->def_u_idx = 0;
+
REG_WR(bp, BAR_USTRORM_INTMEM +
USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
REG_WR(bp, BAR_USTRORM_INTMEM +
@@ -4489,6 +5369,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
c_def_status_block);
def_sb->c_def_status_block.status_block_id = id;
+ bp->def_c_idx = 0;
+
REG_WR(bp, BAR_CSTRORM_INTMEM +
CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
REG_WR(bp, BAR_CSTRORM_INTMEM +
@@ -4506,6 +5388,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
t_def_status_block);
def_sb->t_def_status_block.status_block_id = id;
+ bp->def_t_idx = 0;
+
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
REG_WR(bp, BAR_TSTRORM_INTMEM +
@@ -4523,6 +5407,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
x_def_status_block);
def_sb->x_def_status_block.status_block_id = id;
+ bp->def_x_idx = 0;
+
REG_WR(bp, BAR_XSTRORM_INTMEM +
XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
REG_WR(bp, BAR_XSTRORM_INTMEM +
@@ -4535,6 +5421,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
REG_WR16(bp, BAR_XSTRORM_INTMEM +
XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
+ bp->stat_pending = 0;
+
bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
}
@@ -4626,7 +5514,7 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
fp->rx_bd_prod = fp->rx_comp_prod = ring_prod;
fp->rx_pkt = fp->rx_calls = 0;
- /* Warning! this will genrate an interrupt (to the TSTORM) */
+ /* Warning! this will generate an interrupt (to the TSTORM) */
/* must only be done when chip is initialized */
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_RCQ_PROD_OFFSET(port, j), ring_prod);
@@ -4678,7 +5566,6 @@ static void bnx2x_init_sp_ring(struct bnx2x *bp)
bp->spq_left = MAX_SPQ_PENDING;
bp->spq_prod_idx = 0;
- bp->dsb_sp_prod_idx = 0;
bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX;
bp->spq_prod_bd = bp->spq;
bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT;
@@ -4755,6 +5642,42 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
}
+static void bnx2x_set_client_config(struct bnx2x *bp)
+{
+#ifdef BCM_VLAN
+ int mode = bp->rx_mode;
+#endif
+ int i, port = bp->port;
+ struct tstorm_eth_client_config tstorm_client = {0};
+
+ tstorm_client.mtu = bp->dev->mtu;
+ tstorm_client.statistics_counter_id = 0;
+ tstorm_client.config_flags =
+ TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
+#ifdef BCM_VLAN
+ if (mode && bp->vlgrp) {
+ tstorm_client.config_flags |=
+ TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
+ DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
+ }
+#endif
+ if (mode != BNX2X_RX_MODE_PROMISC)
+ tstorm_client.drop_flags =
+ TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR;
+
+ for_each_queue(bp, i) {
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_CLIENT_CONFIG_OFFSET(port, i),
+ ((u32 *)&tstorm_client)[0]);
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_CLIENT_CONFIG_OFFSET(port, i) + 4,
+ ((u32 *)&tstorm_client)[1]);
+ }
+
+/* DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n",
+ ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */
+}
+
static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
{
int mode = bp->rx_mode;
@@ -4794,41 +5717,9 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i,
((u32 *)&tstorm_mac_filter)[i]); */
}
-}
-static void bnx2x_set_client_config(struct bnx2x *bp, int client_id)
-{
-#ifdef BCM_VLAN
- int mode = bp->rx_mode;
-#endif
- int port = bp->port;
- struct tstorm_eth_client_config tstorm_client = {0};
-
- tstorm_client.mtu = bp->dev->mtu;
- tstorm_client.statistics_counter_id = 0;
- tstorm_client.config_flags =
- TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
-#ifdef BCM_VLAN
- if (mode && bp->vlgrp) {
- tstorm_client.config_flags |=
- TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
- DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
- }
-#endif
- tstorm_client.drop_flags = (TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR |
- TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR |
- TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR |
- TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR);
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, client_id),
- ((u32 *)&tstorm_client)[0]);
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) + 4,
- ((u32 *)&tstorm_client)[1]);
-
-/* DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n",
- ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */
+ if (mode != BNX2X_RX_MODE_NONE)
+ bnx2x_set_client_config(bp);
}
static void bnx2x_init_internal(struct bnx2x *bp)
@@ -4836,7 +5727,6 @@ static void bnx2x_init_internal(struct bnx2x *bp)
int port = bp->port;
struct tstorm_eth_function_common_config tstorm_config = {0};
struct stats_indication_flags stats_flags = {0};
- int i;
if (is_multi(bp)) {
tstorm_config.config_flags = MULTI_FLAGS;
@@ -4850,13 +5740,9 @@ static void bnx2x_init_internal(struct bnx2x *bp)
/* DP(NETIF_MSG_IFUP, "tstorm_config: 0x%08x\n",
(*(u32 *)&tstorm_config)); */
- bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx untill link is up */
+ bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
bnx2x_set_storm_rx_mode(bp);
- for_each_queue(bp, i)
- bnx2x_set_client_config(bp, i);
-
-
stats_flags.collect_eth = cpu_to_le32(1);
REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port),
@@ -4902,7 +5788,7 @@ static void bnx2x_nic_init(struct bnx2x *bp)
bnx2x_init_internal(bp);
bnx2x_init_stats(bp);
bnx2x_init_ind_table(bp);
- bnx2x_enable_int(bp);
+ bnx2x_int_enable(bp);
}
@@ -5265,8 +6151,10 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
if (mode & 0x1) { /* init common */
DP(BNX2X_MSG_MCP, "starting common init func %d mode %x\n",
func, mode);
- REG_WR(bp, MISC_REG_RESET_REG_1, 0xffffffff);
- REG_WR(bp, MISC_REG_RESET_REG_2, 0xfffc);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+ 0xffffffff);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+ 0xfffc);
bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100);
@@ -5359,7 +6247,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 8);
#endif
bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
- /* softrest pulse */
+ /* soft reset pulse */
REG_WR(bp, QM_REG_SOFT_RESET, 1);
REG_WR(bp, QM_REG_SOFT_RESET, 0);
@@ -5413,7 +6301,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
REG_WR(bp, SRC_REG_SOFT_RST, 1);
for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
REG_WR(bp, i, 0xc0cac01a);
- /* TODO: repleace with something meaningfull */
+ /* TODO: replace with something meaningful */
}
/* SRCH COMMON comes here */
REG_WR(bp, SRC_REG_SOFT_RST, 0);
@@ -5486,6 +6374,28 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
enable_blocks_attention(bp);
/* enable_blocks_parity(bp); */
+ switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+ case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ /* Fan failure is indicated by SPIO 5 */
+ bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
+ MISC_REGISTERS_SPIO_INPUT_HI_Z);
+
+ /* set to active low mode */
+ val = REG_RD(bp, MISC_REG_SPIO_INT);
+ val |= ((1 << MISC_REGISTERS_SPIO_5) <<
+ MISC_REGISTERS_SPIO_INT_OLD_SET_POS);
+ REG_WR(bp, MISC_REG_SPIO_INT, val);
+
+ /* enable interrupt to signal the IGU */
+ val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN);
+ val |= (1 << MISC_REGISTERS_SPIO_5);
+ REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val);
+ break;
+
+ default:
+ break;
+ }
+
} /* end of common init */
/* per port init */
@@ -5645,9 +6555,21 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
/* Port MCP comes here */
/* Port DMAE comes here */
+ switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+ case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ /* add SPIO 5 to group 0 */
+ val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+ val |= AEU_INPUTS_ATTN_BITS_SPIO5;
+ REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val);
+ break;
+
+ default:
+ break;
+ }
+
bnx2x_link_reset(bp);
- /* Reset pciex errors for debug */
+ /* Reset PCIE errors for debug */
REG_WR(bp, 0x2114, 0xffffffff);
REG_WR(bp, 0x2120, 0xffffffff);
REG_WR(bp, 0x2814, 0xffffffff);
@@ -5669,9 +6591,9 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
port = bp->port;
bp->fw_drv_pulse_wr_seq =
- (SHMEM_RD(bp, drv_fw_mb[port].drv_pulse_mb) &
+ (SHMEM_RD(bp, func_mb[port].drv_pulse_mb) &
DRV_PULSE_SEQ_MASK);
- bp->fw_mb = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_param);
+ bp->fw_mb = SHMEM_RD(bp, func_mb[port].fw_mb_param);
DP(BNX2X_MSG_MCP, "drv_pulse 0x%x fw_mb 0x%x\n",
bp->fw_drv_pulse_wr_seq, bp->fw_mb);
} else {
@@ -5681,16 +6603,15 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
return 0;
}
-
-/* send the MCP a request, block untill there is a reply */
+/* send the MCP a request, block until there is a reply */
static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
{
- u32 rc = 0;
- u32 seq = ++bp->fw_seq;
int port = bp->port;
+ u32 seq = ++bp->fw_seq;
+ u32 rc = 0;
- SHMEM_WR(bp, drv_fw_mb[port].drv_mb_header, command|seq);
- DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", command|seq);
+ SHMEM_WR(bp, func_mb[port].drv_mb_header, (command | seq));
+ DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
/* let the FW do it's magic ... */
msleep(100); /* TBD */
@@ -5698,19 +6619,20 @@ static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
if (CHIP_REV_IS_SLOW(bp))
msleep(900);
- rc = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_header);
-
+ rc = SHMEM_RD(bp, func_mb[port].fw_mb_header);
DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq);
/* is this a reply to our command? */
if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
rc &= FW_MSG_CODE_MASK;
+
} else {
/* FW BUG! */
BNX2X_ERR("FW failed to respond!\n");
bnx2x_fw_dump(bp);
rc = 0;
}
+
return rc;
}
@@ -5869,7 +6791,7 @@ static int bnx2x_alloc_mem(struct bnx2x *bp)
for (i = 0; i < 16*1024; i += 64)
* (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64;
- /* now sixup the last line in the block to point to the next block */
+ /* now fixup the last line in the block to point to the next block */
*(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping;
/* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */
@@ -5950,22 +6872,19 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp)
int i;
free_irq(bp->msix_table[0].vector, bp->dev);
- DP(NETIF_MSG_IFDOWN, "rleased sp irq (%d)\n",
+ DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n",
bp->msix_table[0].vector);
for_each_queue(bp, i) {
- DP(NETIF_MSG_IFDOWN, "about to rlease fp #%d->%d irq "
+ DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq "
"state(%x)\n", i, bp->msix_table[i + 1].vector,
bnx2x_fp(bp, i, state));
- if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED) {
-
- free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]);
- bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_CLOSED;
-
- } else
- DP(NETIF_MSG_IFDOWN, "irq not freed\n");
+ if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED)
+ BNX2X_ERR("IRQ of fp #%d being freed while "
+ "state != closed\n", i);
+ free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]);
}
}
@@ -5995,7 +6914,7 @@ static int bnx2x_enable_msix(struct bnx2x *bp)
if (pci_enable_msix(bp->pdev, &bp->msix_table[0],
bp->num_queues + 1)){
- BNX2X_ERR("failed to enable msix\n");
+ BNX2X_LOG("failed to enable MSI-X\n");
return -1;
}
@@ -6010,11 +6929,8 @@ static int bnx2x_enable_msix(struct bnx2x *bp)
static int bnx2x_req_msix_irqs(struct bnx2x *bp)
{
-
int i, rc;
- DP(NETIF_MSG_IFUP, "about to request sp irq\n");
-
rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0,
bp->dev->name, bp->dev);
@@ -6029,7 +6945,8 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
bp->dev->name, &bp->fp[i]);
if (rc) {
- BNX2X_ERR("request fp #%d irq failed\n", i);
+ BNX2X_ERR("request fp #%d irq failed "
+ "rc %d\n", i, rc);
bnx2x_free_msix_irqs(bp);
return -EBUSY;
}
@@ -6109,8 +7026,8 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
/* can take a while if any port is running */
int timeout = 500;
- /* DP("waiting for state to become %d on IDX [%d]\n",
- state, sb_idx); */
+ DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
+ poll ? "polling" : "waiting", state, idx);
might_sleep();
@@ -6128,7 +7045,7 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
mb(); /* state is changed by bnx2x_sp_event()*/
- if (*state_p != state)
+ if (*state_p == state)
return 0;
timeout--;
@@ -6136,17 +7053,17 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
}
-
/* timeout! */
- BNX2X_ERR("timeout waiting for ramrod %d on %d\n", state, idx);
- return -EBUSY;
+ BNX2X_ERR("timeout %s for state %x on IDX [%d]\n",
+ poll ? "polling" : "waiting", state, idx);
+ return -EBUSY;
}
static int bnx2x_setup_leading(struct bnx2x *bp)
{
- /* reset IGU staae */
+ /* reset IGU state */
bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
/* SETUP ramrod */
@@ -6162,12 +7079,13 @@ static int bnx2x_setup_multi(struct bnx2x *bp, int index)
/* reset IGU state */
bnx2x_ack_sb(bp, index, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+ /* SETUP ramrod */
bp->fp[index].state = BNX2X_FP_STATE_OPENING;
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0);
/* Wait for completion */
return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
- &(bp->fp[index].state), 1);
+ &(bp->fp[index].state), 0);
}
@@ -6177,8 +7095,8 @@ static void bnx2x_set_rx_mode(struct net_device *dev);
static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
{
- int rc;
- int i = 0;
+ u32 load_code;
+ int i;
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
@@ -6188,26 +7106,28 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
initialized, otherwise - not.
*/
if (!nomcp) {
- rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
- if (rc == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+ if (!load_code) {
+ BNX2X_ERR("MCP response failure, unloading\n");
+ return -EBUSY;
+ }
+ if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+ BNX2X_ERR("MCP refused load request, unloading\n");
return -EBUSY; /* other port in diagnostic mode */
}
} else {
- rc = FW_MSG_CODE_DRV_LOAD_COMMON;
+ load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
}
- DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues);
-
/* if we can't use msix we only need one fp,
* so try to enable msix with the requested number of fp's
* and fallback to inta with one fp
*/
if (req_irq) {
-
if (use_inta) {
bp->num_queues = 1;
} else {
- if (use_multi > 1 && use_multi <= 16)
+ if ((use_multi > 1) && (use_multi <= 16))
/* user requested number */
bp->num_queues = use_multi;
else if (use_multi == 1)
@@ -6216,15 +7136,17 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
bp->num_queues = 1;
if (bnx2x_enable_msix(bp)) {
- /* faild to enable msix */
+ /* failed to enable msix */
bp->num_queues = 1;
if (use_multi)
- BNX2X_ERR("Muti requested but failed"
+ BNX2X_ERR("Multi requested but failed"
" to enable MSI-X\n");
}
}
}
+ DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues);
+
if (bnx2x_alloc_mem(bp))
return -ENOMEM;
@@ -6232,13 +7154,13 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
if (bp->flags & USING_MSIX_FLAG) {
if (bnx2x_req_msix_irqs(bp)) {
pci_disable_msix(bp->pdev);
- goto out_error;
+ goto load_error;
}
} else {
if (bnx2x_req_irq(bp)) {
BNX2X_ERR("IRQ request failed, aborting\n");
- goto out_error;
+ goto load_error;
}
}
}
@@ -6249,31 +7171,25 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
/* Initialize HW */
- if (bnx2x_function_init(bp, (rc == FW_MSG_CODE_DRV_LOAD_COMMON))) {
+ if (bnx2x_function_init(bp,
+ (load_code == FW_MSG_CODE_DRV_LOAD_COMMON))) {
BNX2X_ERR("HW init failed, aborting\n");
- goto out_error;
+ goto load_error;
}
atomic_set(&bp->intr_sem, 0);
- /* Reenable SP tasklet */
- /*if (bp->sp_task_en) { */
- /* tasklet_enable(&bp->sp_task);*/
- /*} else { */
- /* bp->sp_task_en = 1; */
- /*} */
/* Setup NIC internals and enable interrupts */
bnx2x_nic_init(bp);
/* Send LOAD_DONE command to MCP */
if (!nomcp) {
- rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
- DP(NETIF_MSG_IFUP, "rc = 0x%x\n", rc);
- if (!rc) {
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
+ if (!load_code) {
BNX2X_ERR("MCP response failure, unloading\n");
- goto int_disable;
+ goto load_int_disable;
}
}
@@ -6285,11 +7201,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
napi_enable(&bnx2x_fp(bp, i, napi));
if (bnx2x_setup_leading(bp))
- goto stop_netif;
+ goto load_stop_netif;
for_each_nondefault_queue(bp, i)
if (bnx2x_setup_multi(bp, i))
- goto stop_netif;
+ goto load_stop_netif;
bnx2x_set_mac_addr(bp);
@@ -6313,42 +7229,24 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
return 0;
-stop_netif:
+load_stop_netif:
for_each_queue(bp, i)
napi_disable(&bnx2x_fp(bp, i, napi));
-int_disable:
- bnx2x_disable_int_sync(bp);
+load_int_disable:
+ bnx2x_int_disable_sync(bp);
bnx2x_free_skbs(bp);
bnx2x_free_irq(bp);
-out_error:
+load_error:
bnx2x_free_mem(bp);
/* TBD we really need to reset the chip
if we want to recover from this */
- return rc;
+ return -EBUSY;
}
-static void bnx2x_netif_stop(struct bnx2x *bp)
-{
- int i;
-
- bp->rx_mode = BNX2X_RX_MODE_NONE;
- bnx2x_set_storm_rx_mode(bp);
-
- bnx2x_disable_int_sync(bp);
- bnx2x_link_reset(bp);
-
- for_each_queue(bp, i)
- napi_disable(&bnx2x_fp(bp, i, napi));
-
- if (netif_running(bp->dev)) {
- netif_tx_disable(bp->dev);
- bp->dev->trans_start = jiffies; /* prevent tx timeout */
- }
-}
static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
{
@@ -6401,20 +7299,20 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index)
int rc;
- /* halt the connnection */
+ /* halt the connection */
bp->fp[index].state = BNX2X_FP_STATE_HALTING;
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, 0, 0);
rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
&(bp->fp[index].state), 1);
- if (rc) /* timout */
+ if (rc) /* timeout */
return rc;
/* delete cfc entry */
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1);
- return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_DELETED, index,
+ return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index,
&(bp->fp[index].state), 1);
}
@@ -6422,8 +7320,8 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index)
static void bnx2x_stop_leading(struct bnx2x *bp)
{
-
- /* if the other port is hadling traffic,
+ u16 dsb_sp_prod_idx;
+ /* if the other port is handling traffic,
this can take a lot of time */
int timeout = 500;
@@ -6437,52 +7335,71 @@ static void bnx2x_stop_leading(struct bnx2x *bp)
&(bp->fp[0].state), 1))
return;
- bp->dsb_sp_prod_idx = *bp->dsb_sp_prod;
+ dsb_sp_prod_idx = *bp->dsb_sp_prod;
- /* Send CFC_DELETE ramrod */
+ /* Send PORT_DELETE ramrod */
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1);
- /*
- Wait for completion.
+ /* Wait for completion to arrive on default status block
we are going to reset the chip anyway
so there is not much to do if this times out
*/
- while (bp->dsb_sp_prod_idx == *bp->dsb_sp_prod && timeout) {
- timeout--;
- msleep(1);
+ while ((dsb_sp_prod_idx == *bp->dsb_sp_prod) && timeout) {
+ timeout--;
+ msleep(1);
}
-
+ if (!timeout) {
+ DP(NETIF_MSG_IFDOWN, "timeout polling for completion "
+ "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n",
+ *bp->dsb_sp_prod, dsb_sp_prod_idx);
+ }
+ bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
+ bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
}
-static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq)
+
+static int bnx2x_nic_unload(struct bnx2x *bp, int free_irq)
{
u32 reset_code = 0;
- int rc;
- int i;
+ int i, timeout;
bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
- /* Calling flush_scheduled_work() may deadlock because
- * linkwatch_event() may be on the workqueue and it will try to get
- * the rtnl_lock which we are holding.
- */
+ del_timer_sync(&bp->timer);
- while (bp->in_reset_task)
- msleep(1);
+ bp->rx_mode = BNX2X_RX_MODE_NONE;
+ bnx2x_set_storm_rx_mode(bp);
- /* Delete the timer: do it before disabling interrupts, as it
- may be stil STAT_QUERY ramrod pending after stopping the timer */
- del_timer_sync(&bp->timer);
+ if (netif_running(bp->dev)) {
+ netif_tx_disable(bp->dev);
+ bp->dev->trans_start = jiffies; /* prevent tx timeout */
+ }
+
+ /* Wait until all fast path tasks complete */
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ timeout = 1000;
+ while (bnx2x_has_work(fp) && (timeout--))
+ msleep(1);
+ if (!timeout)
+ BNX2X_ERR("timeout waiting for queue[%d]\n", i);
+ }
/* Wait until stat ramrod returns and all SP tasks complete */
- while (bp->stat_pending && (bp->spq_left != MAX_SPQ_PENDING))
+ timeout = 1000;
+ while ((bp->stat_pending || (bp->spq_left != MAX_SPQ_PENDING)) &&
+ (timeout--))
msleep(1);
- /* Stop fast path, disable MAC, disable interrupts, disable napi */
- bnx2x_netif_stop(bp);
+ for_each_queue(bp, i)
+ napi_disable(&bnx2x_fp(bp, i, napi));
+ /* Disable interrupts after Tx and Rx are disabled on stack level */
+ bnx2x_int_disable_sync(bp);
if (bp->flags & NO_WOL_FLAG)
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
+
else if (bp->wol) {
u32 emac_base = bp->port ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
u8 *mac_addr = bp->dev->dev_addr;
@@ -6499,28 +7416,37 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq)
EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;
+
} else
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
+ /* Close multi and leading connections */
for_each_nondefault_queue(bp, i)
if (bnx2x_stop_multi(bp, i))
- goto error;
-
+ goto unload_error;
bnx2x_stop_leading(bp);
+ if ((bp->state != BNX2X_STATE_CLOSING_WAIT4_UNLOAD) ||
+ (bp->fp[0].state != BNX2X_FP_STATE_CLOSED)) {
+ DP(NETIF_MSG_IFDOWN, "failed to close leading properly!"
+ "state 0x%x fp[0].state 0x%x",
+ bp->state, bp->fp[0].state);
+ }
+
+unload_error:
+ bnx2x_link_reset(bp);
-error:
if (!nomcp)
- rc = bnx2x_fw_command(bp, reset_code);
+ reset_code = bnx2x_fw_command(bp, reset_code);
else
- rc = FW_MSG_CODE_DRV_UNLOAD_COMMON;
+ reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
/* Release IRQs */
- if (fre_irq)
+ if (free_irq)
bnx2x_free_irq(bp);
/* Reset the chip */
- bnx2x_reset_chip(bp, rc);
+ bnx2x_reset_chip(bp, reset_code);
/* Report UNLOAD_DONE to MCP */
if (!nomcp)
@@ -6531,8 +7457,7 @@ error:
bnx2x_free_mem(bp);
bp->state = BNX2X_STATE_CLOSED;
- /* Set link down */
- bp->link_up = 0;
+
netif_carrier_off(bp->dev);
return 0;
@@ -6568,7 +7493,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseT_Full |
+ SUPPORTED_2500baseX_Full |
SUPPORTED_TP | SUPPORTED_FIBRE |
SUPPORTED_Autoneg |
SUPPORTED_Pause |
@@ -6581,10 +7506,10 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
bp->phy_flags |= PHY_SGMII_FLAG;
- bp->supported |= (/* SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |*/
+ bp->supported |= (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_TP | SUPPORTED_FIBRE |
SUPPORTED_Autoneg |
@@ -6620,7 +7545,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseT_Full |
+ SUPPORTED_2500baseX_Full |
SUPPORTED_10000baseT_Full |
SUPPORTED_TP | SUPPORTED_FIBRE |
SUPPORTED_Autoneg |
@@ -6629,12 +7554,46 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
+ ext_phy_type);
+
+ bp->supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8705/6)\n",
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
+ ext_phy_type);
+
+ bp->supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
ext_phy_type);
bp->supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
+ ext_phy_type);
+
+ bp->supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
@@ -6691,7 +7650,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
SUPPORTED_1000baseT_Full);
if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
- bp->supported &= ~SUPPORTED_2500baseT_Full;
+ bp->supported &= ~SUPPORTED_2500baseX_Full;
if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
bp->supported &= ~SUPPORTED_10000baseT_Full;
@@ -6711,13 +7670,8 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
bp->req_line_speed = 0;
bp->advertising = bp->supported;
} else {
- u32 ext_phy_type;
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
- if ((ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
- (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) {
+ if (XGXS_EXT_PHY_TYPE(bp) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) {
/* force 10G, no AN */
bp->req_line_speed = SPEED_10000;
bp->advertising =
@@ -6734,8 +7688,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_10M_FULL:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) {
+ if (bp->supported & SUPPORTED_10baseT_Full) {
bp->req_line_speed = SPEED_10;
bp->advertising = (ADVERTISED_10baseT_Full |
ADVERTISED_TP);
@@ -6749,8 +7702,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_10M_HALF:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
+ if (bp->supported & SUPPORTED_10baseT_Half) {
bp->req_line_speed = SPEED_10;
bp->req_duplex = DUPLEX_HALF;
bp->advertising = (ADVERTISED_10baseT_Half |
@@ -6765,8 +7717,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_100M_FULL:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
+ if (bp->supported & SUPPORTED_100baseT_Full) {
bp->req_line_speed = SPEED_100;
bp->advertising = (ADVERTISED_100baseT_Full |
ADVERTISED_TP);
@@ -6780,8 +7731,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_100M_HALF:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
+ if (bp->supported & SUPPORTED_100baseT_Half) {
bp->req_line_speed = SPEED_100;
bp->req_duplex = DUPLEX_HALF;
bp->advertising = (ADVERTISED_100baseT_Half |
@@ -6796,8 +7746,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_1G:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
+ if (bp->supported & SUPPORTED_1000baseT_Full) {
bp->req_line_speed = SPEED_1000;
bp->advertising = (ADVERTISED_1000baseT_Full |
ADVERTISED_TP);
@@ -6811,10 +7760,9 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_2_5G:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) {
+ if (bp->supported & SUPPORTED_2500baseX_Full) {
bp->req_line_speed = SPEED_2500;
- bp->advertising = (ADVERTISED_2500baseT_Full |
+ bp->advertising = (ADVERTISED_2500baseX_Full |
ADVERTISED_TP);
} else {
BNX2X_ERR("NVRAM config error. "
@@ -6828,15 +7776,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
case PORT_FEATURE_LINK_SPEED_10G_CX4:
case PORT_FEATURE_LINK_SPEED_10G_KX4:
case PORT_FEATURE_LINK_SPEED_10G_KR:
- if (!(bp->phy_flags & PHY_XGXS_FLAG)) {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " phy_flags 0x%x\n",
- bp->link_config, bp->phy_flags);
- return;
- }
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
+ if (bp->supported & SUPPORTED_10000baseT_Full) {
bp->req_line_speed = SPEED_10000;
bp->advertising = (ADVERTISED_10000baseT_Full |
ADVERTISED_FIBRE);
@@ -6863,43 +7803,13 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
bp->req_flow_ctrl = (bp->link_config &
PORT_FEATURE_FLOW_CONTROL_MASK);
- /* Please refer to Table 28B-3 of the 802.3ab-1999 spec */
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
+ if ((bp->req_flow_ctrl == FLOW_CTRL_AUTO) &&
+ (bp->supported & SUPPORTED_Autoneg))
bp->req_autoneg |= AUTONEG_FLOW_CTRL;
- if (bp->dev->mtu <= 4500) {
- bp->pause_mode = PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- } else {
- bp->pause_mode = PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
- }
- break;
-
- case FLOW_CTRL_TX:
- bp->pause_mode = PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
- break;
-
- case FLOW_CTRL_RX:
- case FLOW_CTRL_BOTH:
- bp->pause_mode = PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
- case FLOW_CTRL_NONE:
- default:
- bp->pause_mode = PAUSE_NONE;
- bp->advertising &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
- }
- BNX2X_DEV_INFO("req_autoneg 0x%x req_flow_ctrl 0x%x\n"
- KERN_INFO " pause_mode %d advertising 0x%x\n",
- bp->req_autoneg, bp->req_flow_ctrl,
- bp->pause_mode, bp->advertising);
+ BNX2X_DEV_INFO("req_autoneg 0x%x req_flow_ctrl 0x%x"
+ " advertising 0x%x\n",
+ bp->req_autoneg, bp->req_flow_ctrl, bp->advertising);
}
static void bnx2x_get_hwinfo(struct bnx2x *bp)
@@ -6933,15 +7843,15 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp)
val = SHMEM_RD(bp, validity_map[port]);
if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
!= (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
- BNX2X_ERR("MCP validity signature bad\n");
+ BNX2X_ERR("BAD MCP validity signature\n");
- bp->fw_seq = (SHMEM_RD(bp, drv_fw_mb[port].drv_mb_header) &
+ bp->fw_seq = (SHMEM_RD(bp, func_mb[port].drv_mb_header) &
DRV_MSG_SEQ_NUMBER_MASK);
bp->hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
-
+ bp->board = SHMEM_RD(bp, dev_info.shared_hw_config.board);
bp->serdes_config =
- SHMEM_RD(bp, dev_info.port_hw_config[bp->port].serdes_config);
+ SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config);
bp->lane_config =
SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
bp->ext_phy_config =
@@ -6954,13 +7864,13 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp)
bp->link_config =
SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
- BNX2X_DEV_INFO("hw_config (%08x) serdes_config (%08x)\n"
+ BNX2X_DEV_INFO("hw_config (%08x) board (%08x) serdes_config (%08x)\n"
KERN_INFO " lane_config (%08x) ext_phy_config (%08x)\n"
KERN_INFO " speed_cap_mask (%08x) link_config (%08x)"
" fw_seq (%08x)\n",
- bp->hw_config, bp->serdes_config, bp->lane_config,
- bp->ext_phy_config, bp->speed_cap_mask,
- bp->link_config, bp->fw_seq);
+ bp->hw_config, bp->board, bp->serdes_config,
+ bp->lane_config, bp->ext_phy_config,
+ bp->speed_cap_mask, bp->link_config, bp->fw_seq);
switch_cfg = (bp->link_config & PORT_FEATURE_CONNECTED_SWITCH_MASK);
bnx2x_link_settings_supported(bp, switch_cfg);
@@ -7014,14 +7924,8 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp)
return;
set_mac: /* only supposed to happen on emulation/FPGA */
- BNX2X_ERR("warning constant MAC workaround active\n");
- bp->dev->dev_addr[0] = 0;
- bp->dev->dev_addr[1] = 0x50;
- bp->dev->dev_addr[2] = 0xc2;
- bp->dev->dev_addr[3] = 0x2c;
- bp->dev->dev_addr[4] = 0x71;
- bp->dev->dev_addr[5] = port ? 0x0d : 0x0e;
-
+ BNX2X_ERR("warning rendom MAC workaround active\n");
+ random_ether_addr(bp->dev->dev_addr);
memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6);
}
@@ -7048,19 +7952,34 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
}
if (bp->phy_flags & PHY_XGXS_FLAG) {
- cmd->port = PORT_FIBRE;
- } else {
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ cmd->port = PORT_FIBRE;
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ cmd->port = PORT_TP;
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+ bp->ext_phy_config);
+ }
+ } else
cmd->port = PORT_TP;
- }
cmd->phy_address = bp->phy_addr;
cmd->transceiver = XCVR_INTERNAL;
- if (bp->req_autoneg & AUTONEG_SPEED) {
+ if (bp->req_autoneg & AUTONEG_SPEED)
cmd->autoneg = AUTONEG_ENABLE;
- } else {
+ else
cmd->autoneg = AUTONEG_DISABLE;
- }
cmd->maxtxpkt = 0;
cmd->maxrxpkt = 0;
@@ -7091,8 +8010,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
switch (cmd->port) {
case PORT_TP:
- if (!(bp->supported & SUPPORTED_TP))
+ if (!(bp->supported & SUPPORTED_TP)) {
+ DP(NETIF_MSG_LINK, "TP not supported\n");
return -EINVAL;
+ }
if (bp->phy_flags & PHY_XGXS_FLAG) {
bnx2x_link_reset(bp);
@@ -7102,8 +8023,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
case PORT_FIBRE:
- if (!(bp->supported & SUPPORTED_FIBRE))
+ if (!(bp->supported & SUPPORTED_FIBRE)) {
+ DP(NETIF_MSG_LINK, "FIBRE not supported\n");
return -EINVAL;
+ }
if (!(bp->phy_flags & PHY_XGXS_FLAG)) {
bnx2x_link_reset(bp);
@@ -7113,12 +8036,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
default:
+ DP(NETIF_MSG_LINK, "Unknown port type\n");
return -EINVAL;
}
if (cmd->autoneg == AUTONEG_ENABLE) {
- if (!(bp->supported & SUPPORTED_Autoneg))
+ if (!(bp->supported & SUPPORTED_Autoneg)) {
+ DP(NETIF_MSG_LINK, "Aotoneg not supported\n");
return -EINVAL;
+ }
/* advertise the requested speed and duplex if supported */
cmd->advertising &= bp->supported;
@@ -7133,14 +8059,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
switch (cmd->speed) {
case SPEED_10:
if (cmd->duplex == DUPLEX_FULL) {
- if (!(bp->supported & SUPPORTED_10baseT_Full))
+ if (!(bp->supported &
+ SUPPORTED_10baseT_Full)) {
+ DP(NETIF_MSG_LINK,
+ "10M full not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_10baseT_Full |
ADVERTISED_TP);
} else {
- if (!(bp->supported & SUPPORTED_10baseT_Half))
+ if (!(bp->supported &
+ SUPPORTED_10baseT_Half)) {
+ DP(NETIF_MSG_LINK,
+ "10M half not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_10baseT_Half |
ADVERTISED_TP);
@@ -7150,15 +8084,21 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case SPEED_100:
if (cmd->duplex == DUPLEX_FULL) {
if (!(bp->supported &
- SUPPORTED_100baseT_Full))
+ SUPPORTED_100baseT_Full)) {
+ DP(NETIF_MSG_LINK,
+ "100M full not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_100baseT_Full |
ADVERTISED_TP);
} else {
if (!(bp->supported &
- SUPPORTED_100baseT_Half))
+ SUPPORTED_100baseT_Half)) {
+ DP(NETIF_MSG_LINK,
+ "100M half not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_100baseT_Half |
ADVERTISED_TP);
@@ -7166,39 +8106,54 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
case SPEED_1000:
- if (cmd->duplex != DUPLEX_FULL)
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(NETIF_MSG_LINK, "1G half not supported\n");
return -EINVAL;
+ }
- if (!(bp->supported & SUPPORTED_1000baseT_Full))
+ if (!(bp->supported & SUPPORTED_1000baseT_Full)) {
+ DP(NETIF_MSG_LINK, "1G full not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_1000baseT_Full |
ADVERTISED_TP);
break;
case SPEED_2500:
- if (cmd->duplex != DUPLEX_FULL)
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(NETIF_MSG_LINK,
+ "2.5G half not supported\n");
return -EINVAL;
+ }
- if (!(bp->supported & SUPPORTED_2500baseT_Full))
+ if (!(bp->supported & SUPPORTED_2500baseX_Full)) {
+ DP(NETIF_MSG_LINK,
+ "2.5G full not supported\n");
return -EINVAL;
+ }
- advertising = (ADVERTISED_2500baseT_Full |
+ advertising = (ADVERTISED_2500baseX_Full |
ADVERTISED_TP);
break;
case SPEED_10000:
- if (cmd->duplex != DUPLEX_FULL)
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(NETIF_MSG_LINK, "10G half not supported\n");
return -EINVAL;
+ }
- if (!(bp->supported & SUPPORTED_10000baseT_Full))
+ if (!(bp->supported & SUPPORTED_10000baseT_Full)) {
+ DP(NETIF_MSG_LINK, "10G full not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_10000baseT_Full |
ADVERTISED_FIBRE);
break;
default:
+ DP(NETIF_MSG_LINK, "Unsupported speed\n");
return -EINVAL;
}
@@ -7398,8 +8353,7 @@ static void bnx2x_disable_nvram_access(struct bnx2x *bp)
static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
u32 cmd_flags)
{
- int rc;
- int count, i;
+ int count, i, rc;
u32 val;
/* build the command word */
@@ -7452,13 +8406,13 @@ static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
DP(NETIF_MSG_NVM,
- "Invalid paramter: offset 0x%x buf_size 0x%x\n",
+ "Invalid parameter: offset 0x%x buf_size 0x%x\n",
offset, buf_size);
return -EINVAL;
}
if (offset + buf_size > bp->flash_size) {
- DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+ DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
" buf_size (0x%x) > flash_size (0x%x)\n",
offset, buf_size, bp->flash_size);
return -EINVAL;
@@ -7519,8 +8473,7 @@ static int bnx2x_get_eeprom(struct net_device *dev,
static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
u32 cmd_flags)
{
- int rc;
- int count, i;
+ int count, i, rc;
/* build the command word */
cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR;
@@ -7557,7 +8510,7 @@ static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
return rc;
}
-#define BYTE_OFFSET(offset) (8 * (offset & 0x03))
+#define BYTE_OFFSET(offset) (8 * (offset & 0x03))
static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
int buf_size)
@@ -7568,7 +8521,7 @@ static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
u32 val;
if (offset + buf_size > bp->flash_size) {
- DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+ DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
" buf_size (0x%x) > flash_size (0x%x)\n",
offset, buf_size, bp->flash_size);
return -EINVAL;
@@ -7621,13 +8574,13 @@ static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf,
if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
DP(NETIF_MSG_NVM,
- "Invalid paramter: offset 0x%x buf_size 0x%x\n",
+ "Invalid parameter: offset 0x%x buf_size 0x%x\n",
offset, buf_size);
return -EINVAL;
}
if (offset + buf_size > bp->flash_size) {
- DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+ DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
" buf_size (0x%x) > flash_size (0x%x)\n",
offset, buf_size, bp->flash_size);
return -EINVAL;
@@ -7788,52 +8741,29 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n",
epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
- bp->req_flow_ctrl = FLOW_CTRL_AUTO;
if (epause->autoneg) {
- bp->req_autoneg |= AUTONEG_FLOW_CTRL;
- if (bp->dev->mtu <= 4500) {
- bp->pause_mode = PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- } else {
- bp->pause_mode = PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
+ if (!(bp->supported & SUPPORTED_Autoneg)) {
+ DP(NETIF_MSG_LINK, "Aotoneg not supported\n");
+ return -EINVAL;
}
- } else {
+ bp->req_autoneg |= AUTONEG_FLOW_CTRL;
+ } else
bp->req_autoneg &= ~AUTONEG_FLOW_CTRL;
- if (epause->rx_pause)
- bp->req_flow_ctrl |= FLOW_CTRL_RX;
- if (epause->tx_pause)
- bp->req_flow_ctrl |= FLOW_CTRL_TX;
-
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- bp->req_flow_ctrl = FLOW_CTRL_NONE;
- bp->pause_mode = PAUSE_NONE;
- bp->advertising &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
+ bp->req_flow_ctrl = FLOW_CTRL_AUTO;
- case FLOW_CTRL_TX:
- bp->pause_mode = PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
- break;
+ if (epause->rx_pause)
+ bp->req_flow_ctrl |= FLOW_CTRL_RX;
+ if (epause->tx_pause)
+ bp->req_flow_ctrl |= FLOW_CTRL_TX;
- case FLOW_CTRL_RX:
- case FLOW_CTRL_BOTH:
- bp->pause_mode = PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
- }
- }
+ if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) &&
+ (bp->req_flow_ctrl == FLOW_CTRL_AUTO))
+ bp->req_flow_ctrl = FLOW_CTRL_NONE;
- DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_flow_ctrl 0x%x\n"
- DP_LEVEL " pause_mode %d advertising 0x%x\n",
- bp->req_autoneg, bp->req_flow_ctrl, bp->pause_mode,
- bp->advertising);
+ DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_flow_ctrl 0x%x\n",
+ bp->req_autoneg, bp->req_flow_ctrl);
bnx2x_stop_stats(bp);
bnx2x_link_initialize(bp);
@@ -7906,81 +8836,87 @@ static void bnx2x_self_test(struct net_device *dev,
static struct {
char string[ETH_GSTRING_LEN];
} bnx2x_stats_str_arr[BNX2X_NUM_STATS] = {
- { "rx_bytes"}, /* 0 */
- { "rx_error_bytes"}, /* 1 */
- { "tx_bytes"}, /* 2 */
- { "tx_error_bytes"}, /* 3 */
- { "rx_ucast_packets"}, /* 4 */
- { "rx_mcast_packets"}, /* 5 */
- { "rx_bcast_packets"}, /* 6 */
- { "tx_ucast_packets"}, /* 7 */
- { "tx_mcast_packets"}, /* 8 */
- { "tx_bcast_packets"}, /* 9 */
- { "tx_mac_errors"}, /* 10 */
- { "tx_carrier_errors"}, /* 11 */
- { "rx_crc_errors"}, /* 12 */
- { "rx_align_errors"}, /* 13 */
- { "tx_single_collisions"}, /* 14 */
- { "tx_multi_collisions"}, /* 15 */
- { "tx_deferred"}, /* 16 */
- { "tx_excess_collisions"}, /* 17 */
- { "tx_late_collisions"}, /* 18 */
- { "tx_total_collisions"}, /* 19 */
- { "rx_fragments"}, /* 20 */
- { "rx_jabbers"}, /* 21 */
- { "rx_undersize_packets"}, /* 22 */
- { "rx_oversize_packets"}, /* 23 */
- { "rx_xon_frames"}, /* 24 */
- { "rx_xoff_frames"}, /* 25 */
- { "tx_xon_frames"}, /* 26 */
- { "tx_xoff_frames"}, /* 27 */
- { "rx_mac_ctrl_frames"}, /* 28 */
- { "rx_filtered_packets"}, /* 29 */
- { "rx_discards"}, /* 30 */
+ { "rx_bytes"},
+ { "rx_error_bytes"},
+ { "tx_bytes"},
+ { "tx_error_bytes"},
+ { "rx_ucast_packets"},
+ { "rx_mcast_packets"},
+ { "rx_bcast_packets"},
+ { "tx_ucast_packets"},
+ { "tx_mcast_packets"},
+ { "tx_bcast_packets"},
+ { "tx_mac_errors"}, /* 10 */
+ { "tx_carrier_errors"},
+ { "rx_crc_errors"},
+ { "rx_align_errors"},
+ { "tx_single_collisions"},
+ { "tx_multi_collisions"},
+ { "tx_deferred"},
+ { "tx_excess_collisions"},
+ { "tx_late_collisions"},
+ { "tx_total_collisions"},
+ { "rx_fragments"}, /* 20 */
+ { "rx_jabbers"},
+ { "rx_undersize_packets"},
+ { "rx_oversize_packets"},
+ { "rx_xon_frames"},
+ { "rx_xoff_frames"},
+ { "tx_xon_frames"},
+ { "tx_xoff_frames"},
+ { "rx_mac_ctrl_frames"},
+ { "rx_filtered_packets"},
+ { "rx_discards"}, /* 30 */
+ { "brb_discard"},
+ { "brb_truncate"},
+ { "xxoverflow"}
};
#define STATS_OFFSET32(offset_name) \
(offsetof(struct bnx2x_eth_stats, offset_name) / 4)
static unsigned long bnx2x_stats_offset_arr[BNX2X_NUM_STATS] = {
- STATS_OFFSET32(total_bytes_received_hi), /* 0 */
- STATS_OFFSET32(stat_IfHCInBadOctets_hi), /* 1 */
- STATS_OFFSET32(total_bytes_transmitted_hi), /* 2 */
- STATS_OFFSET32(stat_IfHCOutBadOctets_hi), /* 3 */
- STATS_OFFSET32(total_unicast_packets_received_hi), /* 4 */
- STATS_OFFSET32(total_multicast_packets_received_hi), /* 5 */
- STATS_OFFSET32(total_broadcast_packets_received_hi), /* 6 */
- STATS_OFFSET32(total_unicast_packets_transmitted_hi), /* 7 */
- STATS_OFFSET32(total_multicast_packets_transmitted_hi), /* 8 */
- STATS_OFFSET32(total_broadcast_packets_transmitted_hi), /* 9 */
- STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */
- STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors), /* 11 */
- STATS_OFFSET32(crc_receive_errors), /* 12 */
- STATS_OFFSET32(alignment_errors), /* 13 */
- STATS_OFFSET32(single_collision_transmit_frames), /* 14 */
- STATS_OFFSET32(multiple_collision_transmit_frames), /* 15 */
- STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions), /* 16 */
- STATS_OFFSET32(excessive_collision_frames), /* 17 */
- STATS_OFFSET32(late_collision_frames), /* 18 */
- STATS_OFFSET32(number_of_bugs_found_in_stats_spec), /* 19 */
- STATS_OFFSET32(runt_packets_received), /* 20 */
- STATS_OFFSET32(jabber_packets_received), /* 21 */
- STATS_OFFSET32(error_runt_packets_received), /* 22 */
- STATS_OFFSET32(error_jabber_packets_received), /* 23 */
- STATS_OFFSET32(pause_xon_frames_received), /* 24 */
- STATS_OFFSET32(pause_xoff_frames_received), /* 25 */
- STATS_OFFSET32(pause_xon_frames_transmitted), /* 26 */
- STATS_OFFSET32(pause_xoff_frames_transmitted), /* 27 */
- STATS_OFFSET32(control_frames_received), /* 28 */
- STATS_OFFSET32(mac_filter_discard), /* 29 */
- STATS_OFFSET32(no_buff_discard), /* 30 */
+ STATS_OFFSET32(total_bytes_received_hi),
+ STATS_OFFSET32(stat_IfHCInBadOctets_hi),
+ STATS_OFFSET32(total_bytes_transmitted_hi),
+ STATS_OFFSET32(stat_IfHCOutBadOctets_hi),
+ STATS_OFFSET32(total_unicast_packets_received_hi),
+ STATS_OFFSET32(total_multicast_packets_received_hi),
+ STATS_OFFSET32(total_broadcast_packets_received_hi),
+ STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ STATS_OFFSET32(total_multicast_packets_transmitted_hi),
+ STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
+ STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */
+ STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors),
+ STATS_OFFSET32(crc_receive_errors),
+ STATS_OFFSET32(alignment_errors),
+ STATS_OFFSET32(single_collision_transmit_frames),
+ STATS_OFFSET32(multiple_collision_transmit_frames),
+ STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions),
+ STATS_OFFSET32(excessive_collision_frames),
+ STATS_OFFSET32(late_collision_frames),
+ STATS_OFFSET32(number_of_bugs_found_in_stats_spec),
+ STATS_OFFSET32(runt_packets_received), /* 20 */
+ STATS_OFFSET32(jabber_packets_received),
+ STATS_OFFSET32(error_runt_packets_received),
+ STATS_OFFSET32(error_jabber_packets_received),
+ STATS_OFFSET32(pause_xon_frames_received),
+ STATS_OFFSET32(pause_xoff_frames_received),
+ STATS_OFFSET32(pause_xon_frames_transmitted),
+ STATS_OFFSET32(pause_xoff_frames_transmitted),
+ STATS_OFFSET32(control_frames_received),
+ STATS_OFFSET32(mac_filter_discard),
+ STATS_OFFSET32(no_buff_discard), /* 30 */
+ STATS_OFFSET32(brb_discard),
+ STATS_OFFSET32(brb_truncate_discard),
+ STATS_OFFSET32(xxoverflow_discard)
};
static u8 bnx2x_stats_len_arr[BNX2X_NUM_STATS] = {
8, 0, 8, 0, 8, 8, 8, 8, 8, 8,
4, 0, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4,
+ 4, 4, 4, 4
};
static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
@@ -8138,9 +9074,7 @@ static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
* net_device service functions
*/
-/* Called with rtnl_lock from vlan functions and also netif_tx_lock
- * from set_multicast.
- */
+/* called with netif_tx_lock from set_multicast */
static void bnx2x_set_rx_mode(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
@@ -8314,7 +9248,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
ETH_TX_BD_ETH_ADDR_TYPE_SHIFT);
tx_bd->general_data |= 1; /* header nbd */
- /* remeber the first bd of the packet */
+ /* remember the first bd of the packet */
tx_buf->first_bd = bd_prod;
DP(NETIF_MSG_TX_QUEUED,
@@ -8334,7 +9268,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* for now NS flag is not used in Linux */
pbd->global_data = (len |
- ((skb->protocol == ETH_P_8021Q) <<
+ ((skb->protocol == ntohs(ETH_P_8021Q)) <<
ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
pbd->ip_hlen = ip_hdrlen(skb) / 2;
pbd->total_hlen = cpu_to_le16(len + pbd->ip_hlen);
@@ -8343,7 +9277,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_bd->bd_flags.as_bitfield |=
ETH_TX_BD_FLAGS_TCP_CSUM;
- pbd->tcp_flags = htonl(tcp_flag_word(skb)) & 0xFFFF;
+ pbd->tcp_flags = pbd_tcp_flags(skb);
pbd->total_hlen += cpu_to_le16(tcp_hdrlen(skb) / 2);
pbd->tcp_pseudo_csum = swab16(th->check);
@@ -8387,7 +9321,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb_shinfo(skb)->gso_size &&
(skb->len > (bp->dev->mtu + ETH_HLEN))) {
- int hlen = 2 * le32_to_cpu(pbd->total_hlen);
+ int hlen = 2 * le16_to_cpu(pbd->total_hlen);
DP(NETIF_MSG_TX_QUEUED,
"TSO packet len %d hlen %d total len %d tso size %d\n",
@@ -8427,7 +9361,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_bd->vlan = cpu_to_le16(pkt_prod);
/* this marks the bd
* as one that has no individual mapping
- * the FW ignors this flag in a bd not maked start
+ * the FW ignores this flag in a bd not marked start
*/
tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_SW_LSO;
DP(NETIF_MSG_TX_QUEUED,
@@ -8504,9 +9438,11 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %u bd %d\n", nbd, bd_prod);
- fp->hw_tx_prods->bds_prod += cpu_to_le16(nbd);
+ fp->hw_tx_prods->bds_prod =
+ cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd);
mb(); /* FW restriction: must not reorder writing nbd and packets */
- fp->hw_tx_prods->packets_prod += cpu_to_le32(1);
+ fp->hw_tx_prods->packets_prod =
+ cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
DOORBELL(bp, fp_index, 0);
mmiowb();
@@ -8525,11 +9461,6 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
-static struct net_device_stats *bnx2x_get_stats(struct net_device *dev)
-{
- return &dev->stats;
-}
-
/* Called with rtnl_lock */
static int bnx2x_open(struct net_device *dev)
{
@@ -8543,16 +9474,13 @@ static int bnx2x_open(struct net_device *dev)
/* Called with rtnl_lock */
static int bnx2x_close(struct net_device *dev)
{
- int rc;
struct bnx2x *bp = netdev_priv(dev);
/* Unload the driver, release IRQs */
- rc = bnx2x_nic_unload(bp, 1);
- if (rc) {
- BNX2X_ERR("bnx2x_nic_unload failed: %d\n", rc);
- return rc;
- }
- bnx2x_set_power_state(bp, PCI_D3hot);
+ bnx2x_nic_unload(bp, 1);
+
+ if (!CHIP_REV_IS_SLOW(bp))
+ bnx2x_set_power_state(bp, PCI_D3hot);
return 0;
}
@@ -8584,7 +9512,7 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
case SIOCGMIIPHY:
data->phy_id = bp->phy_addr;
- /* fallthru */
+ /* fallthrough */
case SIOCGMIIREG: {
u32 mii_regval;
@@ -8633,7 +9561,7 @@ static int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
/* This does not race with packet allocation
- * because the actuall alloc size is
+ * because the actual alloc size is
* only updated as part of load
*/
dev->mtu = new_mtu;
@@ -8666,7 +9594,7 @@ static void bnx2x_vlan_rx_register(struct net_device *dev,
bp->vlgrp = vlgrp;
if (netif_running(dev))
- bnx2x_set_rx_mode(dev);
+ bnx2x_set_client_config(bp);
}
#endif
@@ -8695,14 +9623,18 @@ static void bnx2x_reset_task(struct work_struct *work)
if (!netif_running(bp->dev))
return;
- bp->in_reset_task = 1;
+ rtnl_lock();
- bnx2x_netif_stop(bp);
+ if (bp->state != BNX2X_STATE_OPEN) {
+ DP(NETIF_MSG_TX_ERR, "state is %x, returning\n", bp->state);
+ goto reset_task_exit;
+ }
bnx2x_nic_unload(bp, 0);
bnx2x_nic_load(bp, 0);
- bp->in_reset_task = 0;
+reset_task_exit:
+ rtnl_unlock();
}
static int __devinit bnx2x_init_board(struct pci_dev *pdev,
@@ -8783,8 +9715,6 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev,
spin_lock_init(&bp->phy_lock);
- bp->in_reset_task = 0;
-
INIT_WORK(&bp->reset_task, bnx2x_reset_task);
INIT_WORK(&bp->sp_task, bnx2x_sp_task);
@@ -8813,7 +9743,7 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev,
bnx2x_get_hwinfo(bp);
if (CHIP_REV(bp) == CHIP_REV_FPGA) {
- printk(KERN_ERR PFX "FPGA detacted. MCP disabled,"
+ printk(KERN_ERR PFX "FPGA detected. MCP disabled,"
" will only init first device\n");
onefunc = 1;
nomcp = 1;
@@ -8882,14 +9812,32 @@ err_out:
return rc;
}
+static int __devinit bnx2x_get_pcie_width(struct bnx2x *bp)
+{
+ u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
+
+ val = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
+ return val;
+}
+
+/* return value of 1=2.5GHz 2=5GHz */
+static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
+{
+ u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
+
+ val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
+ return val;
+}
+
static int __devinit bnx2x_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
static int version_printed;
struct net_device *dev = NULL;
struct bnx2x *bp;
- int rc, i;
+ int rc;
int port = PCI_FUNC(pdev->devfn);
+ DECLARE_MAC_BUF(mac);
if (version_printed++ == 0)
printk(KERN_INFO "%s", version);
@@ -8906,6 +9854,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
if (port && onefunc) {
printk(KERN_ERR PFX "second function disabled. exiting\n");
+ free_netdev(dev);
return 0;
}
@@ -8918,7 +9867,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
dev->hard_start_xmit = bnx2x_start_xmit;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->get_stats = bnx2x_get_stats;
dev->ethtool_ops = &bnx2x_ethtool_ops;
dev->open = bnx2x_open;
dev->stop = bnx2x_close;
@@ -8944,7 +9892,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
rc = register_netdev(dev);
if (rc) {
- printk(KERN_ERR PFX "Cannot register net device\n");
+ dev_err(&pdev->dev, "Cannot register net device\n");
if (bp->regview)
iounmap(bp->regview);
if (bp->doorbells)
@@ -8959,32 +9907,30 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
pci_set_drvdata(pdev, dev);
bp->name = board_info[ent->driver_data].name;
- printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz "
- "found at mem %lx, IRQ %d, ",
- dev->name, bp->name,
+ printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
+ " IRQ %d, ", dev->name, bp->name,
((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
((CHIP_ID(bp) & 0x0ff0) >> 4),
- ((bp->flags & PCIX_FLAG) ? "-X" : ""),
- ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
- bp->bus_speed_mhz,
- dev->base_addr,
- bp->pdev->irq);
-
- printk("node addr ");
- for (i = 0; i < 6; i++)
- printk("%2.2x", dev->dev_addr[i]);
- printk("\n");
-
+ bnx2x_get_pcie_width(bp),
+ (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
+ dev->base_addr, bp->pdev->irq);
+ printk(KERN_CONT "node addr %s\n", print_mac(mac, dev->dev_addr));
return 0;
}
static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp = netdev_priv(dev);
+ struct bnx2x *bp;
+
+ if (!dev) {
+ /* we get here if init_one() fails */
+ printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
+ return;
+ }
+
+ bp = netdev_priv(dev);
- flush_scheduled_work();
- /*tasklet_kill(&bp->sp_task);*/
unregister_netdev(dev);
if (bp->regview)
@@ -9002,34 +9948,43 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp = netdev_priv(dev);
- int rc;
+ struct bnx2x *bp;
+
+ if (!dev)
+ return 0;
if (!netif_running(dev))
return 0;
- rc = bnx2x_nic_unload(bp, 0);
- if (!rc)
- return rc;
+ bp = netdev_priv(dev);
+
+ bnx2x_nic_unload(bp, 0);
netif_device_detach(dev);
- pci_save_state(pdev);
+ pci_save_state(pdev);
bnx2x_set_power_state(bp, pci_choose_state(pdev, state));
+
return 0;
}
static int bnx2x_resume(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp = netdev_priv(dev);
+ struct bnx2x *bp;
int rc;
+ if (!dev) {
+ printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
+ return -ENODEV;
+ }
+
if (!netif_running(dev))
return 0;
- pci_restore_state(pdev);
+ bp = netdev_priv(dev);
+ pci_restore_state(pdev);
bnx2x_set_power_state(bp, PCI_D0);
netif_device_attach(dev);
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 4f7ae6f7745..4f0c0d31e7c 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -1,6 +1,6 @@
/* bnx2x.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 Broadcom Corporation
*
* 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
@@ -24,6 +24,8 @@
#define BNX2X_MSG_STATS 0x20000 /* was: NETIF_MSG_TIMER */
#define NETIF_MSG_NVM 0x40000 /* was: NETIF_MSG_HW */
#define NETIF_MSG_DMAE 0x80000 /* was: NETIF_MSG_HW */
+#define BNX2X_MSG_SP 0x100000 /* was: NETIF_MSG_INTR */
+#define BNX2X_MSG_FP 0x200000 /* was: NETIF_MSG_INTR */
#define DP_LEVEL KERN_NOTICE /* was: KERN_DEBUG */
@@ -40,6 +42,12 @@
__LINE__, bp->dev?(bp->dev->name):"?", ##__args); \
} while (0)
+/* for logging (never masked) */
+#define BNX2X_LOG(__fmt, __args...) do { \
+ printk(KERN_NOTICE "[%s:%d(%s)]" __fmt, __FUNCTION__, \
+ __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \
+ } while (0)
+
/* before we have a dev->name use dev_info() */
#define BNX2X_DEV_INFO(__fmt, __args...) do { \
if (bp->msglevel & NETIF_MSG_PROBE) \
@@ -423,8 +431,6 @@ struct bnx2x_fastpath {
#define BNX2X_FP_STATE_OPEN 0xa0000
#define BNX2X_FP_STATE_HALTING 0xb0000
#define BNX2X_FP_STATE_HALTED 0xc0000
-#define BNX2X_FP_STATE_DELETED 0xd0000
-#define BNX2X_FP_STATE_CLOSE_IRQ 0xe0000
int index;
@@ -505,7 +511,6 @@ struct bnx2x {
struct eth_spe *spq;
dma_addr_t spq_mapping;
u16 spq_prod_idx;
- u16 dsb_sp_prod_idx;
struct eth_spe *spq_prod_bd;
struct eth_spe *spq_last_bd;
u16 *dsb_sp_prod;
@@ -517,7 +522,7 @@ struct bnx2x {
*/
u8 stat_pending;
- /* End of fileds used in the performance code paths */
+ /* End of fields used in the performance code paths */
int panic;
int msglevel;
@@ -540,8 +545,6 @@ struct bnx2x {
spinlock_t phy_lock;
struct work_struct reset_task;
- u16 in_reset_task;
-
struct work_struct sp_task;
struct timer_list timer;
@@ -555,7 +558,6 @@ struct bnx2x {
#define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0)
#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000)
-#define CHIP_NUM_5710 0x57100000
#define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000)
#define CHIP_REV_Ax 0x00000000
@@ -574,7 +576,8 @@ struct bnx2x {
u32 fw_mb;
u32 hw_config;
- u32 serdes_config;
+ u32 board;
+ u32 serdes_config;
u32 lane_config;
u32 ext_phy_config;
#define XGXS_EXT_PHY_TYPE(bp) (bp->ext_phy_config & \
@@ -595,11 +598,11 @@ struct bnx2x {
u8 tx_lane_swap;
u8 link_up;
+ u8 phy_link_up;
u32 supported;
/* link settings - missing defines */
#define SUPPORTED_2500baseT_Full (1 << 15)
-#define SUPPORTED_CX4 (1 << 16)
u32 phy_flags;
/*#define PHY_SERDES_FLAG 0x1*/
@@ -644,16 +647,9 @@ struct bnx2x {
#define FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH
#define FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE
- u32 pause_mode;
-#define PAUSE_NONE 0
-#define PAUSE_SYMMETRIC 1
-#define PAUSE_ASYMMETRIC 2
-#define PAUSE_BOTH 3
-
u32 advertising;
/* link settings - missing defines */
#define ADVERTISED_2500baseT_Full (1 << 15)
-#define ADVERTISED_CX4 (1 << 16)
u32 link_status;
u32 line_speed;
@@ -667,6 +663,8 @@ struct bnx2x {
#define NVRAM_TIMEOUT_COUNT 30000
#define NVRAM_PAGE_SIZE 256
+ u8 wol;
+
int rx_ring_size;
u16 tx_quick_cons_trip_int;
@@ -718,9 +716,6 @@ struct bnx2x {
#endif
char *name;
- u16 bus_speed_mhz;
- u8 wol;
- u8 pad;
/* used to synchronize stats collecting */
int stats_state;
@@ -856,8 +851,8 @@ struct bnx2x {
#define MAX_SPQ_PENDING 8
-#define BNX2X_NUM_STATS 31
-#define BNX2X_NUM_TESTS 2
+#define BNX2X_NUM_STATS 34
+#define BNX2X_NUM_TESTS 1
#define DPM_TRIGER_TYPE 0x40
@@ -867,6 +862,15 @@ struct bnx2x {
DPM_TRIGER_TYPE); \
} while (0)
+/* PCIE link and speed */
+#define PCICFG_LINK_WIDTH 0x1f00000
+#define PCICFG_LINK_WIDTH_SHIFT 20
+#define PCICFG_LINK_SPEED 0xf0000
+#define PCICFG_LINK_SPEED_SHIFT 16
+
+#define BMAC_CONTROL_RX_ENABLE 2
+
+#define pbd_tcp_flags(skb) (ntohl(tcp_flag_word(tcp_hdr(skb)))>>16 & 0xff)
/* stuff added to make the code fit 80Col */
@@ -939,13 +943,13 @@ struct bnx2x {
#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
-#define NIG_STATUS_INTERRUPT_XGXS0_LINK10G \
+#define NIG_STATUS_XGXS0_LINK10G \
NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
-#define NIG_XGXS0_LINK_STATUS \
+#define NIG_STATUS_XGXS0_LINK_STATUS \
NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
-#define NIG_XGXS0_LINK_STATUS_SIZE \
+#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
-#define NIG_SERDES0_LINK_STATUS \
+#define NIG_STATUS_SERDES0_LINK_STATUS \
NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
#define NIG_MASK_MI_INT \
NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h
index 62a6eb81025..3b968904ca6 100644
--- a/drivers/net/bnx2x_fw_defs.h
+++ b/drivers/net/bnx2x_fw_defs.h
@@ -1,6 +1,6 @@
/* bnx2x_fw_defs.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 Broadcom Corporation
*
* 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/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
index 6fd959c34d1..b21075ccb52 100644
--- a/drivers/net/bnx2x_hsi.h
+++ b/drivers/net/bnx2x_hsi.h
@@ -1,6 +1,6 @@
/* bnx2x_hsi.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 Broadcom Corporation
*
* 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
@@ -8,169 +8,9 @@
*/
-#define FUNC_0 0
-#define FUNC_1 1
-#define FUNC_MAX 2
-
-
-/* This value (in milliseconds) determines the frequency of the driver
- * issuing the PULSE message code. The firmware monitors this periodic
- * pulse to determine when to switch to an OS-absent mode. */
-#define DRV_PULSE_PERIOD_MS 250
-
-/* This value (in milliseconds) determines how long the driver should
- * wait for an acknowledgement from the firmware before timing out. Once
- * the firmware has timed out, the driver will assume there is no firmware
- * running and there won't be any firmware-driver synchronization during a
- * driver reset. */
-#define FW_ACK_TIME_OUT_MS 5000
-
-#define FW_ACK_POLL_TIME_MS 1
-
-#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS)
-
-/* LED Blink rate that will achieve ~15.9Hz */
-#define LED_BLINK_RATE_VAL 480
-
-/****************************************************************************
- * Driver <-> FW Mailbox *
- ****************************************************************************/
-struct drv_fw_mb {
- u32 drv_mb_header;
-#define DRV_MSG_CODE_MASK 0xffff0000
-#define DRV_MSG_CODE_LOAD_REQ 0x10000000
-#define DRV_MSG_CODE_LOAD_DONE 0x11000000
-#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000
-#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000
-#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000
-#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000
-#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000
-#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000
-#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000
-#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000
-#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000
-#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000
-#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000
-
-#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff
-
- u32 drv_mb_param;
-
- u32 fw_mb_header;
-#define FW_MSG_CODE_MASK 0xffff0000
-#define FW_MSG_CODE_DRV_LOAD_COMMON 0x11000000
-#define FW_MSG_CODE_DRV_LOAD_PORT 0x12000000
-#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x13000000
-#define FW_MSG_CODE_DRV_LOAD_DONE 0x14000000
-#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x21000000
-#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x22000000
-#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x23000000
-#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50000000
-#define FW_MSG_CODE_DIAG_REFUSE 0x51000000
-#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70000000
-#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x71000000
-#define FW_MSG_CODE_GET_KEY_DONE 0x80000000
-#define FW_MSG_CODE_NO_KEY 0x8f000000
-#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x8f800000
-#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90000000
-#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x91000000
-#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x92000000
-#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x93000000
-#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x94000000
-
-#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff
-
- u32 fw_mb_param;
-
- u32 link_status;
- /* Driver should update this field on any link change event */
-
-#define LINK_STATUS_LINK_FLAG_MASK 0x00000001
-#define LINK_STATUS_LINK_UP 0x00000001
-#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E
-#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1)
-
-#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020
-#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020
-
-#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040
-#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080
-#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080
-
-#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200
-#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400
-#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800
-#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000
-#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000
-#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000
-#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000
-
-#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000
-#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000
-
-#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000
-#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000
-
-#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000
-#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18)
-#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18)
-#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18)
-#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18)
-
-#define LINK_STATUS_SERDES_LINK 0x00100000
-
-#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000
-#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000
-#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000
-#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000
-#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000
-#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000
-#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000
-#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000
-
- u32 drv_pulse_mb;
-#define DRV_PULSE_SEQ_MASK 0x00007fff
-#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000
- /* The system time is in the format of
- * (year-2001)*12*32 + month*32 + day. */
-#define DRV_PULSE_ALWAYS_ALIVE 0x00008000
- /* Indicate to the firmware not to go into the
- * OS-absent when it is not getting driver pulse.
- * This is used for debugging as well for PXE(MBA). */
-
- u32 mcp_pulse_mb;
-#define MCP_PULSE_SEQ_MASK 0x00007fff
-#define MCP_PULSE_ALWAYS_ALIVE 0x00008000
- /* Indicates to the driver not to assert due to lack
- * of MCP response */
-#define MCP_EVENT_MASK 0xffff0000
-#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000
-
-};
-
+#define PORT_0 0
+#define PORT_1 1
+#define PORT_MAX 2
/****************************************************************************
* Shared HW configuration *
@@ -249,7 +89,7 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_SMBUS_TIMING_100KHZ 0x00000000
#define SHARED_HW_CFG_SMBUS_TIMING_400KHZ 0x00001000
-#define SHARED_HW_CFG_HIDE_FUNC1 0x00002000
+#define SHARED_HW_CFG_HIDE_PORT1 0x00002000
u32 power_dissipated; /* 0x11c */
#define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000
@@ -290,6 +130,8 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1015G 0x00000006
#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1020G 0x00000007
#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G 0x00000008
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G 0x00000009
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G 0x0000000a
#define SHARED_HW_CFG_BOARD_VER_MASK 0xffff0000
#define SHARED_HW_CFG_BOARD_VER_SHIFT 16
@@ -304,13 +146,12 @@ struct shared_hw_cfg { /* NVRAM Offset */
};
+
/****************************************************************************
* Port HW configuration *
****************************************************************************/
-struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */
+struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
- /* Fields below are port specific (in anticipation of dual port
- devices */
u32 pci_id;
#define PORT_HW_CFG_PCI_VENDOR_ID_MASK 0xffff0000
#define PORT_HW_CFG_PCI_DEVICE_ID_MASK 0x0000ffff
@@ -420,6 +261,8 @@ struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276 0x00000600
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00
#define PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK 0x000000ff
@@ -462,11 +305,13 @@ struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */
};
+
/****************************************************************************
* Shared Feature configuration *
****************************************************************************/
struct shared_feat_cfg { /* NVRAM Offset */
- u32 bmc_common; /* 0x450 */
+
+ u32 config; /* 0x450 */
#define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001
};
@@ -475,7 +320,8 @@ struct shared_feat_cfg { /* NVRAM Offset */
/****************************************************************************
* Port Feature configuration *
****************************************************************************/
-struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */
+struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
+
u32 config;
#define PORT_FEATURE_BAR1_SIZE_MASK 0x0000000f
#define PORT_FEATURE_BAR1_SIZE_SHIFT 0
@@ -609,8 +455,7 @@ struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */
#define PORT_FEATURE_SMBUS_ADDR_MASK 0x000000fe
#define PORT_FEATURE_SMBUS_ADDR_SHIFT 1
- u32 iscsib_boot_cfg;
-#define PORT_FEATURE_ISCSIB_SKIP_TARGET_BOOT 0x00000001
+ u32 reserved1;
u32 link_config; /* Used as HW defaults for the driver */
#define PORT_FEATURE_CONNECTED_SWITCH_MASK 0x03000000
@@ -657,20 +502,201 @@ struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */
};
+/*****************************************************************************
+ * Device Information *
+ *****************************************************************************/
+struct dev_info { /* size */
+
+ u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */
+
+ struct shared_hw_cfg shared_hw_config; /* 40 */
+
+ struct port_hw_cfg port_hw_config[PORT_MAX]; /* 400*2=800 */
+
+ struct shared_feat_cfg shared_feature_config; /* 4 */
+
+ struct port_feat_cfg port_feature_config[PORT_MAX]; /* 116*2=232 */
+
+};
+
+
+#define FUNC_0 0
+#define FUNC_1 1
+#define E1_FUNC_MAX 2
+#define FUNC_MAX E1_FUNC_MAX
+
+
+/* This value (in milliseconds) determines the frequency of the driver
+ * issuing the PULSE message code. The firmware monitors this periodic
+ * pulse to determine when to switch to an OS-absent mode. */
+#define DRV_PULSE_PERIOD_MS 250
+
+/* This value (in milliseconds) determines how long the driver should
+ * wait for an acknowledgement from the firmware before timing out. Once
+ * the firmware has timed out, the driver will assume there is no firmware
+ * running and there won't be any firmware-driver synchronization during a
+ * driver reset. */
+#define FW_ACK_TIME_OUT_MS 5000
+
+#define FW_ACK_POLL_TIME_MS 1
+
+#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS)
+
+/* LED Blink rate that will achieve ~15.9Hz */
+#define LED_BLINK_RATE_VAL 480
+
/****************************************************************************
- * Device Information *
+ * Driver <-> FW Mailbox *
****************************************************************************/
-struct dev_info { /* size */
+struct drv_port_mb {
+
+ u32 link_status;
+ /* Driver should update this field on any link change event */
+
+#define LINK_STATUS_LINK_FLAG_MASK 0x00000001
+#define LINK_STATUS_LINK_UP 0x00000001
+#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E
+#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1)
+
+#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020
+#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020
+
+#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040
+#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080
+#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080
+
+#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200
+#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400
+#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800
+#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000
+#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000
+#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000
+#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000
+
+#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000
+#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000
+
+#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000
+#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000
+
+#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000
+#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18)
+#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18)
+#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18)
+#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18)
+
+#define LINK_STATUS_SERDES_LINK 0x00100000
+
+#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000
+#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000
+#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000
+#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000
+#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000
+#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000
+#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000
+#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000
- u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */
+ u32 reserved[3];
- struct shared_hw_cfg shared_hw_config; /* 40 */
+};
+
+
+struct drv_func_mb {
+
+ u32 drv_mb_header;
+#define DRV_MSG_CODE_MASK 0xffff0000
+#define DRV_MSG_CODE_LOAD_REQ 0x10000000
+#define DRV_MSG_CODE_LOAD_DONE 0x11000000
+#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000
+#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000
+#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000
+#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000
+#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000
+#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000
+#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000
+#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000
+#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000
+#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000
+#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000
+
+#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff
+
+ u32 drv_mb_param;
+
+ u32 fw_mb_header;
+#define FW_MSG_CODE_MASK 0xffff0000
+#define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000
+#define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000
+#define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000
+#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000
+#define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000
+#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000
+#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x20110000
+#define FW_MSG_CODE_DRV_UNLOAD_FUNCTION 0x20120000
+#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x21100000
+#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50100000
+#define FW_MSG_CODE_DIAG_REFUSE 0x50200000
+#define FW_MSG_CODE_DIAG_EXIT_DONE 0x60100000
+#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70100000
+#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x70200000
+#define FW_MSG_CODE_GET_KEY_DONE 0x80100000
+#define FW_MSG_CODE_NO_KEY 0x80f00000
+#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x80f80000
+#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90100000
+#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x90210000
+#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x90220000
+#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x90230000
+#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x90240000
+
+#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff
+
+ u32 fw_mb_param;
+
+ u32 drv_pulse_mb;
+#define DRV_PULSE_SEQ_MASK 0x00007fff
+#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000
+ /* The system time is in the format of
+ * (year-2001)*12*32 + month*32 + day. */
+#define DRV_PULSE_ALWAYS_ALIVE 0x00008000
+ /* Indicate to the firmware not to go into the
+ * OS-absent when it is not getting driver pulse.
+ * This is used for debugging as well for PXE(MBA). */
- struct port_hw_cfg port_hw_config[FUNC_MAX]; /* 400*2=800 */
+ u32 mcp_pulse_mb;
+#define MCP_PULSE_SEQ_MASK 0x00007fff
+#define MCP_PULSE_ALWAYS_ALIVE 0x00008000
+ /* Indicates to the driver not to assert due to lack
+ * of MCP response */
+#define MCP_EVENT_MASK 0xffff0000
+#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000
- struct shared_feat_cfg shared_feature_config; /* 4 */
+ u32 iscsi_boot_signature;
+ u32 iscsi_boot_block_offset;
- struct port_feat_cfg port_feature_config[FUNC_MAX];/* 116*2=232 */
+ u32 reserved[3];
};
@@ -678,9 +704,8 @@ struct dev_info { /* size */
/****************************************************************************
* Management firmware state *
****************************************************************************/
-/* Allocate 320 bytes for management firmware: still not known exactly
- * how much IMD needs. */
-#define MGMTFW_STATE_WORD_SIZE 80
+/* Allocate 440 bytes for management firmware */
+#define MGMTFW_STATE_WORD_SIZE 110
struct mgmtfw_state {
u32 opaque[MGMTFW_STATE_WORD_SIZE];
@@ -691,31 +716,40 @@ struct mgmtfw_state {
* Shared Memory Region *
****************************************************************************/
struct shmem_region { /* SharedMem Offset (size) */
- u32 validity_map[FUNC_MAX]; /* 0x0 (4 * 2 = 0x8) */
-#define SHR_MEM_VALIDITY_PCI_CFG 0x00000001
-#define SHR_MEM_VALIDITY_MB 0x00000002
-#define SHR_MEM_VALIDITY_DEV_INFO 0x00000004
+
+ u32 validity_map[PORT_MAX]; /* 0x0 (4*2 = 0x8) */
+#define SHR_MEM_FORMAT_REV_ID ('A'<<24)
+#define SHR_MEM_FORMAT_REV_MASK 0xff000000
+ /* validity bits */
+#define SHR_MEM_VALIDITY_PCI_CFG 0x00100000
+#define SHR_MEM_VALIDITY_MB 0x00200000
+#define SHR_MEM_VALIDITY_DEV_INFO 0x00400000
+#define SHR_MEM_VALIDITY_RESERVED 0x00000007
/* One licensing bit should be set */
#define SHR_MEM_VALIDITY_LIC_KEY_IN_EFFECT_MASK 0x00000038
#define SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT 0x00000008
#define SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT 0x00000010
#define SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT 0x00000020
+ /* Active MFW */
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_UNKNOWN 0x00000000
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_IPMI 0x00000040
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_UMP 0x00000080
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_NCSI 0x000000c0
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_NONE 0x000001c0
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_MASK 0x000001c0
- struct drv_fw_mb drv_fw_mb[FUNC_MAX]; /* 0x8 (28 * 2 = 0x38) */
-
- struct dev_info dev_info; /* 0x40 (0x438) */
+ struct dev_info dev_info; /* 0x8 (0x438) */
-#ifdef _LICENSE_H
- license_key_t drv_lic_key[FUNC_MAX]; /* 0x478 (52 * 2 = 0x68) */
-#else /* Linux! */
- u8 reserved[52*FUNC_MAX];
-#endif
+ u8 reserved[52*PORT_MAX];
/* FW information (for internal FW use) */
- u32 fw_info_fio_offset; /* 0x4e0 (0x4) */
- struct mgmtfw_state mgmtfw_state; /* 0x4e4 (0x140) */
+ u32 fw_info_fio_offset; /* 0x4a8 (0x4) */
+ struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */
+
+ struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */
+ struct drv_func_mb func_mb[FUNC_MAX]; /* 0x684 (44*2=0x58) */
-}; /* 0x624 */
+}; /* 0x6dc */
#define BCM_5710_FW_MAJOR_VERSION 4
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 04f93bff2ef..dcaecc53bdb 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -1,6 +1,6 @@
/* bnx2x_init.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 Broadcom Corporation
*
* 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
@@ -409,7 +409,7 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
pci_read_config_word(bp->pdev,
bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val);
- DP(NETIF_MSG_HW, "read 0x%x from devctl\n", val);
+ DP(NETIF_MSG_HW, "read 0x%x from devctl\n", (u16)val);
w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12);
@@ -472,10 +472,14 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
- REG_WR(bp, PXP2_REG_RQ_WR_MBS0 + 8, w_order);
+ REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
- REG_WR(bp, PXP2_REG_RQ_RD_MBS0 + 8, r_order);
+ REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
+ if (r_order == MAX_RD_ORD)
+ REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
+
+ REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
REG_WR(bp, PXP2_REG_WR_DMAE_TH, (128 << w_order)/16);
}
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index 86055297ab0..5a1aa0b5504 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -1,6 +1,6 @@
/* bnx2x_reg.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 Broadcom Corporation
*
* 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
@@ -24,6 +24,8 @@
#define BRB1_REG_BRB1_INT_STS 0x6011c
/* [RW 4] Parity mask register #0 read/write */
#define BRB1_REG_BRB1_PRTY_MASK 0x60138
+/* [R 4] Parity register #0 read */
+#define BRB1_REG_BRB1_PRTY_STS 0x6012c
/* [RW 10] At address BRB1_IND_FREE_LIST_PRS_CRDT initialize free head. At
address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address
BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */
@@ -281,6 +283,8 @@
#define CDU_REG_CDU_INT_STS 0x101030
/* [RW 5] Parity mask register #0 read/write */
#define CDU_REG_CDU_PRTY_MASK 0x10104c
+/* [R 5] Parity register #0 read */
+#define CDU_REG_CDU_PRTY_STS 0x101040
/* [RC 32] logging of error data in case of a CDU load error:
{expected_cid[15:0]; xpected_type[2:0]; xpected_region[2:0]; ctive_error;
ype_error; ctual_active; ctual_compressed_context}; */
@@ -308,6 +312,8 @@
#define CFC_REG_CFC_INT_STS_CLR 0x104100
/* [RW 4] Parity mask register #0 read/write */
#define CFC_REG_CFC_PRTY_MASK 0x104118
+/* [R 4] Parity register #0 read */
+#define CFC_REG_CFC_PRTY_STS 0x10410c
/* [RW 21] CID cam access (21:1 - Data; alid - 0) */
#define CFC_REG_CID_CAM 0x104800
#define CFC_REG_CONTROL0 0x104028
@@ -354,6 +360,8 @@
#define CSDM_REG_CSDM_INT_MASK_1 0xc22ac
/* [RW 11] Parity mask register #0 read/write */
#define CSDM_REG_CSDM_PRTY_MASK 0xc22bc
+/* [R 11] Parity register #0 read */
+#define CSDM_REG_CSDM_PRTY_STS 0xc22b0
#define CSDM_REG_ENABLE_IN1 0xc2238
#define CSDM_REG_ENABLE_IN2 0xc223c
#define CSDM_REG_ENABLE_OUT1 0xc2240
@@ -438,6 +446,9 @@
/* [RW 32] Parity mask register #0 read/write */
#define CSEM_REG_CSEM_PRTY_MASK_0 0x200130
#define CSEM_REG_CSEM_PRTY_MASK_1 0x200140
+/* [R 32] Parity register #0 read */
+#define CSEM_REG_CSEM_PRTY_STS_0 0x200124
+#define CSEM_REG_CSEM_PRTY_STS_1 0x200134
#define CSEM_REG_ENABLE_IN 0x2000a4
#define CSEM_REG_ENABLE_OUT 0x2000a8
/* [RW 32] This address space contains all registers and memories that are
@@ -526,6 +537,8 @@
#define CSEM_REG_TS_9_AS 0x20005c
/* [RW 1] Parity mask register #0 read/write */
#define DBG_REG_DBG_PRTY_MASK 0xc0a8
+/* [R 1] Parity register #0 read */
+#define DBG_REG_DBG_PRTY_STS 0xc09c
/* [RW 2] debug only: These bits indicate the credit for PCI request type 4
interface; MUST be configured AFTER pci_ext_buffer_strt_addr_lsb/msb are
configured */
@@ -543,6 +556,8 @@
#define DMAE_REG_DMAE_INT_MASK 0x102054
/* [RW 4] Parity mask register #0 read/write */
#define DMAE_REG_DMAE_PRTY_MASK 0x102064
+/* [R 4] Parity register #0 read */
+#define DMAE_REG_DMAE_PRTY_STS 0x102058
/* [RW 1] Command 0 go. */
#define DMAE_REG_GO_C0 0x102080
/* [RW 1] Command 1 go. */
@@ -623,6 +638,8 @@
#define DORQ_REG_DORQ_INT_STS_CLR 0x170178
/* [RW 2] Parity mask register #0 read/write */
#define DORQ_REG_DORQ_PRTY_MASK 0x170190
+/* [R 2] Parity register #0 read */
+#define DORQ_REG_DORQ_PRTY_STS 0x170184
/* [RW 8] The address to write the DPM CID to STORM. */
#define DORQ_REG_DPM_CID_ADDR 0x170044
/* [RW 5] The DPM mode CID extraction offset. */
@@ -692,6 +709,8 @@
#define HC_REG_CONFIG_1 0x108004
/* [RW 3] Parity mask register #0 read/write */
#define HC_REG_HC_PRTY_MASK 0x1080a0
+/* [R 3] Parity register #0 read */
+#define HC_REG_HC_PRTY_STS 0x108094
/* [RW 17] status block interrupt mask; one in each bit means unmask; zerow
in each bit means mask; bit 0 - default SB; bit 1 - SB_0; bit 2 - SB_1...
bit 16- SB_15; addr 0 - port 0; addr 1 - port 1 */
@@ -1127,6 +1146,7 @@
#define MISC_REG_AEU_GENERAL_ATTN_17 0xa044
#define MISC_REG_AEU_GENERAL_ATTN_18 0xa048
#define MISC_REG_AEU_GENERAL_ATTN_19 0xa04c
+#define MISC_REG_AEU_GENERAL_ATTN_10 0xa028
#define MISC_REG_AEU_GENERAL_ATTN_11 0xa02c
#define MISC_REG_AEU_GENERAL_ATTN_2 0xa008
#define MISC_REG_AEU_GENERAL_ATTN_20 0xa050
@@ -1135,6 +1155,9 @@
#define MISC_REG_AEU_GENERAL_ATTN_4 0xa010
#define MISC_REG_AEU_GENERAL_ATTN_5 0xa014
#define MISC_REG_AEU_GENERAL_ATTN_6 0xa018
+#define MISC_REG_AEU_GENERAL_ATTN_7 0xa01c
+#define MISC_REG_AEU_GENERAL_ATTN_8 0xa020
+#define MISC_REG_AEU_GENERAL_ATTN_9 0xa024
/* [RW 32] first 32b for inverting the input for function 0; for each bit:
0= do not invert; 1= invert; mapped as follows: [0] NIG attention for
function0; [1] NIG attention for function1; [2] GPIO1 mcp; [3] GPIO2 mcp;
@@ -1183,6 +1206,40 @@
starts at 0x0 for the A0 tape-out and increments by one for each
all-layer tape-out. */
#define MISC_REG_CHIP_REV 0xa40c
+/* [RW 32] The following driver registers(1..6) represent 6 drivers and 32
+ clients. Each client can be controlled by one driver only. One in each
+ bit represent that this driver control the appropriate client (Ex: bit 5
+ is set means this driver control client number 5). addr1 = set; addr0 =
+ clear; read from both addresses will give the same result = status. write
+ to address 1 will set a request to control all the clients that their
+ appropriate bit (in the write command) is set. if the client is free (the
+ appropriate bit in all the other drivers is clear) one will be written to
+ that driver register; if the client isn't free the bit will remain zero.
+ if the appropriate bit is set (the driver request to gain control on a
+ client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
+ interrupt will be asserted). write to address 0 will set a request to
+ free all the clients that their appropriate bit (in the write command) is
+ set. if the appropriate bit is clear (the driver request to free a client
+ it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
+ be asserted). */
+#define MISC_REG_DRIVER_CONTROL_1 0xa510
+/* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of
+ these bits is written as a '1'; the corresponding SPIO bit will turn off
+ it's drivers and become an input. This is the reset state of all GPIO
+ pins. The read value of these bits will be a '1' if that last command
+ (#SET; #CLR; or #FLOAT) for this bit was a #FLOAT. (reset value 0xff).
+ [23-20] CLR port 1; 19-16] CLR port 0; When any of these bits is written
+ as a '1'; the corresponding GPIO bit will drive low. The read value of
+ these bits will be a '1' if that last command (#SET; #CLR; or #FLOAT) for
+ this bit was a #CLR. (reset value 0). [15-12] SET port 1; 11-8] port 0;
+ SET When any of these bits is written as a '1'; the corresponding GPIO
+ bit will drive high (if it has that capability). The read value of these
+ bits will be a '1' if that last command (#SET; #CLR; or #FLOAT) for this
+ bit was a #SET. (reset value 0). [7-4] VALUE port 1; [3-0] VALUE port 0;
+ RO; These bits indicate the read value of each of the eight GPIO pins.
+ This is the result value of the pin; not the drive value. Writing these
+ bits will have not effect. */
+#define MISC_REG_GPIO 0xa490
/* [RW 1] Setting this bit enables a timer in the GRC block to timeout any
access that does not finish within
~misc_registers_grc_timout_val.grc_timeout_val cycles. When this bit is
@@ -1223,6 +1280,8 @@
#define MISC_REG_MISC_INT_MASK 0xa388
/* [RW 1] Parity mask register #0 read/write */
#define MISC_REG_MISC_PRTY_MASK 0xa398
+/* [R 1] Parity register #0 read */
+#define MISC_REG_MISC_PRTY_STS 0xa38c
/* [RW 32] 32 LSB of storm PLL first register; reset val = 0x 071d2911.
inside order of the bits is: [0] P1 divider[0] (reset value 1); [1] P1
divider[1] (reset value 0); [2] P1 divider[2] (reset value 0); [3] P1
@@ -1264,6 +1323,55 @@
/* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is
shared with the driver resides */
#define MISC_REG_SHARED_MEM_ADDR 0xa2b4
+/* [RW 32] SPIO. [31-24] FLOAT When any of these bits is written as a '1';
+ the corresponding SPIO bit will turn off it's drivers and become an
+ input. This is the reset state of all SPIO pins. The read value of these
+ bits will be a '1' if that last command (#SET; #CL; or #FLOAT) for this
+ bit was a #FLOAT. (reset value 0xff). [23-16] CLR When any of these bits
+ is written as a '1'; the corresponding SPIO bit will drive low. The read
+ value of these bits will be a '1' if that last command (#SET; #CLR; or
+#FLOAT) for this bit was a #CLR. (reset value 0). [15-8] SET When any of
+ these bits is written as a '1'; the corresponding SPIO bit will drive
+ high (if it has that capability). The read value of these bits will be a
+ '1' if that last command (#SET; #CLR; or #FLOAT) for this bit was a #SET.
+ (reset value 0). [7-0] VALUE RO; These bits indicate the read value of
+ each of the eight SPIO pins. This is the result value of the pin; not the
+ drive value. Writing these bits will have not effect. Each 8 bits field
+ is divided as follows: [0] VAUX Enable; when pulsed low; enables supply
+ from VAUX. (This is an output pin only; the FLOAT field is not applicable
+ for this pin); [1] VAUX Disable; when pulsed low; disables supply form
+ VAUX. (This is an output pin only; FLOAT field is not applicable for this
+ pin); [2] SEL_VAUX_B - Control to power switching logic. Drive low to
+ select VAUX supply. (This is an output pin only; it is not controlled by
+ the SET and CLR fields; it is controlled by the Main Power SM; the FLOAT
+ field is not applicable for this pin; only the VALUE fields is relevant -
+ it reflects the output value); [3] reserved; [4] spio_4; [5] spio_5; [6]
+ Bit 0 of UMP device ID select; read by UMP firmware; [7] Bit 1 of UMP
+ device ID select; read by UMP firmware. */
+#define MISC_REG_SPIO 0xa4fc
+/* [RW 8] These bits enable the SPIO_INTs to signals event to the IGU/MC.
+ according to the following map: [3:0] reserved; [4] spio_4 [5] spio_5;
+ [7:0] reserved */
+#define MISC_REG_SPIO_EVENT_EN 0xa2b8
+/* [RW 32] SPIO INT. [31-24] OLD_CLR Writing a '1' to these bit clears the
+ corresponding bit in the #OLD_VALUE register. This will acknowledge an
+ interrupt on the falling edge of corresponding SPIO input (reset value
+ 0). [23-16] OLD_SET Writing a '1' to these bit sets the corresponding bit
+ in the #OLD_VALUE register. This will acknowledge an interrupt on the
+ rising edge of corresponding SPIO input (reset value 0). [15-8] OLD_VALUE
+ RO; These bits indicate the old value of the SPIO input value. When the
+ ~INT_STATE bit is set; this bit indicates the OLD value of the pin such
+ that if ~INT_STATE is set and this bit is '0'; then the interrupt is due
+ to a low to high edge. If ~INT_STATE is set and this bit is '1'; then the
+ interrupt is due to a high to low edge (reset value 0). [7-0] INT_STATE
+ RO; These bits indicate the current SPIO interrupt state for each SPIO
+ pin. This bit is cleared when the appropriate #OLD_SET or #OLD_CLR
+ command bit is written. This bit is set when the SPIO input does not
+ match the current value in #OLD_VALUE (reset value 0). */
+#define MISC_REG_SPIO_INT 0xa500
+/* [RW 1] Set by the MCP to remember if one or more of the drivers is/are
+ loaded; 0-prepare; -unprepare */
+#define MISC_REG_UNPREPARED 0xa424
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0)
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9)
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15)
@@ -1392,6 +1500,9 @@
#define NIG_REG_NIG_INGRESS_EMAC0_NO_CRC 0x10044
/* [RW 1] Input enable for RX PBF LP IF */
#define NIG_REG_PBF_LB_IN_EN 0x100b4
+/* [RW 1] Value of this register will be transmitted to port swap when
+ ~nig_registers_strap_override.strap_override =1 */
+#define NIG_REG_PORT_SWAP 0x10394
/* [RW 1] output enable for RX parser descriptor IF */
#define NIG_REG_PRS_EOP_OUT_EN 0x10104
/* [RW 1] Input enable for RX parser request IF */
@@ -1410,6 +1521,10 @@
#define NIG_REG_STAT2_BRB_OCTET 0x107e0
#define NIG_REG_STATUS_INTERRUPT_PORT0 0x10328
#define NIG_REG_STATUS_INTERRUPT_PORT1 0x1032c
+/* [RW 1] port swap mux selection. If this register equal to 0 then port
+ swap is equal to SPIO pin that inputs from ifmux_serdes_swap. If 1 then
+ ort swap is equal to ~nig_registers_port_swap.port_swap */
+#define NIG_REG_STRAP_OVERRIDE 0x10398
/* [RW 1] output enable for RX_XCM0 IF */
#define NIG_REG_XCM0_OUT_EN 0x100f0
/* [RW 1] output enable for RX_XCM1 IF */
@@ -1499,6 +1614,8 @@
#define PB_REG_PB_INT_STS 0x1c
/* [RW 4] Parity mask register #0 read/write */
#define PB_REG_PB_PRTY_MASK 0x38
+/* [R 4] Parity register #0 read */
+#define PB_REG_PB_PRTY_STS 0x2c
#define PRS_REG_A_PRSU_20 0x40134
/* [R 8] debug only: CFC load request current credit. Transaction based. */
#define PRS_REG_CFC_LD_CURRENT_CREDIT 0x40164
@@ -1590,6 +1707,8 @@
#define PRS_REG_PRS_INT_STS 0x40188
/* [RW 8] Parity mask register #0 read/write */
#define PRS_REG_PRS_PRTY_MASK 0x401a4
+/* [R 8] Parity register #0 read */
+#define PRS_REG_PRS_PRTY_STS 0x40198
/* [RW 8] Context region for pure acknowledge packets. Used in CFC load
request message */
#define PRS_REG_PURE_REGIONS 0x40024
@@ -1718,6 +1837,9 @@
/* [RW 32] Parity mask register #0 read/write */
#define PXP2_REG_PXP2_PRTY_MASK_0 0x120588
#define PXP2_REG_PXP2_PRTY_MASK_1 0x120598
+/* [R 32] Parity register #0 read */
+#define PXP2_REG_PXP2_PRTY_STS_0 0x12057c
+#define PXP2_REG_PXP2_PRTY_STS_1 0x12058c
/* [R 1] Debug only: The 'almost full' indication from each fifo (gives
indication about backpressure) */
#define PXP2_REG_RD_ALMOST_FULL_0 0x120424
@@ -1911,6 +2033,8 @@
#define PXP2_REG_RQ_HC_ENDIAN_M 0x1201a8
/* [WB 53] Onchip address table */
#define PXP2_REG_RQ_ONCHIP_AT 0x122000
+/* [RW 13] Pending read limiter threshold; in Dwords */
+#define PXP2_REG_RQ_PDR_LIMIT 0x12033c
/* [RW 2] Endian mode for qm */
#define PXP2_REG_RQ_QM_ENDIAN_M 0x120194
/* [RW 3] page size in L2P table for QM module; -4k; -8k; -16k; -32k; -64k;
@@ -1921,6 +2045,9 @@
/* [RW 3] Max burst size filed for read requests port 0; 000 - 128B;
001:256B; 010: 512B; 11:1K:100:2K; 01:4K */
#define PXP2_REG_RQ_RD_MBS0 0x120160
+/* [RW 3] Max burst size filed for read requests port 1; 000 - 128B;
+ 001:256B; 010: 512B; 11:1K:100:2K; 01:4K */
+#define PXP2_REG_RQ_RD_MBS1 0x120168
/* [RW 2] Endian mode for src */
#define PXP2_REG_RQ_SRC_ENDIAN_M 0x12019c
/* [RW 3] page size in L2P table for SRC module; -4k; -8k; -16k; -32k; -64k;
@@ -2000,10 +2127,17 @@
/* [RW 3] Max burst size filed for write requests port 0; 000 - 128B;
001:256B; 010: 512B; */
#define PXP2_REG_RQ_WR_MBS0 0x12015c
+/* [RW 3] Max burst size filed for write requests port 1; 000 - 128B;
+ 001:256B; 010: 512B; */
+#define PXP2_REG_RQ_WR_MBS1 0x120164
/* [RW 10] if Number of entries in dmae fifo will be higer than this
threshold then has_payload indication will be asserted; the default value
should be equal to &gt; write MBS size! */
#define PXP2_REG_WR_DMAE_TH 0x120368
+/* [RW 10] if Number of entries in usdmdp fifo will be higer than this
+ threshold then has_payload indication will be asserted; the default value
+ should be equal to &gt; write MBS size! */
+#define PXP2_REG_WR_USDMDP_TH 0x120348
/* [R 1] debug only: Indication if PSWHST arbiter is idle */
#define PXP_REG_HST_ARB_IS_IDLE 0x103004
/* [R 8] debug only: A bit mask for all PSWHST arbiter clients. '1' means
@@ -2021,6 +2155,8 @@
#define PXP_REG_PXP_INT_STS_CLR_0 0x10306c
/* [RW 26] Parity mask register #0 read/write */
#define PXP_REG_PXP_PRTY_MASK 0x103094
+/* [R 26] Parity register #0 read */
+#define PXP_REG_PXP_PRTY_STS 0x103088
/* [RW 4] The activity counter initial increment value sent in the load
request */
#define QM_REG_ACTCTRINITVAL_0 0x168040
@@ -2127,6 +2263,8 @@
#define QM_REG_QM_INT_STS 0x168438
/* [RW 9] Parity mask register #0 read/write */
#define QM_REG_QM_PRTY_MASK 0x168454
+/* [R 9] Parity register #0 read */
+#define QM_REG_QM_PRTY_STS 0x168448
/* [R 32] Current queues in pipeline: Queues from 32 to 63 */
#define QM_REG_QSTATUS_HIGH 0x16802c
/* [R 32] Current queues in pipeline: Queues from 0 to 31 */
@@ -2410,6 +2548,8 @@
#define SRC_REG_SRC_INT_STS 0x404ac
/* [RW 3] Parity mask register #0 read/write */
#define SRC_REG_SRC_PRTY_MASK 0x404c8
+/* [R 3] Parity register #0 read */
+#define SRC_REG_SRC_PRTY_STS 0x404bc
/* [R 4] Used to read the value of the XX protection CAM occupancy counter. */
#define TCM_REG_CAM_OCCUP 0x5017c
/* [RW 1] CDU AG read Interface enable. If 0 - the request input is
@@ -2730,6 +2870,8 @@
#define TSDM_REG_TSDM_INT_MASK_1 0x422ac
/* [RW 11] Parity mask register #0 read/write */
#define TSDM_REG_TSDM_PRTY_MASK 0x422bc
+/* [R 11] Parity register #0 read */
+#define TSDM_REG_TSDM_PRTY_STS 0x422b0
/* [RW 5] The number of time_slots in the arbitration cycle */
#define TSEM_REG_ARB_CYCLE_SIZE 0x180034
/* [RW 3] The source that is associated with arbitration element 0. Source
@@ -2854,6 +2996,9 @@
/* [RW 32] Parity mask register #0 read/write */
#define TSEM_REG_TSEM_PRTY_MASK_0 0x180120
#define TSEM_REG_TSEM_PRTY_MASK_1 0x180130
+/* [R 32] Parity register #0 read */
+#define TSEM_REG_TSEM_PRTY_STS_0 0x180114
+#define TSEM_REG_TSEM_PRTY_STS_1 0x180124
/* [R 5] Used to read the XX protection CAM occupancy counter. */
#define UCM_REG_CAM_OCCUP 0xe0170
/* [RW 1] CDU AG read Interface enable. If 0 - the request input is
@@ -3155,6 +3300,8 @@
#define USDM_REG_USDM_INT_MASK_1 0xc42b0
/* [RW 11] Parity mask register #0 read/write */
#define USDM_REG_USDM_PRTY_MASK 0xc42c0
+/* [R 11] Parity register #0 read */
+#define USDM_REG_USDM_PRTY_STS 0xc42b4
/* [RW 5] The number of time_slots in the arbitration cycle */
#define USEM_REG_ARB_CYCLE_SIZE 0x300034
/* [RW 3] The source that is associated with arbitration element 0. Source
@@ -3279,6 +3426,9 @@
/* [RW 32] Parity mask register #0 read/write */
#define USEM_REG_USEM_PRTY_MASK_0 0x300130
#define USEM_REG_USEM_PRTY_MASK_1 0x300140
+/* [R 32] Parity register #0 read */
+#define USEM_REG_USEM_PRTY_STS_0 0x300124
+#define USEM_REG_USEM_PRTY_STS_1 0x300134
/* [RW 2] The queue index for registration on Aux1 counter flag. */
#define XCM_REG_AUX1_Q 0x20134
/* [RW 2] Per each decision rule the queue index to register to. */
@@ -3684,6 +3834,8 @@
#define XSDM_REG_XSDM_INT_MASK_1 0x1662ac
/* [RW 11] Parity mask register #0 read/write */
#define XSDM_REG_XSDM_PRTY_MASK 0x1662bc
+/* [R 11] Parity register #0 read */
+#define XSDM_REG_XSDM_PRTY_STS 0x1662b0
/* [RW 5] The number of time_slots in the arbitration cycle */
#define XSEM_REG_ARB_CYCLE_SIZE 0x280034
/* [RW 3] The source that is associated with arbitration element 0. Source
@@ -3808,6 +3960,9 @@
/* [RW 32] Parity mask register #0 read/write */
#define XSEM_REG_XSEM_PRTY_MASK_0 0x280130
#define XSEM_REG_XSEM_PRTY_MASK_1 0x280140
+/* [R 32] Parity register #0 read */
+#define XSEM_REG_XSEM_PRTY_STS_0 0x280124
+#define XSEM_REG_XSEM_PRTY_STS_1 0x280134
#define MCPR_NVM_ACCESS_ENABLE_EN (1L<<0)
#define MCPR_NVM_ACCESS_ENABLE_WR_EN (1L<<1)
#define MCPR_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0)
@@ -3847,6 +4002,8 @@
#define EMAC_MDIO_COMM_START_BUSY (1L<<29)
#define EMAC_MDIO_MODE_AUTO_POLL (1L<<4)
#define EMAC_MDIO_MODE_CLAUSE_45 (1L<<31)
+#define EMAC_MDIO_MODE_CLOCK_CNT (0x3fL<<16)
+#define EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT 16
#define EMAC_MODE_25G_MODE (1L<<5)
#define EMAC_MODE_ACPI_RCVD (1L<<20)
#define EMAC_MODE_HALF_DUPLEX (1L<<1)
@@ -3874,6 +4031,17 @@
#define EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31)
#define EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3)
#define EMAC_TX_MODE_RESET (1L<<0)
+#define MISC_REGISTERS_GPIO_1 1
+#define MISC_REGISTERS_GPIO_2 2
+#define MISC_REGISTERS_GPIO_3 3
+#define MISC_REGISTERS_GPIO_CLR_POS 16
+#define MISC_REGISTERS_GPIO_FLOAT (0xffL<<24)
+#define MISC_REGISTERS_GPIO_FLOAT_POS 24
+#define MISC_REGISTERS_GPIO_INPUT_HI_Z 2
+#define MISC_REGISTERS_GPIO_OUTPUT_HIGH 1
+#define MISC_REGISTERS_GPIO_OUTPUT_LOW 0
+#define MISC_REGISTERS_GPIO_PORT_SHIFT 4
+#define MISC_REGISTERS_GPIO_SET_POS 8
#define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588
#define MISC_REGISTERS_RESET_REG_1_SET 0x584
#define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598
@@ -3891,6 +4059,25 @@
#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW (0x1<<4)
#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB (0x1<<8)
#define MISC_REGISTERS_RESET_REG_3_SET 0x5a4
+#define MISC_REGISTERS_SPIO_4 4
+#define MISC_REGISTERS_SPIO_5 5
+#define MISC_REGISTERS_SPIO_7 7
+#define MISC_REGISTERS_SPIO_CLR_POS 16
+#define MISC_REGISTERS_SPIO_FLOAT (0xffL<<24)
+#define GRC_MISC_REGISTERS_SPIO_FLOAT7 0x80000000
+#define GRC_MISC_REGISTERS_SPIO_FLOAT6 0x40000000
+#define GRC_MISC_REGISTERS_SPIO_FLOAT5 0x20000000
+#define GRC_MISC_REGISTERS_SPIO_FLOAT4 0x10000000
+#define MISC_REGISTERS_SPIO_FLOAT_POS 24
+#define MISC_REGISTERS_SPIO_INPUT_HI_Z 2
+#define MISC_REGISTERS_SPIO_INT_OLD_SET_POS 16
+#define MISC_REGISTERS_SPIO_OUTPUT_HIGH 1
+#define MISC_REGISTERS_SPIO_OUTPUT_LOW 0
+#define MISC_REGISTERS_SPIO_SET_POS 8
+#define HW_LOCK_MAX_RESOURCE_VALUE 31
+#define HW_LOCK_RESOURCE_8072_MDIO 0
+#define HW_LOCK_RESOURCE_GPIO 1
+#define HW_LOCK_RESOURCE_SPIO 2
#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18)
#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31)
#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9)
@@ -3918,6 +4105,7 @@
#define AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT (1<<3)
#define AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR (1<<2)
#define AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR (1<<22)
+#define AEU_INPUTS_ATTN_BITS_SPIO5 (1<<15)
#define AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT (1<<27)
#define AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT (1<<5)
#define AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT (1<<25)
@@ -4206,6 +4394,9 @@
#define MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE 0x4000
#define MDIO_XGXS_BLOCK2_TX_LN_SWAP 0x11
#define MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE 0x8000
+#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G 0x14
+#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS 0x0001
+#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS 0x0010
#define MDIO_XGXS_BLOCK2_TEST_MODE_LANE 0x15
#define MDIO_REG_BANK_GP_STATUS 0x8120
@@ -4362,11 +4553,13 @@
#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE 0x0001
+#define EXT_PHY_AUTO_NEG_DEVAD 0x7
#define EXT_PHY_OPT_PMA_PMD_DEVAD 0x1
#define EXT_PHY_OPT_WIS_DEVAD 0x2
#define EXT_PHY_OPT_PCS_DEVAD 0x3
#define EXT_PHY_OPT_PHY_XS_DEVAD 0x4
#define EXT_PHY_OPT_CNTL 0x0
+#define EXT_PHY_OPT_CNTL2 0x7
#define EXT_PHY_OPT_PMD_RX_SD 0xa
#define EXT_PHY_OPT_PMD_MISC_CNTL 0xca0a
#define EXT_PHY_OPT_PHY_IDENTIFIER 0xc800
@@ -4378,11 +4571,24 @@
#define EXT_PHY_OPT_LASI_STATUS 0x9005
#define EXT_PHY_OPT_PCS_STATUS 0x0020
#define EXT_PHY_OPT_XGXS_LANE_STATUS 0x0018
+#define EXT_PHY_OPT_AN_LINK_STATUS 0x8304
+#define EXT_PHY_OPT_AN_CL37_CL73 0x8370
+#define EXT_PHY_OPT_AN_CL37_FD 0xffe4
+#define EXT_PHY_OPT_AN_CL37_AN 0xffe0
+#define EXT_PHY_OPT_AN_ADV 0x11
#define EXT_PHY_KR_PMA_PMD_DEVAD 0x1
#define EXT_PHY_KR_PCS_DEVAD 0x3
#define EXT_PHY_KR_AUTO_NEG_DEVAD 0x7
#define EXT_PHY_KR_CTRL 0x0000
+#define EXT_PHY_KR_STATUS 0x0001
+#define EXT_PHY_KR_AUTO_NEG_COMPLETE 0x0020
+#define EXT_PHY_KR_AUTO_NEG_ADVERT 0x0010
+#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE 0x0400
+#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC 0x0800
+#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH 0x0C00
+#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK 0x0C00
+#define EXT_PHY_KR_LP_AUTO_NEG 0x0013
#define EXT_PHY_KR_CTRL2 0x0007
#define EXT_PHY_KR_PCS_STATUS 0x0020
#define EXT_PHY_KR_PMD_CTRL 0x0096
@@ -4391,4 +4597,8 @@
#define EXT_PHY_KR_MISC_CTRL1 0xca85
#define EXT_PHY_KR_GEN_CTRL 0xca10
#define EXT_PHY_KR_ROM_CODE 0xca19
+#define EXT_PHY_KR_ROM_RESET_INTERNAL_MP 0x0188
+#define EXT_PHY_KR_ROM_MICRO_RESET 0x018a
+
+#define EXT_PHY_SFX7101_XGXS_TEST1 0xc00a
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index 57175097513..348371fda59 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -172,30 +172,30 @@ static char version[] __initdata =
them to system IRQ numbers. This mapping is card specific and is set to
the configuration of the Cirrus Eval board for this chip. */
#ifdef CONFIG_ARCH_CLPS7500
-static unsigned int netcard_portlist[] __initdata =
+static unsigned int netcard_portlist[] __used __initdata =
{ 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
static unsigned int cs8900_irq_map[] = {12,0,0,0};
#elif defined(CONFIG_SH_HICOSH4)
-static unsigned int netcard_portlist[] __initdata =
+static unsigned int netcard_portlist[] __used __initdata =
{ 0x0300, 0};
static unsigned int cs8900_irq_map[] = {1,0,0,0};
#elif defined(CONFIG_MACH_IXDP2351)
-static unsigned int netcard_portlist[] __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
+static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
#include <asm/irq.h>
#elif defined(CONFIG_ARCH_IXDP2X01)
#include <asm/irq.h>
-static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
+static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
#elif defined(CONFIG_ARCH_PNX010X)
#include <asm/irq.h>
#include <asm/arch/gpio.h>
#define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */
#define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
-static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0};
+static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0};
static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
#else
-static unsigned int netcard_portlist[] __initdata =
+static unsigned int netcard_portlist[] __used __initdata =
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
static unsigned int cs8900_irq_map[] = {10,11,12,5};
#endif
diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c
index 17ed4c3527b..865faee53e1 100644
--- a/drivers/net/cxgb3/l2t.c
+++ b/drivers/net/cxgb3/l2t.c
@@ -404,7 +404,7 @@ found:
if (neigh->nud_state & NUD_FAILED) {
arpq = e->arpq_head;
e->arpq_head = e->arpq_tail = NULL;
- } else if (neigh_is_connected(neigh))
+ } else if (neigh->nud_state & (NUD_CONNECTED|NUD_STALE))
setup_l2e_send_pending(dev, NULL, e);
} else {
e->state = neigh_is_connected(neigh) ?
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 9ca8c66abd1..979f3fc5e76 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1059,6 +1059,14 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb,
htonl(V_WR_TID(q->token)));
}
+static inline void t3_stop_queue(struct net_device *dev, struct sge_qset *qs,
+ struct sge_txq *q)
+{
+ netif_stop_queue(dev);
+ set_bit(TXQ_ETH, &qs->txq_stopped);
+ q->stops++;
+}
+
/**
* eth_xmit - add a packet to the Ethernet Tx queue
* @skb: the packet
@@ -1090,31 +1098,18 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
ndesc = calc_tx_descs(skb);
if (unlikely(credits < ndesc)) {
- if (!netif_queue_stopped(dev)) {
- netif_stop_queue(dev);
- set_bit(TXQ_ETH, &qs->txq_stopped);
- q->stops++;
- dev_err(&adap->pdev->dev,
- "%s: Tx ring %u full while queue awake!\n",
- dev->name, q->cntxt_id & 7);
- }
+ t3_stop_queue(dev, qs, q);
+ dev_err(&adap->pdev->dev,
+ "%s: Tx ring %u full while queue awake!\n",
+ dev->name, q->cntxt_id & 7);
spin_unlock(&q->lock);
return NETDEV_TX_BUSY;
}
q->in_use += ndesc;
- if (unlikely(credits - ndesc < q->stop_thres)) {
- q->stops++;
- netif_stop_queue(dev);
- set_bit(TXQ_ETH, &qs->txq_stopped);
-#if !USE_GTS
- if (should_restart_tx(q) &&
- test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
- q->restarts++;
- netif_wake_queue(dev);
- }
-#endif
- }
+ if (unlikely(credits - ndesc < q->stop_thres))
+ if (USE_GTS || !should_restart_tx(q))
+ t3_stop_queue(dev, qs, q);
gen = q->gen;
q->unacked += ndesc;
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 6a20a5491a9..1fe305ca2cf 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1,7 +1,5 @@
/*
- * dm9000.c: Version 1.2 03/18/2003
- *
- * A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
+ * Davicom DM9000 Fast Ethernet driver for Linux.
* Copyright (C) 1997 Sten Wang
*
* This program is free software; you can redistribute it and/or
@@ -14,44 +12,11 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
- *
- * V0.11 06/20/2001 REG_0A bit3=1, default enable BP with DA match
- * 06/22/2001 Support DM9801 progrmming
- * E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
- * E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
- * R17 = (R17 & 0xfff0) | NF + 3
- * E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
- * R17 = (R17 & 0xfff0) | NF
- *
- * v1.00 modify by simon 2001.9.5
- * change for kernel 2.4.x
- *
- * v1.1 11/09/2001 fix force mode bug
- *
- * v1.2 03/18/2003 Weilun Huang <weilun_huang@davicom.com.tw>:
- * Fixed phy reset.
- * Added tx/rx 32 bit mode.
- * Cleaned up for kernel merge.
- *
- * 03/03/2004 Sascha Hauer <s.hauer@pengutronix.de>
- * Port to 2.6 kernel
- *
- * 24-Sep-2004 Ben Dooks <ben@simtec.co.uk>
- * Cleanup of code to remove ifdefs
- * Allowed platform device data to influence access width
- * Reformatting areas of code
- *
- * 17-Mar-2005 Sascha Hauer <s.hauer@pengutronix.de>
- * * removed 2.4 style module parameters
- * * removed removed unused stat counter and fixed
- * net_device_stats
- * * introduced tx_timeout function
- * * reworked locking
+ * (C) Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
*
- * 01-Jul-2005 Ben Dooks <ben@simtec.co.uk>
- * * fixed spinlock call without pointer
- * * ensure spinlock is initialised
+ * Additional updates, Copyright:
+ * Ben Dooks <ben@simtec.co.uk>
+ * Sascha Hauer <s.hauer@pengutronix.de>
*/
#include <linux/module.h>
@@ -63,6 +28,7 @@
#include <linux/spinlock.h>
#include <linux/crc32.h>
#include <linux/mii.h>
+#include <linux/ethtool.h>
#include <linux/dm9000.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
@@ -80,30 +46,7 @@
#define CARDNAME "dm9000"
#define PFX CARDNAME ": "
-
-#define DM9000_TIMER_WUT jiffies+(HZ*2) /* timer wakeup time : 2 second */
-
-#define DM9000_DEBUG 0
-
-#if DM9000_DEBUG > 2
-#define PRINTK3(args...) printk(CARDNAME ": " args)
-#else
-#define PRINTK3(args...) do { } while(0)
-#endif
-
-#if DM9000_DEBUG > 1
-#define PRINTK2(args...) printk(CARDNAME ": " args)
-#else
-#define PRINTK2(args...) do { } while(0)
-#endif
-
-#if DM9000_DEBUG > 0
-#define PRINTK1(args...) printk(CARDNAME ": " args)
-#define PRINTK(args...) printk(CARDNAME ": " args)
-#else
-#define PRINTK1(args...) do { } while(0)
-#define PRINTK(args...) printk(KERN_DEBUG args)
-#endif
+#define DRV_VERSION "1.30"
#ifdef CONFIG_BLACKFIN
#define readsb insb
@@ -112,9 +55,9 @@
#define writesb outsb
#define writesw outsw
#define writesl outsl
-#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_HIGH)
+#define DEFAULT_TRIGGER IRQF_TRIGGER_HIGH
#else
-#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQT_RISING)
+#define DEFAULT_TRIGGER (0)
#endif
/*
@@ -124,6 +67,24 @@ static int watchdog = 5000;
module_param(watchdog, int, 0400);
MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
+/* DM9000 register address locking.
+ *
+ * The DM9000 uses an address register to control where data written
+ * to the data register goes. This means that the address register
+ * must be preserved over interrupts or similar calls.
+ *
+ * During interrupt and other critical calls, a spinlock is used to
+ * protect the system, but the calls themselves save the address
+ * in the address register in case they are interrupting another
+ * access to the device.
+ *
+ * For general accesses a lock is provided so that calls which are
+ * allowed to sleep are serialised so that the address register does
+ * not need to be saved. This lock also serves to serialise access
+ * to the EEPROM and PHY access registers which are shared between
+ * these two devices.
+ */
+
/* Structure/enum declaration ------------------------------- */
typedef struct board_info {
@@ -137,33 +98,52 @@ typedef struct board_info {
u16 dbug_cnt;
u8 io_mode; /* 0:word, 2:byte */
u8 phy_addr;
+ unsigned int flags;
+ unsigned int in_suspend :1;
+
+ int debug_level;
void (*inblk)(void __iomem *port, void *data, int length);
void (*outblk)(void __iomem *port, void *data, int length);
void (*dumpblk)(void __iomem *port, int length);
+ struct device *dev; /* parent device */
+
struct resource *addr_res; /* resources found */
struct resource *data_res;
struct resource *addr_req; /* resources requested */
struct resource *data_req;
struct resource *irq_res;
- struct timer_list timer;
- unsigned char srom[128];
+ struct mutex addr_lock; /* phy and eeprom access lock */
+
spinlock_t lock;
struct mii_if_info mii;
u32 msg_enable;
} board_info_t;
+/* debug code */
+
+#define dm9000_dbg(db, lev, msg...) do { \
+ if ((lev) < CONFIG_DM9000_DEBUGLEVEL && \
+ (lev) < db->debug_level) { \
+ dev_dbg(db->dev, msg); \
+ } \
+} while (0)
+
+static inline board_info_t *to_dm9000_board(struct net_device *dev)
+{
+ return dev->priv;
+}
+
/* function declaration ------------------------------------- */
static int dm9000_probe(struct platform_device *);
static int dm9000_open(struct net_device *);
static int dm9000_start_xmit(struct sk_buff *, struct net_device *);
static int dm9000_stop(struct net_device *);
+static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd);
-
-static void dm9000_timer(unsigned long);
static void dm9000_init_dm9000(struct net_device *);
static irqreturn_t dm9000_interrupt(int, void *);
@@ -171,20 +151,19 @@ static irqreturn_t dm9000_interrupt(int, void *);
static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg);
static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg,
int value);
-static u16 read_srom_word(board_info_t *, int);
+
+static void dm9000_read_eeprom(board_info_t *, int addr, u8 *to);
+static void dm9000_write_eeprom(board_info_t *, int addr, u8 *dp);
static void dm9000_rx(struct net_device *);
static void dm9000_hash_table(struct net_device *);
-//#define DM9000_PROGRAM_EEPROM
-#ifdef DM9000_PROGRAM_EEPROM
-static void program_eeprom(board_info_t * db);
-#endif
/* DM9000 network board routine ---------------------------- */
static void
dm9000_reset(board_info_t * db)
{
- PRINTK1("dm9000x: resetting\n");
+ dev_dbg(db->dev, "resetting device\n");
+
/* RESET device */
writeb(DM9000_NCR, db->io_addr);
udelay(200);
@@ -300,14 +279,10 @@ static void dm9000_set_io(struct board_info *db, int byte_width)
db->inblk = dm9000_inblk_8bit;
break;
- case 2:
- db->dumpblk = dm9000_dumpblk_16bit;
- db->outblk = dm9000_outblk_16bit;
- db->inblk = dm9000_inblk_16bit;
- break;
case 3:
- printk(KERN_ERR PFX ": 3 byte IO, falling back to 16bit\n");
+ dev_dbg(db->dev, ": 3 byte IO, falling back to 16bit\n");
+ case 2:
db->dumpblk = dm9000_dumpblk_16bit;
db->outblk = dm9000_outblk_16bit;
db->inblk = dm9000_inblk_16bit;
@@ -358,6 +333,139 @@ static void dm9000_poll_controller(struct net_device *dev)
}
#endif
+static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL);
+}
+
+/* ethtool ops */
+
+static void dm9000_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+
+ strcpy(info->driver, CARDNAME);
+ strcpy(info->version, DRV_VERSION);
+ strcpy(info->bus_info, to_platform_device(dm->dev)->name);
+}
+
+static u32 dm9000_get_msglevel(struct net_device *dev)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+
+ return dm->msg_enable;
+}
+
+static void dm9000_set_msglevel(struct net_device *dev, u32 value)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+
+ dm->msg_enable = value;
+}
+
+static int dm9000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+
+ mii_ethtool_gset(&dm->mii, cmd);
+ return 0;
+}
+
+static int dm9000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+
+ return mii_ethtool_sset(&dm->mii, cmd);
+}
+
+static int dm9000_nway_reset(struct net_device *dev)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+ return mii_nway_restart(&dm->mii);
+}
+
+static u32 dm9000_get_link(struct net_device *dev)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+ return mii_link_ok(&dm->mii);
+}
+
+#define DM_EEPROM_MAGIC (0x444D394B)
+
+static int dm9000_get_eeprom_len(struct net_device *dev)
+{
+ return 128;
+}
+
+static int dm9000_get_eeprom(struct net_device *dev,
+ struct ethtool_eeprom *ee, u8 *data)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+ int offset = ee->offset;
+ int len = ee->len;
+ int i;
+
+ /* EEPROM access is aligned to two bytes */
+
+ if ((len & 1) != 0 || (offset & 1) != 0)
+ return -EINVAL;
+
+ if (dm->flags & DM9000_PLATF_NO_EEPROM)
+ return -ENOENT;
+
+ ee->magic = DM_EEPROM_MAGIC;
+
+ for (i = 0; i < len; i += 2)
+ dm9000_read_eeprom(dm, (offset + i) / 2, data + i);
+
+ return 0;
+}
+
+static int dm9000_set_eeprom(struct net_device *dev,
+ struct ethtool_eeprom *ee, u8 *data)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+ int offset = ee->offset;
+ int len = ee->len;
+ int i;
+
+ /* EEPROM access is aligned to two bytes */
+
+ if ((len & 1) != 0 || (offset & 1) != 0)
+ return -EINVAL;
+
+ if (dm->flags & DM9000_PLATF_NO_EEPROM)
+ return -ENOENT;
+
+ if (ee->magic != DM_EEPROM_MAGIC)
+ return -EINVAL;
+
+ for (i = 0; i < len; i += 2)
+ dm9000_write_eeprom(dm, (offset + i) / 2, data + i);
+
+ return 0;
+}
+
+static const struct ethtool_ops dm9000_ethtool_ops = {
+ .get_drvinfo = dm9000_get_drvinfo,
+ .get_settings = dm9000_get_settings,
+ .set_settings = dm9000_set_settings,
+ .get_msglevel = dm9000_get_msglevel,
+ .set_msglevel = dm9000_set_msglevel,
+ .nway_reset = dm9000_nway_reset,
+ .get_link = dm9000_get_link,
+ .get_eeprom_len = dm9000_get_eeprom_len,
+ .get_eeprom = dm9000_get_eeprom,
+ .set_eeprom = dm9000_set_eeprom,
+};
+
+
/* dm9000_release_board
*
* release a board, and any mapped resources
@@ -401,6 +509,7 @@ dm9000_probe(struct platform_device *pdev)
struct dm9000_plat_data *pdata = pdev->dev.platform_data;
struct board_info *db; /* Point a board information structure */
struct net_device *ndev;
+ const unsigned char *mac_src;
unsigned long base;
int ret = 0;
int iosize;
@@ -410,19 +519,22 @@ dm9000_probe(struct platform_device *pdev)
/* Init network device */
ndev = alloc_etherdev(sizeof (struct board_info));
if (!ndev) {
- printk("%s: could not allocate device.\n", CARDNAME);
+ dev_err(&pdev->dev, "could not allocate device.\n");
return -ENOMEM;
}
SET_NETDEV_DEV(ndev, &pdev->dev);
- PRINTK2("dm9000_probe()");
+ dev_dbg(&pdev->dev, "dm9000_probe()");
/* setup board info structure */
db = (struct board_info *) ndev->priv;
memset(db, 0, sizeof (*db));
+ db->dev = &pdev->dev;
+
spin_lock_init(&db->lock);
+ mutex_init(&db->addr_lock);
if (pdev->num_resources < 2) {
ret = -ENODEV;
@@ -450,7 +562,7 @@ dm9000_probe(struct platform_device *pdev)
if (db->addr_res == NULL || db->data_res == NULL ||
db->irq_res == NULL) {
- printk(KERN_ERR PFX "insufficient resources\n");
+ dev_err(db->dev, "insufficient resources\n");
ret = -ENOENT;
goto out;
}
@@ -460,7 +572,7 @@ dm9000_probe(struct platform_device *pdev)
pdev->name);
if (db->addr_req == NULL) {
- printk(KERN_ERR PFX "cannot claim address reg area\n");
+ dev_err(db->dev, "cannot claim address reg area\n");
ret = -EIO;
goto out;
}
@@ -468,7 +580,7 @@ dm9000_probe(struct platform_device *pdev)
db->io_addr = ioremap(db->addr_res->start, i);
if (db->io_addr == NULL) {
- printk(KERN_ERR "failed to ioremap address reg\n");
+ dev_err(db->dev, "failed to ioremap address reg\n");
ret = -EINVAL;
goto out;
}
@@ -478,7 +590,7 @@ dm9000_probe(struct platform_device *pdev)
pdev->name);
if (db->data_req == NULL) {
- printk(KERN_ERR PFX "cannot claim data reg area\n");
+ dev_err(db->dev, "cannot claim data reg area\n");
ret = -EIO;
goto out;
}
@@ -486,7 +598,7 @@ dm9000_probe(struct platform_device *pdev)
db->io_data = ioremap(db->data_res->start, iosize);
if (db->io_data == NULL) {
- printk(KERN_ERR "failed to ioremap data reg\n");
+ dev_err(db->dev,"failed to ioremap data reg\n");
ret = -EINVAL;
goto out;
}
@@ -525,12 +637,14 @@ dm9000_probe(struct platform_device *pdev)
if (pdata->dumpblk != NULL)
db->dumpblk = pdata->dumpblk;
+
+ db->flags = pdata->flags;
}
dm9000_reset(db);
/* try two times, DM9000 sometimes gets the first read wrong */
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < 8; i++) {
id_val = ior(db, DM9000_VIDL);
id_val |= (u32)ior(db, DM9000_VIDH) << 8;
id_val |= (u32)ior(db, DM9000_PIDL) << 16;
@@ -538,11 +652,11 @@ dm9000_probe(struct platform_device *pdev)
if (id_val == DM9000_ID)
break;
- printk("%s: read wrong id 0x%08x\n", CARDNAME, id_val);
+ dev_err(db->dev, "read wrong id 0x%08x\n", id_val);
}
if (id_val != DM9000_ID) {
- printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val);
+ dev_err(db->dev, "wrong id: 0x%08x\n", id_val);
ret = -ENODEV;
goto out;
}
@@ -558,13 +672,13 @@ dm9000_probe(struct platform_device *pdev)
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
ndev->stop = &dm9000_stop;
ndev->set_multicast_list = &dm9000_hash_table;
+ ndev->ethtool_ops = &dm9000_ethtool_ops;
+ ndev->do_ioctl = &dm9000_ioctl;
+
#ifdef CONFIG_NET_POLL_CONTROLLER
ndev->poll_controller = &dm9000_poll_controller;
#endif
-#ifdef DM9000_PROGRAM_EEPROM
- program_eeprom(db);
-#endif
db->msg_enable = NETIF_MSG_LINK;
db->mii.phy_id_mask = 0x1f;
db->mii.reg_num_mask = 0x1f;
@@ -574,38 +688,37 @@ dm9000_probe(struct platform_device *pdev)
db->mii.mdio_read = dm9000_phy_read;
db->mii.mdio_write = dm9000_phy_write;
- /* Read SROM content */
- for (i = 0; i < 64; i++)
- ((u16 *) db->srom)[i] = read_srom_word(db, i);
+ mac_src = "eeprom";
- /* Set Node Address */
- for (i = 0; i < 6; i++)
- ndev->dev_addr[i] = db->srom[i];
+ /* try reading the node address from the attached EEPROM */
+ for (i = 0; i < 6; i += 2)
+ dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
if (!is_valid_ether_addr(ndev->dev_addr)) {
/* try reading from mac */
-
+
+ mac_src = "chip";
for (i = 0; i < 6; i++)
ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
}
if (!is_valid_ether_addr(ndev->dev_addr))
- printk("%s: Invalid ethernet MAC address. Please "
- "set using ifconfig\n", ndev->name);
+ dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
+ "set using ifconfig\n", ndev->name);
platform_set_drvdata(pdev, ndev);
ret = register_netdev(ndev);
if (ret == 0) {
DECLARE_MAC_BUF(mac);
- printk("%s: dm9000 at %p,%p IRQ %d MAC: %s\n",
+ printk("%s: dm9000 at %p,%p IRQ %d MAC: %s (%s)\n",
ndev->name, db->io_addr, db->io_data, ndev->irq,
- print_mac(mac, ndev->dev_addr));
+ print_mac(mac, ndev->dev_addr), mac_src);
}
return 0;
out:
- printk("%s: not found (%d).\n", CARDNAME, ret);
+ dev_err(db->dev, "not found (%d).\n", ret);
dm9000_release_board(pdev, db);
free_netdev(ndev);
@@ -621,10 +734,22 @@ static int
dm9000_open(struct net_device *dev)
{
board_info_t *db = (board_info_t *) dev->priv;
+ unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
- PRINTK2("entering dm9000_open\n");
+ if (netif_msg_ifup(db))
+ dev_dbg(db->dev, "enabling %s\n", dev->name);
- if (request_irq(dev->irq, &dm9000_interrupt, DM9000_IRQ_FLAGS, dev->name, dev))
+ /* If there is no IRQ type specified, default to something that
+ * may work, and tell the user that this is a problem */
+
+ if (irqflags == IRQF_TRIGGER_NONE) {
+ dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
+ irqflags = DEFAULT_TRIGGER;
+ }
+
+ irqflags |= IRQF_SHARED;
+
+ if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
return -EAGAIN;
/* Initialize DM9000 board */
@@ -634,13 +759,6 @@ dm9000_open(struct net_device *dev)
/* Init driver variable */
db->dbug_cnt = 0;
- /* set and active a timer process */
- init_timer(&db->timer);
- db->timer.expires = DM9000_TIMER_WUT;
- db->timer.data = (unsigned long) dev;
- db->timer.function = &dm9000_timer;
- add_timer(&db->timer);
-
mii_check_media(&db->mii, netif_msg_link(db), 1);
netif_start_queue(dev);
@@ -655,7 +773,7 @@ dm9000_init_dm9000(struct net_device *dev)
{
board_info_t *db = (board_info_t *) dev->priv;
- PRINTK1("entering %s\n",__FUNCTION__);
+ dm9000_dbg(db, 1, "entering %s\n", __func__);
/* I/O mode */
db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */
@@ -665,6 +783,9 @@ dm9000_init_dm9000(struct net_device *dev)
iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */
iow(db, DM9000_GPR, 0); /* Enable PHY */
+ if (db->flags & DM9000_PLATF_EXT_PHY)
+ iow(db, DM9000_NCR, NCR_EXT_PHY);
+
/* Program operating register */
iow(db, DM9000_TCR, 0); /* TX Polling clear */
iow(db, DM9000_BPTR, 0x3f); /* Less 3Kb, 200us */
@@ -698,7 +819,7 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
board_info_t *db = (board_info_t *) dev->priv;
- PRINTK3("dm9000_start_xmit\n");
+ dm9000_dbg(db, 3, "%s:\n", __func__);
if (db->tx_pkt_cnt > 1)
return 1;
@@ -715,8 +836,8 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* TX control: First packet immediately send, second packet queue */
if (db->tx_pkt_cnt == 1) {
/* Set TX length to DM9000 */
- iow(db, DM9000_TXPLL, skb->len & 0xff);
- iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff);
+ iow(db, DM9000_TXPLL, skb->len);
+ iow(db, DM9000_TXPLH, skb->len >> 8);
/* Issue TX polling command */
iow(db, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
@@ -757,10 +878,8 @@ dm9000_stop(struct net_device *ndev)
{
board_info_t *db = (board_info_t *) ndev->priv;
- PRINTK1("entering %s\n",__FUNCTION__);
-
- /* deleted timer */
- del_timer(&db->timer);
+ if (netif_msg_ifdown(db))
+ dev_dbg(db->dev, "shutting down %s\n", ndev->name);
netif_stop_queue(ndev);
netif_carrier_off(ndev);
@@ -788,10 +907,13 @@ dm9000_tx_done(struct net_device *dev, board_info_t * db)
db->tx_pkt_cnt--;
dev->stats.tx_packets++;
+ if (netif_msg_tx_done(db))
+ dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);
+
/* Queue packet check & send */
if (db->tx_pkt_cnt > 0) {
- iow(db, DM9000_TXPLL, db->queue_pkt_len & 0xff);
- iow(db, DM9000_TXPLH, (db->queue_pkt_len >> 8) & 0xff);
+ iow(db, DM9000_TXPLL, db->queue_pkt_len);
+ iow(db, DM9000_TXPLH, db->queue_pkt_len >> 8);
iow(db, DM9000_TCR, TCR_TXREQ);
dev->trans_start = jiffies;
}
@@ -803,19 +925,14 @@ static irqreturn_t
dm9000_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
- board_info_t *db;
+ board_info_t *db = (board_info_t *) dev->priv;
int int_status;
u8 reg_save;
- PRINTK3("entering %s\n",__FUNCTION__);
-
- if (!dev) {
- PRINTK1("dm9000_interrupt() without DEVICE arg\n");
- return IRQ_HANDLED;
- }
+ dm9000_dbg(db, 3, "entering %s\n", __func__);
/* A real interrupt coming */
- db = (board_info_t *) dev->priv;
+
spin_lock(&db->lock);
/* Save previous register address */
@@ -828,6 +945,9 @@ dm9000_interrupt(int irq, void *dev_id)
int_status = ior(db, DM9000_ISR); /* Got ISR */
iow(db, DM9000_ISR, int_status); /* Clear ISR status */
+ if (netif_msg_intr(db))
+ dev_dbg(db->dev, "interrupt status %02x\n", int_status);
+
/* Received the coming packet */
if (int_status & ISR_PRS)
dm9000_rx(dev);
@@ -847,27 +967,9 @@ dm9000_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-/*
- * A periodic timer routine
- * Dynamic media sense, allocated Rx buffer...
- */
-static void
-dm9000_timer(unsigned long data)
-{
- struct net_device *dev = (struct net_device *) data;
- board_info_t *db = (board_info_t *) dev->priv;
-
- PRINTK3("dm9000_timer()\n");
-
- mii_check_media(&db->mii, netif_msg_link(db), 0);
-
- /* Set timer again */
- db->timer.expires = DM9000_TIMER_WUT;
- add_timer(&db->timer);
-}
-
struct dm9000_rxhdr {
- u16 RxStatus;
+ u8 RxPktReady;
+ u8 RxStatus;
u16 RxLen;
} __attribute__((__packed__));
@@ -893,7 +995,7 @@ dm9000_rx(struct net_device *dev)
/* Status check: this byte must be 0 or 1 */
if (rxbyte > DM9000_PKT_RDY) {
- printk("status check failed: %d\n", rxbyte);
+ dev_warn(db->dev, "status check fail: %d\n", rxbyte);
iow(db, DM9000_RCR, 0x00); /* Stop Device */
iow(db, DM9000_ISR, IMR_PAR); /* Stop INT request */
return;
@@ -908,30 +1010,38 @@ dm9000_rx(struct net_device *dev)
(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));
- RxLen = rxhdr.RxLen;
+ RxLen = le16_to_cpu(rxhdr.RxLen);
+
+ if (netif_msg_rx_status(db))
+ dev_dbg(db->dev, "RX: status %02x, length %04x\n",
+ rxhdr.RxStatus, RxLen);
/* Packet Status check */
if (RxLen < 0x40) {
GoodPacket = false;
- PRINTK1("Bad Packet received (runt)\n");
+ if (netif_msg_rx_err(db))
+ dev_dbg(db->dev, "RX: Bad Packet (runt)\n");
}
if (RxLen > DM9000_PKT_MAX) {
- PRINTK1("RST: RX Len:%x\n", RxLen);
+ dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);
}
- if (rxhdr.RxStatus & 0xbf00) {
+ if (rxhdr.RxStatus & 0xbf) {
GoodPacket = false;
- if (rxhdr.RxStatus & 0x100) {
- PRINTK1("fifo error\n");
+ if (rxhdr.RxStatus & 0x01) {
+ if (netif_msg_rx_err(db))
+ dev_dbg(db->dev, "fifo error\n");
dev->stats.rx_fifo_errors++;
}
- if (rxhdr.RxStatus & 0x200) {
- PRINTK1("crc error\n");
+ if (rxhdr.RxStatus & 0x02) {
+ if (netif_msg_rx_err(db))
+ dev_dbg(db->dev, "crc error\n");
dev->stats.rx_crc_errors++;
}
- if (rxhdr.RxStatus & 0x8000) {
- PRINTK1("length error\n");
+ if (rxhdr.RxStatus & 0x80) {
+ if (netif_msg_rx_err(db))
+ dev_dbg(db->dev, "length error\n");
dev->stats.rx_length_errors++;
}
}
@@ -960,72 +1070,119 @@ dm9000_rx(struct net_device *dev)
} while (rxbyte == DM9000_PKT_RDY);
}
-/*
- * Read a word data from SROM
- */
-static u16
-read_srom_word(board_info_t * db, int offset)
+static unsigned int
+dm9000_read_locked(board_info_t *db, int reg)
{
- iow(db, DM9000_EPAR, offset);
- iow(db, DM9000_EPCR, EPCR_ERPRR);
- mdelay(8); /* according to the datasheet 200us should be enough,
- but it doesn't work */
- iow(db, DM9000_EPCR, 0x0);
- return (ior(db, DM9000_EPDRL) + (ior(db, DM9000_EPDRH) << 8));
+ unsigned long flags;
+ unsigned int ret;
+
+ spin_lock_irqsave(&db->lock, flags);
+ ret = ior(db, reg);
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ return ret;
+}
+
+static int dm9000_wait_eeprom(board_info_t *db)
+{
+ unsigned int status;
+ int timeout = 8; /* wait max 8msec */
+
+ /* The DM9000 data sheets say we should be able to
+ * poll the ERRE bit in EPCR to wait for the EEPROM
+ * operation. From testing several chips, this bit
+ * does not seem to work.
+ *
+ * We attempt to use the bit, but fall back to the
+ * timeout (which is why we do not return an error
+ * on expiry) to say that the EEPROM operation has
+ * completed.
+ */
+
+ while (1) {
+ status = dm9000_read_locked(db, DM9000_EPCR);
+
+ if ((status & EPCR_ERRE) == 0)
+ break;
+
+ if (timeout-- < 0) {
+ dev_dbg(db->dev, "timeout waiting EEPROM\n");
+ break;
+ }
+ }
+
+ return 0;
}
-#ifdef DM9000_PROGRAM_EEPROM
/*
- * Write a word data to SROM
+ * Read a word data from EEPROM
*/
static void
-write_srom_word(board_info_t * db, int offset, u16 val)
+dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
{
+ unsigned long flags;
+
+ if (db->flags & DM9000_PLATF_NO_EEPROM) {
+ to[0] = 0xff;
+ to[1] = 0xff;
+ return;
+ }
+
+ mutex_lock(&db->addr_lock);
+
+ spin_lock_irqsave(&db->lock, flags);
+
iow(db, DM9000_EPAR, offset);
- iow(db, DM9000_EPDRH, ((val >> 8) & 0xff));
- iow(db, DM9000_EPDRL, (val & 0xff));
- iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
- mdelay(8); /* same shit */
- iow(db, DM9000_EPCR, 0);
+ iow(db, DM9000_EPCR, EPCR_ERPRR);
+
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ dm9000_wait_eeprom(db);
+
+ /* delay for at-least 150uS */
+ msleep(1);
+
+ spin_lock_irqsave(&db->lock, flags);
+
+ iow(db, DM9000_EPCR, 0x0);
+
+ to[0] = ior(db, DM9000_EPDRL);
+ to[1] = ior(db, DM9000_EPDRH);
+
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ mutex_unlock(&db->addr_lock);
}
/*
- * Only for development:
- * Here we write static data to the eeprom in case
- * we don't have valid content on a new board
+ * Write a word data to SROM
*/
static void
-program_eeprom(board_info_t * db)
+dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
{
- u16 eeprom[] = { 0x0c00, 0x007f, 0x1300, /* MAC Address */
- 0x0000, /* Autoload: accept nothing */
- 0x0a46, 0x9000, /* Vendor / Product ID */
- 0x0000, /* pin control */
- 0x0000,
- }; /* Wake-up mode control */
- int i;
- for (i = 0; i < 8; i++)
- write_srom_word(db, i, eeprom[i]);
-}
-#endif
+ unsigned long flags;
+ if (db->flags & DM9000_PLATF_NO_EEPROM)
+ return;
-/*
- * Calculate the CRC valude of the Rx packet
- * flag = 1 : return the reverse CRC (for the received packet CRC)
- * 0 : return the normal CRC (for Hash Table index)
- */
+ mutex_lock(&db->addr_lock);
-static unsigned long
-cal_CRC(unsigned char *Data, unsigned int Len, u8 flag)
-{
+ spin_lock_irqsave(&db->lock, flags);
+ iow(db, DM9000_EPAR, offset);
+ iow(db, DM9000_EPDRH, data[1]);
+ iow(db, DM9000_EPDRL, data[0]);
+ iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ dm9000_wait_eeprom(db);
- u32 crc = ether_crc_le(Len, Data);
+ mdelay(1); /* wait at least 150uS to clear */
- if (flag)
- return ~crc;
+ spin_lock_irqsave(&db->lock, flags);
+ iow(db, DM9000_EPCR, 0);
+ spin_unlock_irqrestore(&db->lock, flags);
- return crc;
+ mutex_unlock(&db->addr_lock);
}
/*
@@ -1037,15 +1194,16 @@ dm9000_hash_table(struct net_device *dev)
board_info_t *db = (board_info_t *) dev->priv;
struct dev_mc_list *mcptr = dev->mc_list;
int mc_cnt = dev->mc_count;
+ int i, oft;
u32 hash_val;
- u16 i, oft, hash_table[4];
+ u16 hash_table[4];
unsigned long flags;
- PRINTK2("dm9000_hash_table()\n");
+ dm9000_dbg(db, 1, "entering %s\n", __func__);
- spin_lock_irqsave(&db->lock,flags);
+ spin_lock_irqsave(&db->lock, flags);
- for (i = 0, oft = 0x10; i < 6; i++, oft++)
+ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
iow(db, oft, dev->dev_addr[i]);
/* Clear Hash Table */
@@ -1057,21 +1215,33 @@ dm9000_hash_table(struct net_device *dev)
/* the multicast address in Hash Table : 64 bits */
for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
- hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f;
+ hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f;
hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
}
/* Write the hash table to MAC MD table */
- for (i = 0, oft = 0x16; i < 4; i++) {
- iow(db, oft++, hash_table[i] & 0xff);
- iow(db, oft++, (hash_table[i] >> 8) & 0xff);
+ for (i = 0, oft = DM9000_MAR; i < 4; i++) {
+ iow(db, oft++, hash_table[i]);
+ iow(db, oft++, hash_table[i] >> 8);
}
- spin_unlock_irqrestore(&db->lock,flags);
+ spin_unlock_irqrestore(&db->lock, flags);
}
/*
+ * Sleep, either by using msleep() or if we are suspending, then
+ * use mdelay() to sleep.
+ */
+static void dm9000_msleep(board_info_t *db, unsigned int ms)
+{
+ if (db->in_suspend)
+ mdelay(ms);
+ else
+ msleep(ms);
+}
+
+/*
* Read a word from phyxcer
*/
static int
@@ -1082,6 +1252,8 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
unsigned int reg_save;
int ret;
+ mutex_lock(&db->addr_lock);
+
spin_lock_irqsave(&db->lock,flags);
/* Save previous register address */
@@ -1091,7 +1263,15 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
iow(db, DM9000_EPAR, DM9000_PHY | reg);
iow(db, DM9000_EPCR, 0xc); /* Issue phyxcer read command */
- udelay(100); /* Wait read complete */
+
+ writeb(reg_save, db->io_addr);
+ spin_unlock_irqrestore(&db->lock,flags);
+
+ dm9000_msleep(db, 1); /* Wait read complete */
+
+ spin_lock_irqsave(&db->lock,flags);
+ reg_save = readb(db->io_addr);
+
iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */
/* The read data keeps on REG_0D & REG_0E */
@@ -1099,9 +1279,9 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
/* restore the previous address */
writeb(reg_save, db->io_addr);
-
spin_unlock_irqrestore(&db->lock,flags);
+ mutex_unlock(&db->addr_lock);
return ret;
}
@@ -1115,6 +1295,8 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
unsigned long flags;
unsigned long reg_save;
+ mutex_lock(&db->addr_lock);
+
spin_lock_irqsave(&db->lock,flags);
/* Save previous register address */
@@ -1124,25 +1306,38 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
iow(db, DM9000_EPAR, DM9000_PHY | reg);
/* Fill the written data into REG_0D & REG_0E */
- iow(db, DM9000_EPDRL, (value & 0xff));
- iow(db, DM9000_EPDRH, ((value >> 8) & 0xff));
+ iow(db, DM9000_EPDRL, value);
+ iow(db, DM9000_EPDRH, value >> 8);
iow(db, DM9000_EPCR, 0xa); /* Issue phyxcer write command */
- udelay(500); /* Wait write complete */
+
+ writeb(reg_save, db->io_addr);
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ dm9000_msleep(db, 1); /* Wait write complete */
+
+ spin_lock_irqsave(&db->lock,flags);
+ reg_save = readb(db->io_addr);
+
iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */
/* restore the previous address */
writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock,flags);
+ spin_unlock_irqrestore(&db->lock, flags);
+ mutex_unlock(&db->addr_lock);
}
static int
dm9000_drv_suspend(struct platform_device *dev, pm_message_t state)
{
struct net_device *ndev = platform_get_drvdata(dev);
+ board_info_t *db;
if (ndev) {
+ db = (board_info_t *) ndev->priv;
+ db->in_suspend = 1;
+
if (netif_running(ndev)) {
netif_device_detach(ndev);
dm9000_shutdown(ndev);
@@ -1165,6 +1360,8 @@ dm9000_drv_resume(struct platform_device *dev)
netif_device_attach(ndev);
}
+
+ db->in_suspend = 0;
}
return 0;
}
@@ -1180,8 +1377,7 @@ dm9000_drv_remove(struct platform_device *pdev)
dm9000_release_board(pdev, (board_info_t *) ndev->priv);
free_netdev(ndev); /* free device structure */
- PRINTK1("clean_module() exit\n");
-
+ dev_dbg(&pdev->dev, "released and freed device\n");
return 0;
}
@@ -1199,7 +1395,7 @@ static struct platform_driver dm9000_driver = {
static int __init
dm9000_init(void)
{
- printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME);
+ printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);
return platform_driver_register(&dm9000_driver); /* search board and register */
}
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index d876787ce33..85e66f4c788 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -50,7 +50,7 @@ struct e1000_stats {
int stat_offset;
};
-#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
+#define E1000_STAT(m) FIELD_SIZEOF(struct e1000_adapter, m), \
offsetof(struct e1000_adapter, m)
static const struct e1000_stats e1000_gstrings_stats[] = {
{ "rx_packets", E1000_STAT(stats.gprc) },
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 7c5b05a82f0..0991648c53d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -926,8 +926,6 @@ e1000_probe(struct pci_dev *pdev,
{
struct net_device *netdev;
struct e1000_adapter *adapter;
- unsigned long mmio_start, mmio_len;
- unsigned long flash_start, flash_len;
static int cards_found = 0;
static int global_quad_port_a = 0; /* global ksp3 port a indication */
@@ -970,11 +968,9 @@ e1000_probe(struct pci_dev *pdev,
adapter->hw.back = adapter;
adapter->msg_enable = (1 << debug) - 1;
- mmio_start = pci_resource_start(pdev, BAR_0);
- mmio_len = pci_resource_len(pdev, BAR_0);
-
err = -EIO;
- adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
+ adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
+ pci_resource_len(pdev, BAR_0));
if (!adapter->hw.hw_addr)
goto err_ioremap;
@@ -1009,10 +1005,6 @@ e1000_probe(struct pci_dev *pdev,
#endif
strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
- netdev->mem_start = mmio_start;
- netdev->mem_end = mmio_start + mmio_len;
- netdev->base_addr = adapter->hw.io_base;
-
adapter->bd_number = cards_found;
/* setup the private structure */
@@ -1025,9 +1017,9 @@ e1000_probe(struct pci_dev *pdev,
* because it depends on mac_type */
if ((adapter->hw.mac_type == e1000_ich8lan) &&
(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
- flash_start = pci_resource_start(pdev, 1);
- flash_len = pci_resource_len(pdev, 1);
- adapter->hw.flash_address = ioremap(flash_start, flash_len);
+ adapter->hw.flash_address =
+ ioremap(pci_resource_start(pdev, 1),
+ pci_resource_len(pdev, 1));
if (!adapter->hw.flash_address)
goto err_flashmap;
}
@@ -1203,6 +1195,14 @@ e1000_probe(struct pci_dev *pdev,
printk("%s\n", print_mac(mac, netdev->dev_addr));
+ if (adapter->hw.bus_type == e1000_bus_type_pci_express) {
+ DPRINTK(PROBE, WARNING, "This device (id %04x:%04x) will no "
+ "longer be supported by this driver in the future.\n",
+ pdev->vendor, pdev->device);
+ DPRINTK(PROBE, WARNING, "please use the \"e1000e\" "
+ "driver instead.\n");
+ }
+
/* reset the hardware with the new settings */
e1000_reset(adapter);
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 3beace55b58..7fe20310eb5 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -438,7 +438,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw)
* For non-82573 silicon, write data to EEPROM at offset using SPI interface.
*
* If e1000e_update_nvm_checksum is not called after this function, the
- * EEPROM will most likley contain an invalid checksum.
+ * EEPROM will most likely contain an invalid checksum.
**/
static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
@@ -547,7 +547,7 @@ static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw)
* poll for completion.
*
* If e1000e_update_nvm_checksum is not called after this function, the
- * EEPROM will most likley contain an invalid checksum.
+ * EEPROM will most likely contain an invalid checksum.
**/
static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data)
@@ -1053,7 +1053,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
/* If SerDes loopback mode is entered, there is no form
* of reset to take the adapter out of that mode. So we
* have to explicitly take the adapter out of loopback
- * mode. This prevents drivers from twidling their thumbs
+ * mode. This prevents drivers from twiddling their thumbs
* if another tool failed to take it out of loopback mode.
*/
ew32(SCTL,
@@ -1098,7 +1098,7 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
* e1000e_get_laa_state_82571 - Get locally administered address state
* @hw: pointer to the HW structure
*
- * Retrieve and return the current locally administed address state.
+ * Retrieve and return the current locally administered address state.
**/
bool e1000e_get_laa_state_82571(struct e1000_hw *hw)
{
@@ -1113,7 +1113,7 @@ bool e1000e_get_laa_state_82571(struct e1000_hw *hw)
* @hw: pointer to the HW structure
* @state: enable/disable locally administered address
*
- * Enable/Disable the current locally administed address state.
+ * Enable/Disable the current locally administers address state.
**/
void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state)
{
@@ -1281,16 +1281,6 @@ static struct e1000_phy_operations e82_phy_ops_m88 = {
static struct e1000_nvm_operations e82571_nvm_ops = {
.acquire_nvm = e1000_acquire_nvm_82571,
- .read_nvm = e1000e_read_nvm_spi,
- .release_nvm = e1000_release_nvm_82571,
- .update_nvm = e1000_update_nvm_checksum_82571,
- .valid_led_default = e1000_valid_led_default_82571,
- .validate_nvm = e1000_validate_nvm_checksum_82571,
- .write_nvm = e1000_write_nvm_82571,
-};
-
-static struct e1000_nvm_operations e82573_nvm_ops = {
- .acquire_nvm = e1000_acquire_nvm_82571,
.read_nvm = e1000e_read_nvm_eerd,
.release_nvm = e1000_release_nvm_82571,
.update_nvm = e1000_update_nvm_checksum_82571,
@@ -1355,6 +1345,6 @@ struct e1000_info e1000_82573_info = {
.get_invariants = e1000_get_invariants_82571,
.mac_ops = &e82571_mac_ops,
.phy_ops = &e82_phy_ops_m88,
- .nvm_ops = &e82573_nvm_ops,
+ .nvm_ops = &e82571_nvm_ops,
};
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 6232c3e9668..a4f511f549f 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -66,7 +66,7 @@
#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
/* Extended Device Control */
-#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
+#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
@@ -75,12 +75,12 @@
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
-/* Receive Decriptor bit definitions */
+/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
+#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
@@ -223,7 +223,7 @@
#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
-/* Constants used to intrepret the masked PCI-X bus speed. */
+/* Constants used to interpret the masked PCI-X bus speed. */
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2
@@ -517,7 +517,7 @@
/* PHY 1000 MII Register/Bit Definitions */
/* PHY Registers defined by IEEE */
#define PHY_CONTROL 0x00 /* Control Register */
-#define PHY_STATUS 0x01 /* Status Regiser */
+#define PHY_STATUS 0x01 /* Status Register */
#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 8b88c226e85..327c0620da3 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -42,8 +42,7 @@
struct e1000_info;
#define ndev_printk(level, netdev, format, arg...) \
- printk(level "%s: %s: " format, (netdev)->dev.parent->bus_id, \
- (netdev)->name, ## arg)
+ printk(level "%s: " format, (netdev)->name, ## arg)
#ifdef DEBUG
#define ndev_dbg(netdev, format, arg...) \
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 3c5862f97db..916025b30fc 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -184,7 +184,7 @@ enum e1e_registers {
E1000_ICRXDMTC = 0x04120, /* Irq Cause Rx Desc MinThreshold Count */
E1000_ICRXOC = 0x04124, /* Irq Cause Receiver Overrun Count */
E1000_RXCSUM = 0x05000, /* RX Checksum Control - RW */
- E1000_RFCTL = 0x05008, /* Receive Filter Control*/
+ E1000_RFCTL = 0x05008, /* Receive Filter Control */
E1000_MTA = 0x05200, /* Multicast Table Array - RW Array */
E1000_RA = 0x05400, /* Receive Address - RW Array */
E1000_VFTA = 0x05600, /* VLAN Filter Table Array - RW Array */
@@ -202,7 +202,7 @@ enum e1e_registers {
E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */
E1000_SWSM = 0x05B50, /* SW Semaphore */
E1000_FWSM = 0x05B54, /* FW Semaphore */
- E1000_HICR = 0x08F00, /* Host Inteface Control */
+ E1000_HICR = 0x08F00, /* Host Interface Control */
};
/* RSS registers */
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 8f8139de1f4..0ae39550768 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -671,7 +671,7 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
* e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY
* @hw: pointer to the HW structure
*
- * Polarity is determined on the polarity reveral feature being enabled.
+ * Polarity is determined on the polarity reversal feature being enabled.
* This function is only called by other family-specific
* routines.
**/
@@ -947,7 +947,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
/* Either we should have a hardware SPI cycle in progress
* bit to check against, in order to start a new cycle or
* FDONE bit should be changed in the hardware so that it
- * is 1 after harware reset, which can then be used as an
+ * is 1 after hardware reset, which can then be used as an
* indication whether a cycle is in progress or has been
* completed.
*/
@@ -1155,7 +1155,7 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
* which writes the checksum to the shadow ram. The changes in the shadow
* ram are then committed to the EEPROM by processing each bank at a time
* checking for the modified bit and writing only the pending changes.
- * After a succesful commit, the shadow ram is cleared and is ready for
+ * After a successful commit, the shadow ram is cleared and is ready for
* future writes.
**/
static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
@@ -1680,7 +1680,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
* - initialize LED identification
* - setup receive address registers
* - setup flow control
- * - setup transmit discriptors
+ * - setup transmit descriptors
* - clear statistics
**/
static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
@@ -1961,7 +1961,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
ew32(PHY_CTRL, phy_ctrl);
- /* Call gig speed drop workaround on Giga disable before accessing
+ /* Call gig speed drop workaround on Gig disable before accessing
* any PHY registers */
e1000e_gig_downshift_workaround_ich8lan(hw);
@@ -1972,7 +1972,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
/**
* e1000_set_kmrn_lock_loss_workaound_ich8lan - Set Kumeran workaround state
* @hw: pointer to the HW structure
- * @state: boolean value used to set the current Kumaran workaround state
+ * @state: boolean value used to set the current Kumeran workaround state
*
* If ICH8, set the current Kumeran workaround state (enabled - TRUE
* /disabled - FALSE).
@@ -2017,7 +2017,7 @@ void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
ew32(PHY_CTRL, reg);
- /* Call gig speed drop workaround on Giga disable before
+ /* Call gig speed drop workaround on Gig disable before
* accessing any PHY registers */
if (hw->mac.type == e1000_ich8lan)
e1000e_gig_downshift_workaround_ich8lan(hw);
@@ -2045,7 +2045,7 @@ void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
* @hw: pointer to the HW structure
*
* Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC),
- * LPLU, Giga disable, MDIC PHY reset):
+ * LPLU, Gig disable, MDIC PHY reset):
* 1) Set Kumeran Near-end loopback
* 2) Clear Kumeran Near-end loopback
* Should only be called for ICH8[m] devices with IGP_3 Phy.
@@ -2089,10 +2089,10 @@ static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw)
}
/**
- * e1000_led_on_ich8lan - Turn LED's on
+ * e1000_led_on_ich8lan - Turn LEDs on
* @hw: pointer to the HW structure
*
- * Turn on the LED's.
+ * Turn on the LEDs.
**/
static s32 e1000_led_on_ich8lan(struct e1000_hw *hw)
{
@@ -2105,10 +2105,10 @@ static s32 e1000_led_on_ich8lan(struct e1000_hw *hw)
}
/**
- * e1000_led_off_ich8lan - Turn LED's off
+ * e1000_led_off_ich8lan - Turn LEDs off
* @hw: pointer to the HW structure
*
- * Turn off the LED's.
+ * Turn off the LEDs.
**/
static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
{
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 16f35fadb74..95f75a43c9f 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -589,9 +589,6 @@ static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
s32 ret_val;
u16 nvm_data;
- if (mac->fc != e1000_fc_default)
- return 0;
-
/* Read and store word 0x0F of the EEPROM. This word contains bits
* that determine the hardware's default PAUSE (flow control) mode,
* a bit that determines whether the HW defaults to enabling or
@@ -1107,34 +1104,13 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
mac->fc = e1000_fc_rx_pause;
hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
- }
- /* Per the IEEE spec, at this point flow control should be
- * disabled. However, we want to consider that we could
- * be connected to a legacy switch that doesn't advertise
- * desired flow control, but can be forced on the link
- * partner. So if we advertised no flow control, that is
- * what we will resolve to. If we advertised some kind of
- * receive capability (Rx Pause Only or Full Flow Control)
- * and the link partner advertised none, we will configure
- * ourselves to enable Rx Flow Control only. We can do
- * this safely for two reasons: If the link partner really
- * didn't want flow control enabled, and we enable Rx, no
- * harm done since we won't be receiving any PAUSE frames
- * anyway. If the intent on the link partner was to have
- * flow control enabled, then by us enabling RX only, we
- * can at least receive pause frames and process them.
- * This is a good idea because in most cases, since we are
- * predominantly a server NIC, more times than not we will
- * be asked to delay transmission of packets than asking
- * our link partner to pause transmission of frames.
- */
- else if ((mac->original_fc == e1000_fc_none) ||
- (mac->original_fc == e1000_fc_tx_pause)) {
+ } else {
+ /*
+ * Per the IEEE spec, at this point flow control
+ * should be disabled.
+ */
mac->fc = e1000_fc_none;
hw_dbg(hw, "Flow Control = NONE.\r\n");
- } else {
- mac->fc = e1000_fc_rx_pause;
- hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
}
/* Now we need to do one last check... If we auto-
@@ -1164,7 +1140,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
}
/**
- * e1000e_get_speed_and_duplex_copper - Retreive current speed/duplex
+ * e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
@@ -1200,7 +1176,7 @@ s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *dup
}
/**
- * e1000e_get_speed_and_duplex_fiber_serdes - Retreive current speed/duplex
+ * e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
@@ -1410,7 +1386,7 @@ s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
* e1000e_blink_led - Blink LED
* @hw: pointer to the HW structure
*
- * Blink the led's which are set to be on.
+ * Blink the LEDs which are set to be on.
**/
s32 e1000e_blink_led(struct e1000_hw *hw)
{
@@ -1515,7 +1491,7 @@ void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop)
* @hw: pointer to the HW structure
*
* Returns 0 if successful, else returns -10
- * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not casued
+ * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
* the master requests to be disabled.
*
* Disables PCI-Express master access and verifies there are no pending
@@ -1876,7 +1852,7 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
}
/**
- * e1000e_read_nvm_spi - Read EEPROM's using SPI
+ * e1000e_read_nvm_spi - Reads EEPROM using SPI
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
@@ -1980,7 +1956,7 @@ s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000e_update_nvm_checksum is not called after this function , the
- * EEPROM will most likley contain an invalid checksum.
+ * EEPROM will most likely contain an invalid checksum.
**/
s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
@@ -2222,7 +2198,7 @@ static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
*
* Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
*
- * This function checks whether the HOST IF is enabled for command operaton
+ * This function checks whether the HOST IF is enabled for command operation
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
**/
@@ -2254,7 +2230,7 @@ static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
}
/**
- * e1000e_check_mng_mode - check managament mode
+ * e1000e_check_mng_mode - check management mode
* @hw: pointer to the HW structure
*
* Reads the firmware semaphore register and returns true (>0) if
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index f58f017ee47..fc5c63f4f57 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -1006,7 +1006,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
* e1000_get_hw_control - get control of the h/w from f/w
* @adapter: address of board private structure
*
- * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
+ * e1000_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
* For ASF and Pass Through versions of f/w this means that
* the driver is loaded. For AMT version (only with 82573)
* of the f/w this means that the network i/f is open.
@@ -1032,7 +1032,7 @@ static void e1000_get_hw_control(struct e1000_adapter *adapter)
* e1000_release_hw_control - release control of the h/w to f/w
* @adapter: address of board private structure
*
- * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
+ * e1000_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
* For ASF and Pass Through versions of f/w this means that the
* driver is no longer loaded. For AMT version (only with 82573) i
* of the f/w this means that the network i/f is closed.
@@ -1055,23 +1055,6 @@ static void e1000_release_hw_control(struct e1000_adapter *adapter)
}
}
-static void e1000_release_manageability(struct e1000_adapter *adapter)
-{
- if (adapter->flags & FLAG_MNG_PT_ENABLED) {
- struct e1000_hw *hw = &adapter->hw;
-
- u32 manc = er32(MANC);
-
- /* re-enable hardware interception of ARP */
- manc |= E1000_MANC_ARP_EN;
- manc &= ~E1000_MANC_EN_MNG2HOST;
-
- /* don't explicitly have to mess with MANC2H since
- * MANC has an enable disable that gates MANC2H */
- ew32(MANC, manc);
- }
-}
-
/**
* @e1000_alloc_ring - allocate memory for a ring structure
**/
@@ -1258,6 +1241,11 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter)
/**
* e1000_update_itr - update the dynamic ITR value based on statistics
+ * @adapter: pointer to adapter
+ * @itr_setting: current adapter->itr
+ * @packets: the number of packets during this measurement interval
+ * @bytes: the number of bytes during this measurement interval
+ *
* Stores a new ITR value based on packets and byte
* counts during the last interrupt. The advantage of per interrupt
* computation is faster updates and more accurate ITR for the current
@@ -1267,10 +1255,6 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter)
* while increasing bulk throughput.
* this functionality is controlled by the InterruptThrottleRate module
* parameter (see e1000_param.c)
- * @adapter: pointer to adapter
- * @itr_setting: current adapter->itr
- * @packets: the number of packets during this measurement interval
- * @bytes: the number of bytes during this measurement interval
**/
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
u16 itr_setting, int packets,
@@ -1383,6 +1367,7 @@ set_itr_now:
/**
* e1000_clean - NAPI Rx polling callback
* @adapter: board private structure
+ * @budget: amount of packets driver is allowed to process this poll
**/
static int e1000_clean(struct napi_struct *napi, int budget)
{
@@ -1561,9 +1546,6 @@ static void e1000_init_manageability(struct e1000_adapter *adapter)
manc = er32(MANC);
- /* disable hardware interception of ARP */
- manc &= ~(E1000_MANC_ARP_EN);
-
/* enable receiving management packets to the host. this will probably
* generate destination unreachable messages from the host OS, but
* the packets will be handled on SMBUS */
@@ -1690,6 +1672,9 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
else
rctl |= E1000_RCTL_LPE;
+ /* Enable hardware CRC frame stripping */
+ rctl |= E1000_RCTL_SECRC;
+
/* Setup buffer sizes */
rctl &= ~E1000_RCTL_SZ_4096;
rctl |= E1000_RCTL_BSEX;
@@ -1755,9 +1740,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
/* Enable Packet split descriptors */
rctl |= E1000_RCTL_DTYP_PS;
-
- /* Enable hardware CRC frame stripping */
- rctl |= E1000_RCTL_SECRC;
psrctl |= adapter->rx_ps_bsize0 >>
E1000_PSRCTL_BSIZE0_SHIFT;
@@ -2008,7 +1990,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter)
u16 mii_reg;
/* WoL is enabled */
- if (!adapter->wol)
+ if (adapter->wol)
return;
/* non-copper PHY? */
@@ -2020,7 +2002,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter)
e1000_check_reset_block(hw))
return;
- /* managebility (AMT) is enabled */
+ /* manageability (AMT) is enabled */
if (er32(MANC) & E1000_MANC_SMBUS_EN)
return;
@@ -2140,8 +2122,6 @@ void e1000e_reset(struct e1000_adapter *adapter)
phy_data &= ~IGP02E1000_PM_SPD;
e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
}
-
- e1000_release_manageability(adapter);
}
int e1000e_up(struct e1000_adapter *adapter)
@@ -3487,8 +3467,6 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
pci_enable_wake(pdev, PCI_D3cold, 0);
}
- e1000_release_manageability(adapter);
-
/* make sure adapter isn't asleep if manageability is enabled */
if (adapter->flags & FLAG_MNG_PT_ENABLED) {
pci_enable_wake(pdev, PCI_D3hot, 1);
@@ -3512,7 +3490,6 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
static void e1000e_disable_l1aspm(struct pci_dev *pdev)
{
int pos;
- u32 cap;
u16 val;
/*
@@ -3527,7 +3504,6 @@ static void e1000e_disable_l1aspm(struct pci_dev *pdev)
* active.
*/
pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &cap);
pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
if (val & 0x2) {
dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
@@ -4054,8 +4030,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
flush_scheduled_work();
- e1000_release_manageability(adapter);
-
/* Release control of h/w to f/w. If f/w is AMT enabled, this
* would have already happened in close and is redundant. */
e1000_release_hw_control(adapter);
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index fc6fee112f1..dab3c468a76 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -121,7 +121,7 @@ s32 e1000e_phy_reset_dsp(struct e1000_hw *hw)
* @offset: register offset to be read
* @data: pointer to the read data
*
- * Reads the MDI control regsiter in the PHY at offset and stores the
+ * Reads the MDI control register in the PHY at offset and stores the
* information read to data.
**/
static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
@@ -1172,7 +1172,7 @@ s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active)
}
/**
- * e1000e_check_downshift - Checks whether a downshift in speed occured
+ * e1000e_check_downshift - Checks whether a downshift in speed occurred
* @hw: pointer to the HW structure
*
* Success returns 0, Failure returns 1
@@ -1388,8 +1388,8 @@ s32 e1000e_get_cable_length_m88(struct e1000_hw *hw)
*
* The automatic gain control (agc) normalizes the amplitude of the
* received signal, adjusting for the attenuation produced by the
- * cable. By reading the AGC registers, which reperesent the
- * cobination of course and fine gain value, the value can be put
+ * cable. By reading the AGC registers, which represent the
+ * combination of course and fine gain value, the value can be put
* into a lookup table to obtain the approximate cable length
* for each channel.
**/
@@ -1619,7 +1619,7 @@ s32 e1000e_phy_sw_reset(struct e1000_hw *hw)
* Verify the reset block is not blocking us from resetting. Acquire
* semaphore (if necessary) and read/set/write the device control reset
* bit in the PHY. Wait the appropriate delay time for the device to
- * reset and relase the semaphore (if necessary).
+ * reset and release the semaphore (if necessary).
**/
s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw)
{
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 88fb53eba71..7c4ead35cfa 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0083"
+#define DRV_VERSION "EHEA_0087"
/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
@@ -386,6 +386,13 @@ struct ehea_port_res {
#define EHEA_MAX_PORTS 16
+
+#define EHEA_NUM_PORTRES_FW_HANDLES 6 /* QP handle, SendCQ handle,
+ RecvCQ handle, EQ handle,
+ SendMR handle, RecvMR handle */
+#define EHEA_NUM_PORT_FW_HANDLES 1 /* EQ handle */
+#define EHEA_NUM_ADAPTER_FW_HANDLES 2 /* MR handle, NEQ handle */
+
struct ehea_adapter {
u64 handle;
struct of_device *ofdev;
@@ -405,6 +412,31 @@ struct ehea_mc_list {
u64 macaddr;
};
+/* kdump support */
+struct ehea_fw_handle_entry {
+ u64 adh; /* Adapter Handle */
+ u64 fwh; /* Firmware Handle */
+};
+
+struct ehea_fw_handle_array {
+ struct ehea_fw_handle_entry *arr;
+ int num_entries;
+ struct semaphore lock;
+};
+
+struct ehea_bcmc_reg_entry {
+ u64 adh; /* Adapter Handle */
+ u32 port_id; /* Logical Port Id */
+ u8 reg_type; /* Registration Type */
+ u64 macaddr;
+};
+
+struct ehea_bcmc_reg_array {
+ struct ehea_bcmc_reg_entry *arr;
+ int num_entries;
+ struct semaphore lock;
+};
+
#define EHEA_PORT_UP 1
#define EHEA_PORT_DOWN 0
#define EHEA_PHY_LINK_UP 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index c051c7e09b9..21af674b764 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -35,6 +35,7 @@
#include <linux/if_ether.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
+#include <asm/kexec.h>
#include <net/ip.h>
@@ -98,8 +99,10 @@ static int port_name_cnt;
static LIST_HEAD(adapter_list);
u64 ehea_driver_flags;
struct work_struct ehea_rereg_mr_task;
-
struct semaphore dlpar_mem_lock;
+struct ehea_fw_handle_array ehea_fw_handles;
+struct ehea_bcmc_reg_array ehea_bcmc_regs;
+
static int __devinit ehea_probe_adapter(struct of_device *dev,
const struct of_device_id *id);
@@ -132,6 +135,160 @@ void ehea_dump(void *adr, int len, char *msg)
}
}
+static void ehea_update_firmware_handles(void)
+{
+ struct ehea_fw_handle_entry *arr = NULL;
+ struct ehea_adapter *adapter;
+ int num_adapters = 0;
+ int num_ports = 0;
+ int num_portres = 0;
+ int i = 0;
+ int num_fw_handles, k, l;
+
+ /* Determine number of handles */
+ list_for_each_entry(adapter, &adapter_list, list) {
+ num_adapters++;
+
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ num_ports++;
+ num_portres += port->num_def_qps + port->num_add_tx_qps;
+ }
+ }
+
+ num_fw_handles = num_adapters * EHEA_NUM_ADAPTER_FW_HANDLES +
+ num_ports * EHEA_NUM_PORT_FW_HANDLES +
+ num_portres * EHEA_NUM_PORTRES_FW_HANDLES;
+
+ if (num_fw_handles) {
+ arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL);
+ if (!arr)
+ return; /* Keep the existing array */
+ } else
+ goto out_update;
+
+ list_for_each_entry(adapter, &adapter_list, list) {
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ for (l = 0;
+ l < port->num_def_qps + port->num_add_tx_qps;
+ l++) {
+ struct ehea_port_res *pr = &port->port_res[l];
+
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->qp->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->send_cq->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->recv_cq->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->eq->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->send_mr.handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->recv_mr.handle;
+ }
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = port->qp_eq->fw_handle;
+ }
+
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = adapter->neq->fw_handle;
+
+ if (adapter->mr.handle) {
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = adapter->mr.handle;
+ }
+ }
+
+out_update:
+ kfree(ehea_fw_handles.arr);
+ ehea_fw_handles.arr = arr;
+ ehea_fw_handles.num_entries = i;
+}
+
+static void ehea_update_bcmc_registrations(void)
+{
+ struct ehea_bcmc_reg_entry *arr = NULL;
+ struct ehea_adapter *adapter;
+ struct ehea_mc_list *mc_entry;
+ int num_registrations = 0;
+ int i = 0;
+ int k;
+
+ /* Determine number of registrations */
+ list_for_each_entry(adapter, &adapter_list, list)
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ num_registrations += 2; /* Broadcast registrations */
+
+ list_for_each_entry(mc_entry, &port->mc_list->list,list)
+ num_registrations += 2;
+ }
+
+ if (num_registrations) {
+ arr = kzalloc(num_registrations * sizeof(*arr), GFP_KERNEL);
+ if (!arr)
+ return; /* Keep the existing array */
+ } else
+ goto out_update;
+
+ list_for_each_entry(adapter, &adapter_list, list) {
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_BROADCAST |
+ EHEA_BCMC_UNTAGGED;
+ arr[i++].macaddr = port->mac_addr;
+
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_BROADCAST |
+ EHEA_BCMC_VLANID_ALL;
+ arr[i++].macaddr = port->mac_addr;
+
+ list_for_each_entry(mc_entry,
+ &port->mc_list->list, list) {
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
+ EHEA_BCMC_MULTICAST |
+ EHEA_BCMC_UNTAGGED;
+ arr[i++].macaddr = mc_entry->macaddr;
+
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
+ EHEA_BCMC_MULTICAST |
+ EHEA_BCMC_VLANID_ALL;
+ arr[i++].macaddr = mc_entry->macaddr;
+ }
+ }
+ }
+
+out_update:
+ kfree(ehea_bcmc_regs.arr);
+ ehea_bcmc_regs.arr = arr;
+ ehea_bcmc_regs.num_entries = i;
+}
+
static struct net_device_stats *ehea_get_stats(struct net_device *dev)
{
struct ehea_port *port = netdev_priv(dev);
@@ -1601,19 +1758,25 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
+ down(&ehea_bcmc_regs.lock);
+
/* Deregister old MAC in pHYP */
ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
if (ret)
- goto out_free;
+ goto out_upregs;
port->mac_addr = cb0->port_mac_addr << 16;
/* Register new MAC in pHYP */
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
if (ret)
- goto out_free;
+ goto out_upregs;
ret = 0;
+
+out_upregs:
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
out_free:
kfree(cb0);
out:
@@ -1775,9 +1938,11 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
ehea_promiscuous(dev, 0);
+ down(&ehea_bcmc_regs.lock);
+
if (dev->flags & IFF_ALLMULTI) {
ehea_allmulti(dev, 1);
- return;
+ goto out;
}
ehea_allmulti(dev, 0);
@@ -1803,6 +1968,8 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
out:
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
return;
}
@@ -2285,6 +2452,8 @@ static int ehea_up(struct net_device *dev)
if (port->state == EHEA_PORT_UP)
return 0;
+ down(&ehea_fw_handles.lock);
+
ret = ehea_port_res_setup(port, port->num_def_qps,
port->num_add_tx_qps);
if (ret) {
@@ -2321,8 +2490,17 @@ static int ehea_up(struct net_device *dev)
}
}
- ret = 0;
+ down(&ehea_bcmc_regs.lock);
+
+ ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
+ if (ret) {
+ ret = -EIO;
+ goto out_free_irqs;
+ }
+
port->state = EHEA_PORT_UP;
+
+ ret = 0;
goto out;
out_free_irqs:
@@ -2334,6 +2512,12 @@ out:
if (ret)
ehea_info("Failed starting %s. ret=%i", dev->name, ret);
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
+
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
+
return ret;
}
@@ -2382,16 +2566,27 @@ static int ehea_down(struct net_device *dev)
if (port->state == EHEA_PORT_DOWN)
return 0;
+ down(&ehea_bcmc_regs.lock);
ehea_drop_multicast_list(dev);
+ ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
+
ehea_free_interrupts(dev);
+ down(&ehea_fw_handles.lock);
+
port->state = EHEA_PORT_DOWN;
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
+
ret = ehea_clean_all_portres(port);
if (ret)
ehea_info("Failed freeing resources for %s. ret=%i",
dev->name, ret);
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
+
return ret;
}
@@ -2920,19 +3115,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
INIT_WORK(&port->reset_task, ehea_reset_port);
-
- ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
- if (ret) {
- ret = -EIO;
- goto out_unreg_port;
- }
-
ehea_set_ethtool_ops(dev);
ret = register_netdev(dev);
if (ret) {
ehea_error("register_netdev failed. ret=%d", ret);
- goto out_dereg_bc;
+ goto out_unreg_port;
}
port->lro_max_aggr = lro_max_aggr;
@@ -2949,9 +3137,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
return port;
-out_dereg_bc:
- ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
-
out_unreg_port:
ehea_unregister_port(port);
@@ -2971,7 +3156,6 @@ static void ehea_shutdown_single_port(struct ehea_port *port)
{
unregister_netdev(port->netdev);
ehea_unregister_port(port);
- ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
kfree(port->mc_list);
free_netdev(port->netdev);
port->adapter->active_ports--;
@@ -3014,7 +3198,6 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
i++;
};
-
return 0;
}
@@ -3159,6 +3342,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
ehea_error("Invalid ibmebus device probed");
return -EINVAL;
}
+ down(&ehea_fw_handles.lock);
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
@@ -3239,7 +3423,10 @@ out_kill_eq:
out_free_ad:
kfree(adapter);
+
out:
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
return ret;
}
@@ -3258,18 +3445,41 @@ static int __devexit ehea_remove(struct of_device *dev)
flush_scheduled_work();
+ down(&ehea_fw_handles.lock);
+
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
tasklet_kill(&adapter->neq_tasklet);
ehea_destroy_eq(adapter->neq);
ehea_remove_adapter_mr(adapter);
list_del(&adapter->list);
-
kfree(adapter);
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
+
return 0;
}
+void ehea_crash_handler(void)
+{
+ int i;
+
+ if (ehea_fw_handles.arr)
+ for (i = 0; i < ehea_fw_handles.num_entries; i++)
+ ehea_h_free_resource(ehea_fw_handles.arr[i].adh,
+ ehea_fw_handles.arr[i].fwh,
+ FORCE_FREE);
+
+ if (ehea_bcmc_regs.arr)
+ for (i = 0; i < ehea_bcmc_regs.num_entries; i++)
+ ehea_h_reg_dereg_bcmc(ehea_bcmc_regs.arr[i].adh,
+ ehea_bcmc_regs.arr[i].port_id,
+ ehea_bcmc_regs.arr[i].reg_type,
+ ehea_bcmc_regs.arr[i].macaddr,
+ 0, H_DEREG_BCMC);
+}
+
static int ehea_reboot_notifier(struct notifier_block *nb,
unsigned long action, void *unused)
{
@@ -3330,7 +3540,12 @@ int __init ehea_module_init(void)
INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs);
+ memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles));
+ memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs));
+
sema_init(&dlpar_mem_lock, 1);
+ sema_init(&ehea_fw_handles.lock, 1);
+ sema_init(&ehea_bcmc_regs.lock, 1);
ret = check_module_parm();
if (ret)
@@ -3340,12 +3555,18 @@ int __init ehea_module_init(void)
if (ret)
goto out;
- register_reboot_notifier(&ehea_reboot_nb);
+ ret = register_reboot_notifier(&ehea_reboot_nb);
+ if (ret)
+ ehea_info("failed registering reboot notifier");
+
+ ret = crash_shutdown_register(&ehea_crash_handler);
+ if (ret)
+ ehea_info("failed registering crash handler");
ret = ibmebus_register_driver(&ehea_driver);
if (ret) {
ehea_error("failed registering eHEA device driver on ebus");
- goto out;
+ goto out2;
}
ret = driver_create_file(&ehea_driver.driver,
@@ -3353,21 +3574,33 @@ int __init ehea_module_init(void)
if (ret) {
ehea_error("failed to register capabilities attribute, ret=%d",
ret);
- unregister_reboot_notifier(&ehea_reboot_nb);
- ibmebus_unregister_driver(&ehea_driver);
- goto out;
+ goto out3;
}
+ return ret;
+
+out3:
+ ibmebus_unregister_driver(&ehea_driver);
+out2:
+ unregister_reboot_notifier(&ehea_reboot_nb);
+ crash_shutdown_unregister(&ehea_crash_handler);
out:
return ret;
}
static void __exit ehea_module_exit(void)
{
+ int ret;
+
flush_scheduled_work();
driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
ibmebus_unregister_driver(&ehea_driver);
unregister_reboot_notifier(&ehea_reboot_nb);
+ ret = crash_shutdown_unregister(&ehea_crash_handler);
+ if (ret)
+ ehea_info("failed unregistering crash handler");
+ kfree(ehea_fw_handles.arr);
+ kfree(ehea_bcmc_regs.arr);
ehea_destroy_busmap();
}
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 0fbf1bbbaee..d7a3ea88edd 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1253,7 +1253,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
/* Setup interrupt handlers. */
for (idp = id; idp->name; idp++) {
- if (request_irq(idp->irq, idp->handler, 0, idp->name, dev) != 0)
+ if (request_irq(idp->irq, idp->handler, IRQF_DISABLED, idp->name, dev) != 0)
printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, idp->irq);
}
@@ -1382,7 +1382,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
/* Setup interrupt handlers. */
for (idp = id; idp->name; idp++) {
- if (request_irq(b+idp->irq, fec_enet_interrupt, 0, idp->name, dev) != 0)
+ if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name, dev) != 0)
printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
}
@@ -1553,7 +1553,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
/* Setup interrupt handlers. */
for (idp = id; idp->name; idp++) {
- if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0)
+ if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0)
printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
}
@@ -1680,7 +1680,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
/* Setup interrupt handlers. */
for (idp = id; idp->name; idp++) {
- if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0)
+ if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0)
printk("FEC: Could not allocate %s IRQ(%d)!\n",
idp->name, b+idp->irq);
}
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index d4843d014bc..801b4d9cd97 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -166,21 +166,24 @@
* Hardware access:
*/
-#define DEV_NEED_TIMERIRQ 0x0001 /* set the timer irq flag in the irq mask */
-#define DEV_NEED_LINKTIMER 0x0002 /* poll link settings. Relies on the timer irq */
-#define DEV_HAS_LARGEDESC 0x0004 /* device supports jumbo frames and needs packet format 2 */
-#define DEV_HAS_HIGH_DMA 0x0008 /* device supports 64bit dma */
-#define DEV_HAS_CHECKSUM 0x0010 /* device supports tx and rx checksum offloads */
-#define DEV_HAS_VLAN 0x0020 /* device supports vlan tagging and striping */
-#define DEV_HAS_MSI 0x0040 /* device supports MSI */
-#define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */
-#define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */
-#define DEV_HAS_PAUSEFRAME_TX 0x0200 /* device supports tx pause frames */
-#define DEV_HAS_STATISTICS_V1 0x0400 /* device supports hw statistics version 1 */
-#define DEV_HAS_STATISTICS_V2 0x0800 /* device supports hw statistics version 2 */
-#define DEV_HAS_TEST_EXTENDED 0x1000 /* device supports extended diagnostic test */
-#define DEV_HAS_MGMT_UNIT 0x2000 /* device supports management unit */
-#define DEV_HAS_CORRECT_MACADDR 0x4000 /* device supports correct mac address order */
+#define DEV_NEED_TIMERIRQ 0x00001 /* set the timer irq flag in the irq mask */
+#define DEV_NEED_LINKTIMER 0x00002 /* poll link settings. Relies on the timer irq */
+#define DEV_HAS_LARGEDESC 0x00004 /* device supports jumbo frames and needs packet format 2 */
+#define DEV_HAS_HIGH_DMA 0x00008 /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM 0x00010 /* device supports tx and rx checksum offloads */
+#define DEV_HAS_VLAN 0x00020 /* device supports vlan tagging and striping */
+#define DEV_HAS_MSI 0x00040 /* device supports MSI */
+#define DEV_HAS_MSI_X 0x00080 /* device supports MSI-X */
+#define DEV_HAS_POWER_CNTRL 0x00100 /* device supports power savings */
+#define DEV_HAS_STATISTICS_V1 0x00200 /* device supports hw statistics version 1 */
+#define DEV_HAS_STATISTICS_V2 0x00400 /* device supports hw statistics version 2 */
+#define DEV_HAS_TEST_EXTENDED 0x00800 /* device supports extended diagnostic test */
+#define DEV_HAS_MGMT_UNIT 0x01000 /* device supports management unit */
+#define DEV_HAS_CORRECT_MACADDR 0x02000 /* device supports correct mac address order */
+#define DEV_HAS_COLLISION_FIX 0x04000 /* device supports tx collision fix */
+#define DEV_HAS_PAUSEFRAME_TX_V1 0x08000 /* device supports tx pause frames version 1 */
+#define DEV_HAS_PAUSEFRAME_TX_V2 0x10000 /* device supports tx pause frames version 2 */
+#define DEV_HAS_PAUSEFRAME_TX_V3 0x20000 /* device supports tx pause frames version 3 */
enum {
NvRegIrqStatus = 0x000,
@@ -266,9 +269,12 @@ enum {
#define NVREG_RNDSEED_FORCE3 0x7400
NvRegTxDeferral = 0xA0,
-#define NVREG_TX_DEFERRAL_DEFAULT 0x15050f
-#define NVREG_TX_DEFERRAL_RGMII_10_100 0x16070f
-#define NVREG_TX_DEFERRAL_RGMII_1000 0x14050f
+#define NVREG_TX_DEFERRAL_DEFAULT 0x15050f
+#define NVREG_TX_DEFERRAL_RGMII_10_100 0x16070f
+#define NVREG_TX_DEFERRAL_RGMII_1000 0x14050f
+#define NVREG_TX_DEFERRAL_RGMII_STRETCH_10 0x16190f
+#define NVREG_TX_DEFERRAL_RGMII_STRETCH_100 0x16300f
+#define NVREG_TX_DEFERRAL_MII_STRETCH 0x152000
NvRegRxDeferral = 0xA4,
#define NVREG_RX_DEFERRAL_DEFAULT 0x16
NvRegMacAddrA = 0xA8,
@@ -318,8 +324,10 @@ enum {
NvRegTxRingPhysAddrHigh = 0x148,
NvRegRxRingPhysAddrHigh = 0x14C,
NvRegTxPauseFrame = 0x170,
-#define NVREG_TX_PAUSEFRAME_DISABLE 0x01ff0080
-#define NVREG_TX_PAUSEFRAME_ENABLE 0x01800010
+#define NVREG_TX_PAUSEFRAME_DISABLE 0x0fff0080
+#define NVREG_TX_PAUSEFRAME_ENABLE_V1 0x01800010
+#define NVREG_TX_PAUSEFRAME_ENABLE_V2 0x056003f0
+#define NVREG_TX_PAUSEFRAME_ENABLE_V3 0x09f00880
NvRegMIIStatus = 0x180,
#define NVREG_MIISTAT_ERROR 0x0001
#define NVREG_MIISTAT_LINKCHANGE 0x0008
@@ -2751,7 +2759,12 @@ static void nv_update_pause(struct net_device *dev, u32 pause_flags)
if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) {
u32 regmisc = readl(base + NvRegMisc1) & ~NVREG_MISC1_PAUSE_TX;
if (pause_flags & NV_PAUSEFRAME_TX_ENABLE) {
- writel(NVREG_TX_PAUSEFRAME_ENABLE, base + NvRegTxPauseFrame);
+ u32 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V1;
+ if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V2)
+ pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V2;
+ if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V3)
+ pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V3;
+ writel(pause_enable, base + NvRegTxPauseFrame);
writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1);
np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE;
} else {
@@ -2785,6 +2798,7 @@ static int nv_update_linkspeed(struct net_device *dev)
int retval = 0;
u32 control_1000, status_1000, phyreg, pause_flags, txreg;
u32 txrxFlags = 0;
+ u32 phy_exp;
/* BMSR_LSTATUS is latched, read it twice:
* we want the current value.
@@ -2912,13 +2926,25 @@ set_speed:
phyreg |= PHY_1000;
writel(phyreg, base + NvRegPhyInterface);
+ phy_exp = mii_rw(dev, np->phyaddr, MII_EXPANSION, MII_READ) & EXPANSION_NWAY; /* autoneg capable */
if (phyreg & PHY_RGMII) {
- if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_1000)
+ if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_1000) {
txreg = NVREG_TX_DEFERRAL_RGMII_1000;
- else
- txreg = NVREG_TX_DEFERRAL_RGMII_10_100;
+ } else {
+ if (!phy_exp && !np->duplex && (np->driver_data & DEV_HAS_COLLISION_FIX)) {
+ if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_10)
+ txreg = NVREG_TX_DEFERRAL_RGMII_STRETCH_10;
+ else
+ txreg = NVREG_TX_DEFERRAL_RGMII_STRETCH_100;
+ } else {
+ txreg = NVREG_TX_DEFERRAL_RGMII_10_100;
+ }
+ }
} else {
- txreg = NVREG_TX_DEFERRAL_DEFAULT;
+ if (!phy_exp && !np->duplex && (np->driver_data & DEV_HAS_COLLISION_FIX))
+ txreg = NVREG_TX_DEFERRAL_MII_STRETCH;
+ else
+ txreg = NVREG_TX_DEFERRAL_DEFAULT;
}
writel(txreg, base + NvRegTxDeferral);
@@ -5155,7 +5181,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
}
np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE | NV_PAUSEFRAME_RX_REQ | NV_PAUSEFRAME_AUTONEG;
- if (id->driver_data & DEV_HAS_PAUSEFRAME_TX) {
+ if ((id->driver_data & DEV_HAS_PAUSEFRAME_TX_V1) ||
+ (id->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) ||
+ (id->driver_data & DEV_HAS_PAUSEFRAME_TX_V3)) {
np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE | NV_PAUSEFRAME_TX_REQ;
}
@@ -5559,107 +5587,107 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{0,},
};
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 42d94edeee2..af869cf9ae7 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -946,16 +946,11 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct fs_enet_private *fep = netdev_priv(dev);
struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data;
- unsigned long flags;
- int rc;
if (!netif_running(dev))
return -EINVAL;
- spin_lock_irqsave(&fep->lock, flags);
- rc = phy_mii_ioctl(fep->phydev, mii, cmd);
- spin_unlock_irqrestore(&fep->lock, flags);
- return rc;
+ return phy_mii_ioctl(fep->phydev, mii, cmd);
}
extern int fs_mii_connect(struct net_device *dev);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 0431e9ed0fa..718cf77e345 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -130,8 +130,8 @@ static void free_skb_resources(struct gfar_private *priv);
static void gfar_set_multi(struct net_device *dev);
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
static void gfar_configure_serdes(struct net_device *dev);
-extern int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value);
-extern int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum);
+extern int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, int regnum, u16 value);
+extern int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
#ifdef CONFIG_GFAR_NAPI
static int gfar_poll(struct napi_struct *napi, int budget);
#endif
@@ -605,7 +605,7 @@ void stop_gfar(struct net_device *dev)
free_skb_resources(priv);
- dma_free_coherent(NULL,
+ dma_free_coherent(&dev->dev,
sizeof(struct txbd8)*priv->tx_ring_size
+ sizeof(struct rxbd8)*priv->rx_ring_size,
priv->tx_bd_base,
@@ -626,7 +626,7 @@ static void free_skb_resources(struct gfar_private *priv)
for (i = 0; i < priv->tx_ring_size; i++) {
if (priv->tx_skbuff[i]) {
- dma_unmap_single(NULL, txbdp->bufPtr,
+ dma_unmap_single(&priv->dev->dev, txbdp->bufPtr,
txbdp->length,
DMA_TO_DEVICE);
dev_kfree_skb_any(priv->tx_skbuff[i]);
@@ -643,7 +643,7 @@ static void free_skb_resources(struct gfar_private *priv)
if(priv->rx_skbuff != NULL) {
for (i = 0; i < priv->rx_ring_size; i++) {
if (priv->rx_skbuff[i]) {
- dma_unmap_single(NULL, rxbdp->bufPtr,
+ dma_unmap_single(&priv->dev->dev, rxbdp->bufPtr,
priv->rx_buffer_size,
DMA_FROM_DEVICE);
@@ -708,7 +708,7 @@ int startup_gfar(struct net_device *dev)
gfar_write(&regs->imask, IMASK_INIT_CLEAR);
/* Allocate memory for the buffer descriptors */
- vaddr = (unsigned long) dma_alloc_coherent(NULL,
+ vaddr = (unsigned long) dma_alloc_coherent(&dev->dev,
sizeof (struct txbd8) * priv->tx_ring_size +
sizeof (struct rxbd8) * priv->rx_ring_size,
&addr, GFP_KERNEL);
@@ -919,7 +919,7 @@ err_irq_fail:
rx_skb_fail:
free_skb_resources(priv);
tx_skb_fail:
- dma_free_coherent(NULL,
+ dma_free_coherent(&dev->dev,
sizeof(struct txbd8)*priv->tx_ring_size
+ sizeof(struct rxbd8)*priv->rx_ring_size,
priv->tx_bd_base,
@@ -1053,7 +1053,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Set buffer length and pointer */
txbdp->length = skb->len;
- txbdp->bufPtr = dma_map_single(NULL, skb->data,
+ txbdp->bufPtr = dma_map_single(&dev->dev, skb->data,
skb->len, DMA_TO_DEVICE);
/* Save the skb pointer so we can free it later */
@@ -1332,7 +1332,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
*/
skb_reserve(skb, alignamount);
- bdp->bufPtr = dma_map_single(NULL, skb->data,
+ bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
priv->rx_buffer_size, DMA_FROM_DEVICE);
bdp->length = 0;
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 6a647d95e6e..24327629bf0 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -51,7 +51,7 @@
* the local mdio pins, which may not be the same as system mdio bus, used for
* controlling the external PHYs, for example.
*/
-int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id,
+int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
int regnum, u16 value)
{
/* Set the PHY address and the register address we want to write */
@@ -77,7 +77,7 @@ int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id,
* and are always tied to the local mdio pins, which may not be the
* same as system mdio bus, used for controlling the external PHYs, for eg.
*/
-int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum)
+int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum)
{
u16 value;
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index cfcd15af501..30c9b3b0d13 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -289,7 +289,6 @@ static void ax_bump(struct mkiss *ax)
*ax->rbuff &= ~0x20;
}
}
- spin_unlock_bh(&ax->buflock);
count = ax->rcount;
@@ -297,17 +296,17 @@ static void ax_bump(struct mkiss *ax)
printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
ax->dev->name);
ax->stats.rx_dropped++;
+ spin_unlock_bh(&ax->buflock);
return;
}
- spin_lock_bh(&ax->buflock);
memcpy(skb_put(skb,count), ax->rbuff, count);
- spin_unlock_bh(&ax->buflock);
skb->protocol = ax25_type_trans(skb, ax->dev);
netif_rx(skb);
ax->dev->last_rx = jiffies;
ax->stats.rx_packets++;
ax->stats.rx_bytes += count;
+ spin_unlock_bh(&ax->buflock);
}
static void kiss_unesc(struct mkiss *ax, unsigned char s)
diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c
index 9bc1132fa78..5757788227b 100644
--- a/drivers/net/ibm_newemac/rgmii.c
+++ b/drivers/net/ibm_newemac/rgmii.c
@@ -302,7 +302,6 @@ static int __devexit rgmii_remove(struct of_device *ofdev)
static struct of_device_id rgmii_match[] =
{
{
- .type = "rgmii-interface",
.compatible = "ibm,rgmii",
},
{
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index f69721e4eaa..0447f9bcd27 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -43,7 +43,7 @@ struct igb_stats {
int stat_offset;
};
-#define IGB_STAT(m) sizeof(((struct igb_adapter *)0)->m), \
+#define IGB_STAT(m) FIELD_SIZEOF(struct igb_adapter, m), \
offsetof(struct igb_adapter, m)
static const struct igb_stats igb_gstrings_stats[] = {
{ "rx_packets", IGB_STAT(stats.gprc) },
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index d4eb8e2d872..6a1f2309209 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -439,7 +439,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
err = igb_request_msix(adapter);
if (!err) {
/* enable IAM, auto-mask,
- * DO NOT USE EIAME or IAME in legacy mode */
+ * DO NOT USE EIAM or IAM in legacy mode */
wr32(E1000_IAM, IMS_ENABLE_MASK);
goto request_done;
}
@@ -465,14 +465,9 @@ static int igb_request_irq(struct igb_adapter *adapter)
err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED,
netdev->name, netdev);
- if (err) {
+ if (err)
dev_err(&adapter->pdev->dev, "Error %d getting interrupt\n",
err);
- goto request_done;
- }
-
- /* enable IAM, auto-mask */
- wr32(E1000_IAM, IMS_ENABLE_MASK);
request_done:
return err;
@@ -606,9 +601,6 @@ static void igb_init_manageability(struct igb_adapter *adapter)
u32 manc2h = rd32(E1000_MANC2H);
u32 manc = rd32(E1000_MANC);
- /* disable hardware interception of ARP */
- manc &= ~(E1000_MANC_ARP_EN);
-
/* enable receiving management packets to the host */
/* this will probably generate destination unreachable messages
* from the host OS, but the packets will be handled on SMBUS */
@@ -623,25 +615,6 @@ static void igb_init_manageability(struct igb_adapter *adapter)
}
}
-static void igb_release_manageability(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- if (adapter->en_mng_pt) {
- u32 manc = rd32(E1000_MANC);
-
- /* re-enable hardware interception of ARP */
- manc |= E1000_MANC_ARP_EN;
- manc &= ~E1000_MANC_EN_MNG2HOST;
-
- /* don't explicitly have to mess with MANC2H since
- * MANC has an enable disable that gates MANC2H */
-
- /* XXX stop the hardware watchdog ? */
- wr32(E1000_MANC, manc);
- }
-}
-
/**
* igb_configure - configure the hardware for RX and TX
* @adapter: private board structure
@@ -843,8 +816,8 @@ void igb_reset(struct igb_adapter *adapter)
wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
igb_reset_adaptive(&adapter->hw);
- adapter->hw.phy.ops.get_phy_info(&adapter->hw);
- igb_release_manageability(adapter);
+ if (adapter->hw.phy.ops.get_phy_info)
+ adapter->hw.phy.ops.get_phy_info(&adapter->hw);
}
/**
@@ -1178,9 +1151,6 @@ static void __devexit igb_remove(struct pci_dev *pdev)
flush_scheduled_work();
-
- igb_release_manageability(adapter);
-
/* Release control of h/w to f/w. If f/w is AMT enabled, this
* would have already happened in close and is redundant. */
igb_release_hw_control(adapter);
@@ -2083,7 +2053,8 @@ static void igb_set_multi(struct net_device *netdev)
static void igb_update_phy_info(unsigned long data)
{
struct igb_adapter *adapter = (struct igb_adapter *) data;
- adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+ if (adapter->hw.phy.ops.get_phy_info)
+ adapter->hw.phy.ops.get_phy_info(&adapter->hw);
}
/**
@@ -3955,8 +3926,6 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
pci_enable_wake(pdev, PCI_D3cold, 0);
}
- igb_release_manageability(adapter);
-
/* make sure adapter isn't asleep if manageability is enabled */
if (adapter->en_mng_pt) {
pci_enable_wake(pdev, PCI_D3hot, 1);
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index a267dd86252..75f3a68ee35 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -49,7 +49,7 @@ struct ixgb_stats {
int stat_offset;
};
-#define IXGB_STAT(m) sizeof(((struct ixgb_adapter *)0)->m), \
+#define IXGB_STAT(m) FIELD_SIZEOF(struct ixgb_adapter, m), \
offsetof(struct ixgb_adapter, m)
static struct ixgb_stats ixgb_gstrings_stats[] = {
{"rx_packets", IXGB_STAT(net_stats.rx_packets)},
@@ -67,6 +67,7 @@ static struct ixgb_stats ixgb_gstrings_stats[] = {
{"rx_over_errors", IXGB_STAT(net_stats.rx_over_errors)},
{"rx_crc_errors", IXGB_STAT(net_stats.rx_crc_errors)},
{"rx_frame_errors", IXGB_STAT(net_stats.rx_frame_errors)},
+ {"rx_no_buffer_count", IXGB_STAT(stats.rnbc)},
{"rx_fifo_errors", IXGB_STAT(net_stats.rx_fifo_errors)},
{"rx_missed_errors", IXGB_STAT(net_stats.rx_missed_errors)},
{"tx_aborted_errors", IXGB_STAT(net_stats.tx_aborted_errors)},
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index ead49e54f31..23d0a4afe0e 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -220,7 +220,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
tx_ring->stats.bytes += tx_buffer_info->length;
if (cleaned) {
struct sk_buff *skb = tx_buffer_info->skb;
-#ifdef NETIF_F_TSO
unsigned int segs, bytecount;
segs = skb_shinfo(skb)->gso_segs ?: 1;
/* multiply data chunks by size of headers */
@@ -228,10 +227,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
skb->len;
total_tx_packets += segs;
total_tx_bytes += bytecount;
-#else
- total_tx_packets++;
- total_tx_bytes += skb->len;
-#endif
}
ixgbe_unmap_and_free_tx_resource(adapter,
tx_buffer_info);
@@ -1942,6 +1937,10 @@ static int ixgbe_open(struct net_device *netdev)
int err;
u32 num_rx_queues = adapter->num_rx_queues;
+ /* disallow open during test */
+ if (test_bit(__IXGBE_TESTING, &adapter->state))
+ return -EBUSY;
+
try_intr_reinit:
/* allocate transmit descriptors */
err = ixgbe_setup_all_tx_resources(adapter);
@@ -2278,11 +2277,29 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
IXGBE_ADVTXD_DTYP_CTXT);
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- if (skb->protocol == htons(ETH_P_IP))
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
+ if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+ type_tucmd_mlhl |=
+ IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ break;
+
+ case __constant_htons(ETH_P_IPV6):
+ /* XXX what about other V6 headers?? */
+ if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
+ type_tucmd_mlhl |=
+ IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ break;
- if (skb->sk->sk_protocol == IPPROTO_TCP)
- type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ default:
+ if (unlikely(net_ratelimit())) {
+ DPRINTK(PROBE, WARNING,
+ "partial checksum but proto=%x!\n",
+ skb->protocol);
+ }
+ break;
+ }
}
context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
@@ -2778,6 +2795,14 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->mac.type, hw->phy.type,
(part_num >> 8), (part_num & 0xff));
+ if (link_width <= IXGBE_PCI_LINK_WIDTH_4) {
+ dev_warn(&pdev->dev, "PCI-Express bandwidth available for "
+ "this card is not sufficient for optimal "
+ "performance.\n");
+ dev_warn(&pdev->dev, "For optimal performance a x8 "
+ "PCI-Express slot is required.\n");
+ }
+
/* reset the hardware with the new settings */
ixgbe_start_hw(hw);
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 81bf005ff28..1d210ed4613 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -148,7 +148,7 @@ static void macb_handle_link_change(struct net_device *dev)
if (phydev->duplex)
reg |= MACB_BIT(FD);
- if (phydev->speed)
+ if (phydev->speed == SPEED_100)
reg |= MACB_BIT(SPD);
macb_writel(bp, NCFGR, reg);
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 31e047dd7bb..501e451be91 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -309,8 +309,8 @@ static ssize_t show_local_mac(struct netconsole_target *nt, char *buf)
struct net_device *dev = nt->np.dev;
DECLARE_MAC_BUF(mac);
- return snprintf(buf, PAGE_SIZE, "%s\n",
- print_mac(mac, dev->dev_addr));
+ return snprintf(buf, PAGE_SIZE, "%s\n", dev ?
+ print_mac(mac, dev->dev_addr) : "ff:ff:ff:ff:ff:ff");
}
static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf)
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index 6b3384a24f0..26aa8fe1fb2 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -33,20 +33,20 @@
* I have also done a look in the following sources: (mail me if you need them)
* crynwr-packet-driver by Russ Nelson
* Garret A. Wollman's (fourth) i82586-driver for BSD
- * (before getting an i82596 (yes 596 not 586) manual, the existing drivers helped
- * me a lot to understand this tricky chip.)
+ * (before getting an i82596 (yes 596 not 586) manual, the existing drivers
+ * helped me a lot to understand this tricky chip.)
*
* Known Problems:
* The internal sysbus seems to be slow. So we often lose packets because of
* overruns while receiving from a fast remote host.
- * This can slow down TCP connections. Maybe the newer ni5210 cards are better.
- * my experience is, that if a machine sends with more than about 500-600K/s
- * the fifo/sysbus overflows.
+ * This can slow down TCP connections. Maybe the newer ni5210 cards are
+ * better. My experience is, that if a machine sends with more than about
+ * 500-600K/s the fifo/sysbus overflows.
*
* IMPORTANT NOTE:
* On fast networks, it's a (very) good idea to have 16K shared memory. With
- * 8K, we can store only 4 receive frames, so it can (easily) happen that a remote
- * machine 'overruns' our system.
+ * 8K, we can store only 4 receive frames, so it can (easily) happen that a
+ * remote machine 'overruns' our system.
*
* Known i82586/card problems (I'm sure, there are many more!):
* Running the NOP-mode, the i82586 sometimes seems to forget to report
@@ -60,7 +60,8 @@
*
* results from ftp performance tests with Linux 1.2.5
* send and receive about 350-400 KByte/s (peak up to 460 kbytes/s)
- * sending in NOP-mode: peak performance up to 530K/s (but better don't run this mode)
+ * sending in NOP-mode: peak performance up to 530K/s (but better don't
+ * run this mode)
*/
/*
@@ -94,7 +95,8 @@
*
* 26.March.94: patches for Linux 1.0 and iomem-auto-probe (MH)
*
- * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff, too (MH)
+ * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff,
+ * too (MH)
*
* < 30.Sep.93: first versions
*/
@@ -102,7 +104,7 @@
static int debuglevel; /* debug-printk 0: off 1: a few 2: more */
static int automatic_resume; /* experimental .. better should be zero */
static int rfdadd; /* rfdadd=1 may be better for 8K MEM cards */
-static int fifo=0x8; /* don't change */
+static int fifo = 0x8; /* don't change */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -127,14 +129,15 @@ static int fifo=0x8; /* don't change */
#define DEBUG /* debug on */
#define SYSBUSVAL 1 /* 8 Bit */
-#define ni_attn586() {outb(0,dev->base_addr+NI52_ATTENTION);}
-#define ni_reset586() {outb(0,dev->base_addr+NI52_RESET);}
-#define ni_disint() {outb(0,dev->base_addr+NI52_INTDIS);}
-#define ni_enaint() {outb(0,dev->base_addr+NI52_INTENA);}
+#define ni_attn586() { outb(0, dev->base_addr + NI52_ATTENTION); }
+#define ni_reset586() { outb(0, dev->base_addr + NI52_RESET); }
+#define ni_disint() { outb(0, dev->base_addr + NI52_INTDIS); }
+#define ni_enaint() { outb(0, dev->base_addr + NI52_INTENA); }
-#define make32(ptr16) (p->memtop + (short) (ptr16) )
-#define make24(ptr32) ( ((char *) (ptr32)) - p->base)
-#define make16(ptr32) ((unsigned short) ((unsigned long)(ptr32) - (unsigned long) p->memtop ))
+#define make32(ptr16) (p->memtop + (short) (ptr16))
+#define make24(ptr32) ((unsigned long)(ptr32)) - p->base
+#define make16(ptr32) ((unsigned short) ((unsigned long)(ptr32)\
+ - (unsigned long) p->memtop))
/******************* how to calculate the buffers *****************************
@@ -159,96 +162,112 @@ sizeof(nop_cmd) = 8;
/**************************************************************************/
-/* different DELAYs */
-#define DELAY(x) mdelay(32 * x);
-#define DELAY_16(); { udelay(16); }
-#define DELAY_18(); { udelay(4); }
-
-/* wait for command with timeout: */
-#define WAIT_4_SCB_CMD() \
-{ int i; \
- for(i=0;i<16384;i++) { \
- if(!p->scb->cmd_cuc) break; \
- DELAY_18(); \
- if(i == 16383) { \
- printk("%s: scb_cmd timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_cuc,p->scb->cus); \
- if(!p->reseted) { p->reseted = 1; ni_reset586(); } } } }
-
-#define WAIT_4_SCB_CMD_RUC() { int i; \
- for(i=0;i<16384;i++) { \
- if(!p->scb->cmd_ruc) break; \
- DELAY_18(); \
- if(i == 16383) { \
- printk("%s: scb_cmd (ruc) timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_ruc,p->scb->rus); \
- if(!p->reseted) { p->reseted = 1; ni_reset586(); } } } }
-
-#define WAIT_4_STAT_COMPL(addr) { int i; \
- for(i=0;i<32767;i++) { \
- if((addr)->cmd_status & STAT_COMPL) break; \
- DELAY_16(); DELAY_16(); } }
#define NI52_TOTAL_SIZE 16
#define NI52_ADDR0 0x02
#define NI52_ADDR1 0x07
#define NI52_ADDR2 0x01
-static int ni52_probe1(struct net_device *dev,int ioaddr);
-static irqreturn_t ni52_interrupt(int irq,void *dev_id);
+static int ni52_probe1(struct net_device *dev, int ioaddr);
+static irqreturn_t ni52_interrupt(int irq, void *dev_id);
static int ni52_open(struct net_device *dev);
static int ni52_close(struct net_device *dev);
-static int ni52_send_packet(struct sk_buff *,struct net_device *);
+static int ni52_send_packet(struct sk_buff *, struct net_device *);
static struct net_device_stats *ni52_get_stats(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static void ni52_timeout(struct net_device *dev);
-#if 0
-static void ni52_dump(struct net_device *,void *);
-#endif
/* helper-functions */
static int init586(struct net_device *dev);
-static int check586(struct net_device *dev,char *where,unsigned size);
+static int check586(struct net_device *dev, char *where, unsigned size);
static void alloc586(struct net_device *dev);
static void startrecv586(struct net_device *dev);
-static void *alloc_rfa(struct net_device *dev,void *ptr);
+static void *alloc_rfa(struct net_device *dev, void *ptr);
static void ni52_rcv_int(struct net_device *dev);
static void ni52_xmt_int(struct net_device *dev);
static void ni52_rnr_int(struct net_device *dev);
-struct priv
-{
+struct priv {
struct net_device_stats stats;
unsigned long base;
char *memtop;
- long int lock;
- int reseted;
- volatile struct rfd_struct *rfd_last,*rfd_top,*rfd_first;
- volatile struct scp_struct *scp; /* volatile is important */
- volatile struct iscp_struct *iscp; /* volatile is important */
- volatile struct scb_struct *scb; /* volatile is important */
- volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
+ spinlock_t spinlock;
+ int reset;
+ struct rfd_struct *rfd_last, *rfd_top, *rfd_first;
+ struct scp_struct *scp;
+ struct iscp_struct *iscp;
+ struct scb_struct *scb;
+ struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
#if (NUM_XMIT_BUFFS == 1)
- volatile struct transmit_cmd_struct *xmit_cmds[2];
- volatile struct nop_cmd_struct *nop_cmds[2];
+ struct transmit_cmd_struct *xmit_cmds[2];
+ struct nop_cmd_struct *nop_cmds[2];
#else
- volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
- volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
+ struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
+ struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
#endif
- volatile int nop_point,num_recv_buffs;
- volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
- volatile int xmit_count,xmit_last;
+ int nop_point, num_recv_buffs;
+ char *xmit_cbuffs[NUM_XMIT_BUFFS];
+ int xmit_count, xmit_last;
};
+/* wait for command with timeout: */
+static void wait_for_scb_cmd(struct net_device *dev)
+{
+ struct priv *p = dev->priv;
+ int i;
+ for (i = 0; i < 16384; i++) {
+ if (readb(&p->scb->cmd_cuc) == 0)
+ break;
+ udelay(4);
+ if (i == 16383) {
+ printk(KERN_ERR "%s: scb_cmd timed out: %04x,%04x .. disabling i82586!!\n",
+ dev->name, readb(&p->scb->cmd_cuc), readb(&p->scb->cus));
+ if (!p->reset) {
+ p->reset = 1;
+ ni_reset586();
+ }
+ }
+ }
+}
+
+static void wait_for_scb_cmd_ruc(struct net_device *dev)
+{
+ struct priv *p = dev->priv;
+ int i;
+ for (i = 0; i < 16384; i++) {
+ if (readb(&p->scb->cmd_ruc) == 0)
+ break;
+ udelay(4);
+ if (i == 16383) {
+ printk(KERN_ERR "%s: scb_cmd (ruc) timed out: %04x,%04x .. disabling i82586!!\n",
+ dev->name, p->scb->cmd_ruc, p->scb->rus);
+ if (!p->reset) {
+ p->reset = 1;
+ ni_reset586();
+ }
+ }
+ }
+}
+
+static void wait_for_stat_compl(void *p)
+{
+ struct nop_cmd_struct *addr = p;
+ int i;
+ for (i = 0; i < 32767; i++) {
+ if (readw(&((addr)->cmd_status)) & STAT_COMPL)
+ break;
+ udelay(32);
+ }
+}
+
/**********************************************
* close device
*/
static int ni52_close(struct net_device *dev)
{
free_irq(dev->irq, dev);
-
ni_reset586(); /* the hard way to stop the receiver */
-
netif_stop_queue(dev);
-
return 0;
}
@@ -265,55 +284,53 @@ static int ni52_open(struct net_device *dev)
startrecv586(dev);
ni_enaint();
- ret = request_irq(dev->irq, &ni52_interrupt,0,dev->name,dev);
- if (ret)
- {
+ ret = request_irq(dev->irq, &ni52_interrupt, 0, dev->name, dev);
+ if (ret) {
ni_reset586();
return ret;
}
-
netif_start_queue(dev);
-
return 0; /* most done by init */
}
/**********************************************
* Check to see if there's an 82586 out there.
*/
-static int check586(struct net_device *dev,char *where,unsigned size)
+static int check586(struct net_device *dev, char *where, unsigned size)
{
struct priv pb;
struct priv *p = /* (struct priv *) dev->priv*/ &pb;
char *iscp_addrs[2];
int i;
- p->base = (unsigned long) isa_bus_to_virt((unsigned long)where) + size - 0x01000000;
+ p->base = (unsigned long) isa_bus_to_virt((unsigned long)where)
+ + size - 0x01000000;
p->memtop = isa_bus_to_virt((unsigned long)where) + size;
p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
- memset((char *)p->scp,0, sizeof(struct scp_struct));
- for(i=0;i<sizeof(struct scp_struct);i++) /* memory was writeable? */
- if(((char *)p->scp)[i])
+ memset_io((char *)p->scp, 0, sizeof(struct scp_struct));
+ for (i = 0; i < sizeof(struct scp_struct); i++)
+ /* memory was writeable? */
+ if (readb((char *)p->scp + i))
return 0;
- p->scp->sysbus = SYSBUSVAL; /* 1 = 8Bit-Bus, 0 = 16 Bit */
- if(p->scp->sysbus != SYSBUSVAL)
+ writeb(SYSBUSVAL, &p->scp->sysbus); /* 1 = 8Bit-Bus, 0 = 16 Bit */
+ if (readb(&p->scp->sysbus) != SYSBUSVAL)
return 0;
iscp_addrs[0] = isa_bus_to_virt((unsigned long)where);
- iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct);
+ iscp_addrs[1] = (char *) p->scp - sizeof(struct iscp_struct);
- for(i=0;i<2;i++)
- {
+ for (i = 0; i < 2; i++) {
p->iscp = (struct iscp_struct *) iscp_addrs[i];
- memset((char *)p->iscp,0, sizeof(struct iscp_struct));
+ memset_io((char *)p->iscp, 0, sizeof(struct iscp_struct));
- p->scp->iscp = make24(p->iscp);
- p->iscp->busy = 1;
+ writel(make24(p->iscp), &p->scp->iscp);
+ writeb(1, &p->iscp->busy);
ni_reset586();
ni_attn586();
- DELAY(1); /* wait a while... */
-
- if(p->iscp->busy) /* i82586 clears 'busy' after successful init */
+ mdelay(32); /* wait a while... */
+ /* i82586 clears 'busy' after successful init */
+ if (readb(&p->iscp->busy))
return 0;
}
return 1;
@@ -327,36 +344,39 @@ static void alloc586(struct net_device *dev)
struct priv *p = (struct priv *) dev->priv;
ni_reset586();
- DELAY(1);
+ mdelay(32);
+
+ spin_lock_init(&p->spinlock);
p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS);
p->scb = (struct scb_struct *) isa_bus_to_virt(dev->mem_start);
- p->iscp = (struct iscp_struct *) ((char *)p->scp - sizeof(struct iscp_struct));
+ p->iscp = (struct iscp_struct *)
+ ((char *)p->scp - sizeof(struct iscp_struct));
- memset((char *) p->iscp,0,sizeof(struct iscp_struct));
- memset((char *) p->scp ,0,sizeof(struct scp_struct));
+ memset_io(p->iscp, 0, sizeof(struct iscp_struct));
+ memset_io(p->scp , 0, sizeof(struct scp_struct));
- p->scp->iscp = make24(p->iscp);
- p->scp->sysbus = SYSBUSVAL;
- p->iscp->scb_offset = make16(p->scb);
+ writel(make24(p->iscp), &p->scp->iscp);
+ writeb(SYSBUSVAL, &p->scp->sysbus);
+ writew(make16(p->scb), &p->iscp->scb_offset);
- p->iscp->busy = 1;
+ writeb(1, &p->iscp->busy);
ni_reset586();
ni_attn586();
- DELAY(1);
+ mdelay(32);
- if(p->iscp->busy)
- printk("%s: Init-Problems (alloc).\n",dev->name);
+ if (readb(&p->iscp->busy))
+ printk(KERN_ERR "%s: Init-Problems (alloc).\n", dev->name);
- p->reseted = 0;
+ p->reset = 0;
- memset((char *)p->scb,0,sizeof(struct scb_struct));
+ memset_io((char *)p->scb, 0, sizeof(struct scb_struct));
}
/* set: io,irq,memstart,memend or set it when calling insmod */
-static int irq=9;
-static int io=0x300;
+static int irq = 9;
+static int io = 0x300;
static long memstart; /* e.g 0xd0000 */
static long memend; /* e.g 0xd4000 */
@@ -413,7 +433,7 @@ out:
return ERR_PTR(err);
}
-static int __init ni52_probe1(struct net_device *dev,int ioaddr)
+static int __init ni52_probe1(struct net_device *dev, int ioaddr)
{
int i, size, retval;
@@ -425,90 +445,96 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr)
if (!request_region(ioaddr, NI52_TOTAL_SIZE, DRV_NAME))
return -EBUSY;
- if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
+ if (!(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
!(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2)) {
retval = -ENODEV;
goto out;
}
- for(i=0;i<ETH_ALEN;i++)
+ for (i = 0; i < ETH_ALEN; i++)
dev->dev_addr[i] = inb(dev->base_addr+i);
- if(dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1
+ if (dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1
|| dev->dev_addr[2] != NI52_ADDR2) {
retval = -ENODEV;
goto out;
}
- printk(KERN_INFO "%s: NI5210 found at %#3lx, ",dev->name,dev->base_addr);
+ printk(KERN_INFO "%s: NI5210 found at %#3lx, ",
+ dev->name, dev->base_addr);
/*
* check (or search) IO-Memory, 8K and 16K
*/
#ifdef MODULE
size = dev->mem_end - dev->mem_start;
- if(size != 0x2000 && size != 0x4000) {
- printk("\n%s: Illegal memory size %d. Allowed is 0x2000 or 0x4000 bytes.\n",dev->name,size);
+ if (size != 0x2000 && size != 0x4000) {
+ printk("\n");
+ printk(KERN_ERR "%s: Invalid memory size %d. Allowed is 0x2000 or 0x4000 bytes.\n", dev->name, size);
retval = -ENODEV;
goto out;
}
- if(!check586(dev,(char *) dev->mem_start,size)) {
- printk("?memcheck, Can't find memory at 0x%lx with size %d!\n",dev->mem_start,size);
+ if (!check586(dev, (char *)dev->mem_start, size)) {
+ printk(KERN_ERR "?memcheck, Can't find memory at 0x%lx with size %d!\n", dev->mem_start, size);
retval = -ENODEV;
goto out;
}
#else
- if(dev->mem_start != 0) /* no auto-mem-probe */
- {
+ if (dev->mem_start != 0) {
+ /* no auto-mem-probe */
size = 0x4000; /* check for 16K mem */
- if(!check586(dev,(char *) dev->mem_start,size)) {
+ if (!check586(dev, (char *) dev->mem_start, size)) {
size = 0x2000; /* check for 8K mem */
- if(!check586(dev,(char *) dev->mem_start,size)) {
- printk("?memprobe, Can't find memory at 0x%lx!\n",dev->mem_start);
+ if (!check586(dev, (char *)dev->mem_start, size)) {
+ printk(KERN_ERR "?memprobe, Can't find memory at 0x%lx!\n", dev->mem_start);
retval = -ENODEV;
goto out;
}
}
- }
- else
- {
- static long memaddrs[] = { 0xc8000,0xca000,0xcc000,0xce000,0xd0000,0xd2000,
- 0xd4000,0xd6000,0xd8000,0xda000,0xdc000, 0 };
- for(i=0;;i++)
- {
- if(!memaddrs[i]) {
- printk("?memprobe, Can't find io-memory!\n");
+ } else {
+ static const unsigned long memaddrs[] = {
+ 0xc8000, 0xca000, 0xcc000, 0xce000, 0xd0000, 0xd2000,
+ 0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0
+ };
+ for (i = 0;; i++) {
+ if (!memaddrs[i]) {
+ printk(KERN_ERR "?memprobe, Can't find io-memory!\n");
retval = -ENODEV;
goto out;
}
dev->mem_start = memaddrs[i];
size = 0x2000; /* check for 8K mem */
- if(check586(dev,(char *)dev->mem_start,size)) /* 8K-check */
+ if (check586(dev, (char *)dev->mem_start, size))
+ /* 8K-check */
break;
size = 0x4000; /* check for 16K mem */
- if(check586(dev,(char *)dev->mem_start,size)) /* 16K-check */
+ if (check586(dev, (char *)dev->mem_start, size))
+ /* 16K-check */
break;
}
}
- dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
+ /* set mem_end showed by 'ifconfig' */
+ dev->mem_end = dev->mem_start + size;
#endif
- memset((char *) dev->priv,0,sizeof(struct priv));
+ memset((char *)dev->priv, 0, sizeof(struct priv));
- ((struct priv *) (dev->priv))->memtop = isa_bus_to_virt(dev->mem_start) + size;
- ((struct priv *) (dev->priv))->base = (unsigned long) isa_bus_to_virt(dev->mem_start) + size - 0x01000000;
+ ((struct priv *)(dev->priv))->memtop =
+ isa_bus_to_virt(dev->mem_start) + size;
+ ((struct priv *)(dev->priv))->base = (unsigned long)
+ isa_bus_to_virt(dev->mem_start) + size - 0x01000000;
alloc586(dev);
/* set number of receive-buffs according to memsize */
- if(size == 0x2000)
+ if (size == 0x2000)
((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_8;
else
((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16;
- printk("Memaddr: 0x%lx, Memsize: %d, ",dev->mem_start,size);
+ printk(KERN_DEBUG "Memaddr: 0x%lx, Memsize: %d, ",
+ dev->mem_start, size);
- if(dev->irq < 2)
- {
+ if (dev->irq < 2) {
unsigned long irq_mask;
irq_mask = probe_irq_on();
@@ -517,18 +543,16 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr)
mdelay(20);
dev->irq = probe_irq_off(irq_mask);
- if(!dev->irq)
- {
+ if (!dev->irq) {
printk("?autoirq, Failed to detect IRQ line!\n");
retval = -EAGAIN;
goto out;
}
- printk("IRQ %d (autodetected).\n",dev->irq);
- }
- else {
- if(dev->irq == 2)
+ printk("IRQ %d (autodetected).\n", dev->irq);
+ } else {
+ if (dev->irq == 2)
dev->irq = 9;
- printk("IRQ %d (assigned and not checked!).\n",dev->irq);
+ printk("IRQ %d (assigned and not checked!).\n", dev->irq);
}
dev->open = ni52_open;
@@ -555,56 +579,58 @@ out:
static int init586(struct net_device *dev)
{
void *ptr;
- int i,result=0;
- struct priv *p = (struct priv *) dev->priv;
- volatile struct configure_cmd_struct *cfg_cmd;
- volatile struct iasetup_cmd_struct *ias_cmd;
- volatile struct tdr_cmd_struct *tdr_cmd;
- volatile struct mcsetup_cmd_struct *mc_cmd;
- struct dev_mc_list *dmi=dev->mc_list;
- int num_addrs=dev->mc_count;
+ int i, result = 0;
+ struct priv *p = (struct priv *)dev->priv;
+ struct configure_cmd_struct *cfg_cmd;
+ struct iasetup_cmd_struct *ias_cmd;
+ struct tdr_cmd_struct *tdr_cmd;
+ struct mcsetup_cmd_struct *mc_cmd;
+ struct dev_mc_list *dmi = dev->mc_list;
+ int num_addrs = dev->mc_count;
ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct));
cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */
- cfg_cmd->cmd_status = 0;
- cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST;
- cfg_cmd->cmd_link = 0xffff;
-
- cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */
- cfg_cmd->fifo = fifo; /* fifo-limit (8=tx:32/rx:64) */
- cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */
- cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */
- cfg_cmd->priority = 0x00;
- cfg_cmd->ifs = 0x60;
- cfg_cmd->time_low = 0x00;
- cfg_cmd->time_high = 0xf2;
- cfg_cmd->promisc = 0;
- if(dev->flags & IFF_ALLMULTI) {
+ writew(0, &cfg_cmd->cmd_status);
+ writew(CMD_CONFIGURE | CMD_LAST, &cfg_cmd->cmd_cmd);
+ writew(0xFFFF, &cfg_cmd->cmd_link);
+
+ /* number of cfg bytes */
+ writeb(0x0a, &cfg_cmd->byte_cnt);
+ /* fifo-limit (8=tx:32/rx:64) */
+ writeb(fifo, &cfg_cmd->fifo);
+ /* hold or discard bad recv frames (bit 7) */
+ writeb(0x40, &cfg_cmd->sav_bf);
+ /* addr_len |!src_insert |pre-len |loopback */
+ writeb(0x2e, &cfg_cmd->adr_len);
+ writeb(0x00, &cfg_cmd->priority);
+ writeb(0x60, &cfg_cmd->ifs);;
+ writeb(0x00, &cfg_cmd->time_low);
+ writeb(0xf2, &cfg_cmd->time_high);
+ writeb(0x00, &cfg_cmd->promisc);;
+ if (dev->flags & IFF_ALLMULTI) {
int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
- if(num_addrs > len) {
- printk("%s: switching to promisc. mode\n",dev->name);
- dev->flags|=IFF_PROMISC;
+ if (num_addrs > len) {
+ printk(KERN_ERR "%s: switching to promisc. mode\n",
+ dev->name);
+ dev->flags |= IFF_PROMISC;
}
}
- if(dev->flags&IFF_PROMISC)
- {
- cfg_cmd->promisc=1;
- dev->flags|=IFF_PROMISC;
- }
- cfg_cmd->carr_coll = 0x00;
+ if (dev->flags & IFF_PROMISC)
+ writeb(0x01, &cfg_cmd->promisc);
+ writeb(0x00, &cfg_cmd->carr_coll);
+ writew(make16(cfg_cmd), &p->scb->cbl_offset);
+ writew(0, &p->scb->cmd_ruc);
- p->scb->cbl_offset = make16(cfg_cmd);
- p->scb->cmd_ruc = 0;
-
- p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
+ writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
ni_attn586();
- WAIT_4_STAT_COMPL(cfg_cmd);
+ wait_for_stat_compl(cfg_cmd);
- if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK))
- {
- printk("%s: configure command failed: %x\n",dev->name,cfg_cmd->cmd_status);
+ if ((readw(&cfg_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) !=
+ (STAT_COMPL|STAT_OK)) {
+ printk(KERN_ERR "%s: configure command failed: %x\n",
+ dev->name, readw(&cfg_cmd->cmd_status));
return 1;
}
@@ -614,21 +640,22 @@ static int init586(struct net_device *dev)
ias_cmd = (struct iasetup_cmd_struct *)ptr;
- ias_cmd->cmd_status = 0;
- ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST;
- ias_cmd->cmd_link = 0xffff;
+ writew(0, &ias_cmd->cmd_status);
+ writew(CMD_IASETUP | CMD_LAST, &ias_cmd->cmd_cmd);
+ writew(0xffff, &ias_cmd->cmd_link);
- memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN);
+ memcpy_toio((char *)&ias_cmd->iaddr, (char *)dev->dev_addr, ETH_ALEN);
- p->scb->cbl_offset = make16(ias_cmd);
+ writew(make16(ias_cmd), &p->scb->cbl_offset);
- p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
+ writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
ni_attn586();
- WAIT_4_STAT_COMPL(ias_cmd);
+ wait_for_stat_compl(ias_cmd);
- if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
- printk("%s (ni52): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status);
+ if ((readw(&ias_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) !=
+ (STAT_OK|STAT_COMPL)) {
+ printk(KERN_ERR "%s (ni52): individual address setup command failed: %04x\n", dev->name, readw(&ias_cmd->cmd_status));
return 1;
}
@@ -638,117 +665,119 @@ static int init586(struct net_device *dev)
tdr_cmd = (struct tdr_cmd_struct *)ptr;
- tdr_cmd->cmd_status = 0;
- tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST;
- tdr_cmd->cmd_link = 0xffff;
- tdr_cmd->status = 0;
+ writew(0, &tdr_cmd->cmd_status);
+ writew(CMD_TDR | CMD_LAST, &tdr_cmd->cmd_cmd);
+ writew(0xffff, &tdr_cmd->cmd_link);
+ writew(0, &tdr_cmd->status);
- p->scb->cbl_offset = make16(tdr_cmd);
- p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
+ writew(make16(tdr_cmd), &p->scb->cbl_offset);
+ writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
ni_attn586();
- WAIT_4_STAT_COMPL(tdr_cmd);
-
- if(!(tdr_cmd->cmd_status & STAT_COMPL))
- {
- printk("%s: Problems while running the TDR.\n",dev->name);
- }
- else
- {
- DELAY_16(); /* wait for result */
- result = tdr_cmd->status;
+ wait_for_stat_compl(tdr_cmd);
- p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
+ if (!(readw(&tdr_cmd->cmd_status) & STAT_COMPL))
+ printk(KERN_ERR "%s: Problems while running the TDR.\n",
+ dev->name);
+ else {
+ udelay(16);
+ result = readw(&tdr_cmd->status);
+ writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc);
ni_attn586(); /* ack the interrupts */
- if(result & TDR_LNK_OK)
+ if (result & TDR_LNK_OK)
;
- else if(result & TDR_XCVR_PRB)
- printk("%s: TDR: Transceiver problem. Check the cable(s)!\n",dev->name);
- else if(result & TDR_ET_OPN)
- printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
- else if(result & TDR_ET_SRT)
- {
- if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
- printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
- }
- else
- printk("%s: TDR: Unknown status %04x\n",dev->name,result);
+ else if (result & TDR_XCVR_PRB)
+ printk(KERN_ERR "%s: TDR: Transceiver problem. Check the cable(s)!\n",
+ dev->name);
+ else if (result & TDR_ET_OPN)
+ printk(KERN_ERR "%s: TDR: No correct termination %d clocks away.\n",
+ dev->name, result & TDR_TIMEMASK);
+ else if (result & TDR_ET_SRT) {
+ /* time == 0 -> strange :-) */
+ if (result & TDR_TIMEMASK)
+ printk(KERN_ERR "%s: TDR: Detected a short circuit %d clocks away.\n",
+ dev->name, result & TDR_TIMEMASK);
+ } else
+ printk(KERN_ERR "%s: TDR: Unknown status %04x\n",
+ dev->name, result);
}
/*
* Multicast setup
*/
- if(num_addrs && !(dev->flags & IFF_PROMISC) )
- {
+ if (num_addrs && !(dev->flags & IFF_PROMISC)) {
mc_cmd = (struct mcsetup_cmd_struct *) ptr;
- mc_cmd->cmd_status = 0;
- mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
- mc_cmd->cmd_link = 0xffff;
- mc_cmd->mc_cnt = num_addrs * 6;
+ writew(0, &mc_cmd->cmd_status);
+ writew(CMD_MCSETUP | CMD_LAST, &mc_cmd->cmd_cmd);
+ writew(0xffff, &mc_cmd->cmd_link);
+ writew(num_addrs * 6, &mc_cmd->mc_cnt);
- for(i=0;i<num_addrs;i++,dmi=dmi->next)
- memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr,6);
+ for (i = 0; i < num_addrs; i++, dmi = dmi->next)
+ memcpy_toio((char *) mc_cmd->mc_list[i],
+ dmi->dmi_addr, 6);
- p->scb->cbl_offset = make16(mc_cmd);
- p->scb->cmd_cuc = CUC_START;
+ writew(make16(mc_cmd), &p->scb->cbl_offset);
+ writeb(CUC_START, &p->scb->cmd_cuc);
ni_attn586();
- WAIT_4_STAT_COMPL(mc_cmd);
+ wait_for_stat_compl(mc_cmd);
- if( (mc_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )
- printk("%s: Can't apply multicast-address-list.\n",dev->name);
+ if ((readw(&mc_cmd->cmd_status) & (STAT_COMPL|STAT_OK))
+ != (STAT_COMPL|STAT_OK))
+ printk(KERN_ERR "%s: Can't apply multicast-address-list.\n", dev->name);
}
/*
* alloc nop/xmit-cmds
*/
#if (NUM_XMIT_BUFFS == 1)
- for(i=0;i<2;i++)
- {
- p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
- p->nop_cmds[i]->cmd_cmd = CMD_NOP;
- p->nop_cmds[i]->cmd_status = 0;
- p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
+ for (i = 0; i < 2; i++) {
+ p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
+ writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd);
+ writew(0, &p->nop_cmds[i]->cmd_status);
+ writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link);
ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
}
#else
- for(i=0;i<NUM_XMIT_BUFFS;i++)
- {
- p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
- p->nop_cmds[i]->cmd_cmd = CMD_NOP;
- p->nop_cmds[i]->cmd_status = 0;
- p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
+ for (i = 0; i < NUM_XMIT_BUFFS; i++) {
+ p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
+ writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd);
+ writew(0, &p->nop_cmds[i]->cmd_status);
+ writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link);
ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
}
#endif
- ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */
+ ptr = alloc_rfa(dev, (void *)ptr); /* init receive-frame-area */
/*
* alloc xmit-buffs / init xmit_cmds
*/
- for(i=0;i<NUM_XMIT_BUFFS;i++)
- {
- p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr; /*transmit cmd/buff 0*/
+ for (i = 0; i < NUM_XMIT_BUFFS; i++) {
+ /* Transmit cmd/buff 0 */
+ p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr;
ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
p->xmit_cbuffs[i] = (char *)ptr; /* char-buffs */
ptr = (char *) ptr + XMIT_BUFF_SIZE;
p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */
ptr = (char *) ptr + sizeof(struct tbd_struct);
- if((void *)ptr > (void *)p->iscp)
- {
- printk("%s: not enough shared-mem for your configuration!\n",dev->name);
+ if ((void *)ptr > (void *)p->iscp) {
+ printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n",
+ dev->name);
return 1;
}
- memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
- memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
- p->xmit_cmds[i]->cmd_link = make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]);
- p->xmit_cmds[i]->cmd_status = STAT_COMPL;
- p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT;
- p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
- p->xmit_buffs[i]->next = 0xffff;
- p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
+ memset_io((char *)(p->xmit_cmds[i]), 0,
+ sizeof(struct transmit_cmd_struct));
+ memset_io((char *)(p->xmit_buffs[i]), 0,
+ sizeof(struct tbd_struct));
+ writew(make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]),
+ &p->xmit_cmds[i]->cmd_link);
+ writew(STAT_COMPL, &p->xmit_cmds[i]->cmd_status);
+ writew(CMD_XMIT|CMD_INT, &p->xmit_cmds[i]->cmd_cmd);
+ writew(make16(p->xmit_buffs[i]), &p->xmit_cmds[i]->tbd_offset);
+ writew(0xffff, &p->xmit_buffs[i]->next);
+ writel(make24(p->xmit_cbuffs[i]), &p->xmit_buffs[i]->buffer);
}
p->xmit_count = 0;
@@ -761,21 +790,21 @@ static int init586(struct net_device *dev)
* 'start transmitter'
*/
#ifndef NO_NOPCOMMANDS
- p->scb->cbl_offset = make16(p->nop_cmds[0]);
- p->scb->cmd_cuc = CUC_START;
+ writew(make16(p->nop_cmds[0]), &p->scb->cbl_offset);
+ writeb(CUC_START, &p->scb->cmd_cuc);
ni_attn586();
- WAIT_4_SCB_CMD();
+ wait_for_scb_cmd(dev);
#else
- p->xmit_cmds[0]->cmd_link = make16(p->xmit_cmds[0]);
- p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_SUSPEND | CMD_INT;
+ writew(make16(p->xmit_cmds[0]), &p->xmit_cmds[0]->cmd_link);
+ writew(CMD_XMIT | CMD_SUSPEND | CMD_INT, &p->xmit_cmds[0]->cmd_cmd);
#endif
/*
* ack. interrupts
*/
- p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
+ writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc);
ni_attn586();
- DELAY_16();
+ udelay(16);
ni_enaint();
@@ -787,43 +816,45 @@ static int init586(struct net_device *dev)
* It sets up the Receive Frame Area (RFA).
*/
-static void *alloc_rfa(struct net_device *dev,void *ptr)
+static void *alloc_rfa(struct net_device *dev, void *ptr)
{
- volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
- volatile struct rbd_struct *rbd;
+ struct rfd_struct *rfd = (struct rfd_struct *)ptr;
+ struct rbd_struct *rbd;
int i;
struct priv *p = (struct priv *) dev->priv;
- memset((char *) rfd,0,sizeof(struct rfd_struct)*(p->num_recv_buffs+rfdadd));
+ memset_io((char *) rfd, 0,
+ sizeof(struct rfd_struct) * (p->num_recv_buffs + rfdadd));
p->rfd_first = rfd;
- for(i = 0; i < (p->num_recv_buffs+rfdadd); i++) {
- rfd[i].next = make16(rfd + (i+1) % (p->num_recv_buffs+rfdadd) );
- rfd[i].rbd_offset = 0xffff;
+ for (i = 0; i < (p->num_recv_buffs + rfdadd); i++) {
+ writew(make16(rfd + (i+1) % (p->num_recv_buffs+rfdadd)),
+ &rfd[i].next);
+ writew(0xffff, &rfd[i].rbd_offset);
}
- rfd[p->num_recv_buffs-1+rfdadd].last = RFD_SUSP; /* RU suspend */
+ /* RU suspend */
+ writeb(RFD_SUSP, &rfd[p->num_recv_buffs-1+rfdadd].last);
- ptr = (void *) (rfd + (p->num_recv_buffs + rfdadd) );
+ ptr = (void *) (rfd + (p->num_recv_buffs + rfdadd));
rbd = (struct rbd_struct *) ptr;
ptr = (void *) (rbd + p->num_recv_buffs);
/* clr descriptors */
- memset((char *) rbd,0,sizeof(struct rbd_struct)*(p->num_recv_buffs));
+ memset_io((char *)rbd, 0,
+ sizeof(struct rbd_struct) * (p->num_recv_buffs));
- for(i=0;i<p->num_recv_buffs;i++)
- {
- rbd[i].next = make16((rbd + (i+1) % p->num_recv_buffs));
- rbd[i].size = RECV_BUFF_SIZE;
- rbd[i].buffer = make24(ptr);
+ for (i = 0; i < p->num_recv_buffs; i++) {
+ writew(make16(rbd + (i+1) % p->num_recv_buffs), &rbd[i].next);
+ writew(RECV_BUFF_SIZE, &rbd[i].size);
+ writel(make24(ptr), &rbd[i].buffer);
ptr = (char *) ptr + RECV_BUFF_SIZE;
}
-
p->rfd_top = p->rfd_first;
p->rfd_last = p->rfd_first + (p->num_recv_buffs - 1 + rfdadd);
- p->scb->rfa_offset = make16(p->rfd_first);
- p->rfd_first->rbd_offset = make16(rbd);
+ writew(make16(p->rfd_first), &p->scb->rfa_offset);
+ writew(make16(rbd), &p->rfd_first->rbd_offset);
return ptr;
}
@@ -833,73 +864,71 @@ static void *alloc_rfa(struct net_device *dev,void *ptr)
* Interrupt Handler ...
*/
-static irqreturn_t ni52_interrupt(int irq,void *dev_id)
+static irqreturn_t ni52_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
- unsigned short stat;
- int cnt=0;
+ unsigned int stat;
+ int cnt = 0;
struct priv *p;
- if (!dev) {
- printk ("ni5210-interrupt: irq %d for unknown device.\n",irq);
- return IRQ_NONE;
- }
p = (struct priv *) dev->priv;
- if(debuglevel > 1)
+ if (debuglevel > 1)
printk("I");
- WAIT_4_SCB_CMD(); /* wait for last command */
+ spin_lock(&p->spinlock);
- while((stat=p->scb->cus & STAT_MASK))
- {
- p->scb->cmd_cuc = stat;
+ wait_for_scb_cmd(dev); /* wait for last command */
+
+ while ((stat = readb(&p->scb->cus) & STAT_MASK)) {
+ writeb(stat, &p->scb->cmd_cuc);
ni_attn586();
- if(stat & STAT_FR) /* received a frame */
+ if (stat & STAT_FR) /* received a frame */
ni52_rcv_int(dev);
- if(stat & STAT_RNR) /* RU went 'not ready' */
- {
+ if (stat & STAT_RNR) { /* RU went 'not ready' */
printk("(R)");
- if(p->scb->rus & RU_SUSPEND) /* special case: RU_SUSPEND */
- {
- WAIT_4_SCB_CMD();
+ if (readb(&p->scb->rus) & RU_SUSPEND) {
+ /* special case: RU_SUSPEND */
+ wait_for_scb_cmd(dev);
p->scb->cmd_ruc = RUC_RESUME;
ni_attn586();
- WAIT_4_SCB_CMD_RUC();
- }
- else
- {
- printk("%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->rus);
+ wait_for_scb_cmd_ruc(dev);
+ } else {
+ printk(KERN_ERR "%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",
+ dev->name, stat, readb(&p->scb->rus));
ni52_rnr_int(dev);
}
}
- if(stat & STAT_CX) /* command with I-bit set complete */
+ /* Command with I-bit set complete */
+ if (stat & STAT_CX)
ni52_xmt_int(dev);
#ifndef NO_NOPCOMMANDS
- if(stat & STAT_CNA) /* CU went 'not ready' */
- {
- if(netif_running(dev))
- printk("%s: oops! CU has left active state. stat: %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->cus);
+ if (stat & STAT_CNA) { /* CU went 'not ready' */
+ if (netif_running(dev))
+ printk(KERN_ERR "%s: oops! CU has left active state. stat: %04x/%02x.\n",
+ dev->name, stat, readb(&p->scb->cus));
}
#endif
- if(debuglevel > 1)
- printk("%d",cnt++);
+ if (debuglevel > 1)
+ printk("%d", cnt++);
- WAIT_4_SCB_CMD(); /* wait for ack. (ni52_xmt_int can be faster than ack!!) */
- if(p->scb->cmd_cuc) /* timed out? */
- {
- printk("%s: Acknowledge timed out.\n",dev->name);
+ /* Wait for ack. (ni52_xmt_int can be faster than ack!!) */
+ wait_for_scb_cmd(dev);
+ if (p->scb->cmd_cuc) { /* timed out? */
+ printk(KERN_ERR "%s: Acknowledge timed out.\n",
+ dev->name);
ni_disint();
break;
}
}
+ spin_unlock(&p->spinlock);
- if(debuglevel > 1)
+ if (debuglevel > 1)
printk("i");
return IRQ_HANDLED;
}
@@ -910,121 +939,91 @@ static irqreturn_t ni52_interrupt(int irq,void *dev_id)
static void ni52_rcv_int(struct net_device *dev)
{
- int status,cnt=0;
+ int status, cnt = 0;
unsigned short totlen;
struct sk_buff *skb;
struct rbd_struct *rbd;
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = (struct priv *)dev->priv;
- if(debuglevel > 0)
+ if (debuglevel > 0)
printk("R");
- for(;(status = p->rfd_top->stat_high) & RFD_COMPL;)
- {
- rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
-
- if(status & RFD_OK) /* frame received without error? */
- {
- if( (totlen = rbd->status) & RBD_LAST) /* the first and the last buffer? */
- {
- totlen &= RBD_MASK; /* length of this frame */
- rbd->status = 0;
- skb = (struct sk_buff *) dev_alloc_skb(totlen+2);
- if(skb != NULL)
- {
- skb_reserve(skb,2);
- skb_put(skb,totlen);
- skb_copy_to_linear_data(skb,(char *) p->base+(unsigned long) rbd->buffer,totlen);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- p->stats.rx_packets++;
- p->stats.rx_bytes += totlen;
+ for (; (status = readb(&p->rfd_top->stat_high)) & RFD_COMPL;) {
+ rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
+ if (status & RFD_OK) { /* frame received without error? */
+ totlen = readw(&rbd->status);
+ if (totlen & RBD_LAST) {
+ /* the first and the last buffer? */
+ totlen &= RBD_MASK; /* length of this frame */
+ writew(0x00, &rbd->status);
+ skb = (struct sk_buff *)dev_alloc_skb(totlen+2);
+ if (skb != NULL) {
+ skb_reserve(skb, 2);
+ skb_put(skb, totlen);
+ skb_copy_to_linear_data(skb, (char *)p->base + (unsigned long) rbd->buffer, totlen);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ dev->last_rx = jiffies;
+ p->stats.rx_packets++;
+ p->stats.rx_bytes += totlen;
+ } else
+ p->stats.rx_dropped++;
+ } else {
+ int rstat;
+ /* free all RBD's until RBD_LAST is set */
+ totlen = 0;
+ while (!((rstat = readw(&rbd->status)) & RBD_LAST)) {
+ totlen += rstat & RBD_MASK;
+ if (!rstat) {
+ printk(KERN_ERR "%s: Whoops .. no end mark in RBD list\n", dev->name);
+ break;
}
- else
- p->stats.rx_dropped++;
+ writew(0, &rbd->status);
+ rbd = (struct rbd_struct *) make32(readl(&rbd->next));
}
- else
- {
- int rstat;
- /* free all RBD's until RBD_LAST is set */
- totlen = 0;
- while(!((rstat=rbd->status) & RBD_LAST))
- {
- totlen += rstat & RBD_MASK;
- if(!rstat)
- {
- printk("%s: Whoops .. no end mark in RBD list\n",dev->name);
- break;
- }
- rbd->status = 0;
- rbd = (struct rbd_struct *) make32(rbd->next);
- }
- totlen += rstat & RBD_MASK;
- rbd->status = 0;
- printk("%s: received oversized frame! length: %d\n",dev->name,totlen);
- p->stats.rx_dropped++;
+ totlen += rstat & RBD_MASK;
+ writew(0, &rbd->status);
+ printk(KERN_ERR "%s: received oversized frame! length: %d\n",
+ dev->name, totlen);
+ p->stats.rx_dropped++;
}
- }
- else /* frame !(ok), only with 'save-bad-frames' */
- {
- printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);
+ } else {/* frame !(ok), only with 'save-bad-frames' */
+ printk(KERN_ERR "%s: oops! rfd-error-status: %04x\n",
+ dev->name, status);
p->stats.rx_errors++;
}
- p->rfd_top->stat_high = 0;
- p->rfd_top->last = RFD_SUSP; /* maybe exchange by RFD_LAST */
- p->rfd_top->rbd_offset = 0xffff;
- p->rfd_last->last = 0; /* delete RFD_SUSP */
+ writeb(0, &p->rfd_top->stat_high);
+ writeb(RFD_SUSP, &p->rfd_top->last); /* maybe exchange by RFD_LAST */
+ writew(0xffff, &p->rfd_top->rbd_offset);
+ writeb(0, &p->rfd_last->last); /* delete RFD_SUSP */
p->rfd_last = p->rfd_top;
p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
- p->scb->rfa_offset = make16(p->rfd_top);
+ writew(make16(p->rfd_top), &p->scb->rfa_offset);
- if(debuglevel > 0)
- printk("%d",cnt++);
+ if (debuglevel > 0)
+ printk("%d", cnt++);
}
- if(automatic_resume)
- {
- WAIT_4_SCB_CMD();
- p->scb->cmd_ruc = RUC_RESUME;
+ if (automatic_resume) {
+ wait_for_scb_cmd(dev);
+ writeb(RUC_RESUME, &p->scb->cmd_ruc);
ni_attn586();
- WAIT_4_SCB_CMD_RUC();
+ wait_for_scb_cmd_ruc(dev);
}
#ifdef WAIT_4_BUSY
{
int i;
- for(i=0;i<1024;i++)
- {
- if(p->rfd_top->status)
+ for (i = 0; i < 1024; i++) {
+ if (p->rfd_top->status)
break;
- DELAY_16();
- if(i == 1023)
- printk("%s: RU hasn't fetched next RFD (not busy/complete)\n",dev->name);
+ udelay(16);
+ if (i == 1023)
+ printk(KERN_ERR "%s: RU hasn't fetched next RFD (not busy/complete)\n", dev->name);
}
}
#endif
-
-#if 0
- if(!at_least_one)
- {
- int i;
- volatile struct rfd_struct *rfds=p->rfd_top;
- volatile struct rbd_struct *rbds;
- printk("%s: received a FC intr. without having a frame: %04x %d\n",dev->name,status,old_at_least);
- for(i=0;i< (p->num_recv_buffs+4);i++)
- {
- rbds = (struct rbd_struct *) make32(rfds->rbd_offset);
- printk("%04x:%04x ",rfds->status,rbds->status);
- rfds = (struct rfd_struct *) make32(rfds->next);
- }
- printk("\nerrs: %04x %04x stat: %04x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->status);
- printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus);
- }
- old_at_least = at_least_one;
-#endif
-
- if(debuglevel > 0)
+ if (debuglevel > 0)
printk("r");
}
@@ -1038,16 +1037,16 @@ static void ni52_rnr_int(struct net_device *dev)
p->stats.rx_errors++;
- WAIT_4_SCB_CMD(); /* wait for the last cmd, WAIT_4_FULLSTAT?? */
- p->scb->cmd_ruc = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
+ wait_for_scb_cmd(dev); /* wait for the last cmd, WAIT_4_FULLSTAT?? */
+ writeb(RUC_ABORT, &p->scb->cmd_ruc); /* usually the RU is in the 'no resource'-state .. abort it now. */
ni_attn586();
- WAIT_4_SCB_CMD_RUC(); /* wait for accept cmd. */
+ wait_for_scb_cmd_ruc(dev); /* wait for accept cmd. */
- alloc_rfa(dev,(char *)p->rfd_first);
-/* maybe add a check here, before restarting the RU */
+ alloc_rfa(dev, (char *)p->rfd_first);
+ /* maybe add a check here, before restarting the RU */
startrecv586(dev); /* restart RU */
- printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->rus);
+ printk(KERN_ERR "%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->rus);
}
@@ -1060,43 +1059,41 @@ static void ni52_xmt_int(struct net_device *dev)
int status;
struct priv *p = (struct priv *) dev->priv;
- if(debuglevel > 0)
+ if (debuglevel > 0)
printk("X");
- status = p->xmit_cmds[p->xmit_last]->cmd_status;
- if(!(status & STAT_COMPL))
- printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);
+ status = readw(&p->xmit_cmds[p->xmit_last]->cmd_status);
+ if (!(status & STAT_COMPL))
+ printk(KERN_ERR "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
- if(status & STAT_OK)
- {
+ if (status & STAT_OK) {
p->stats.tx_packets++;
p->stats.collisions += (status & TCMD_MAXCOLLMASK);
- }
- else
- {
+ } else {
p->stats.tx_errors++;
- if(status & TCMD_LATECOLL) {
- printk("%s: late collision detected.\n",dev->name);
+ if (status & TCMD_LATECOLL) {
+ printk(KERN_ERR "%s: late collision detected.\n",
+ dev->name);
p->stats.collisions++;
- }
- else if(status & TCMD_NOCARRIER) {
+ } else if (status & TCMD_NOCARRIER) {
p->stats.tx_carrier_errors++;
- printk("%s: no carrier detected.\n",dev->name);
- }
- else if(status & TCMD_LOSTCTS)
- printk("%s: loss of CTS detected.\n",dev->name);
- else if(status & TCMD_UNDERRUN) {
+ printk(KERN_ERR "%s: no carrier detected.\n",
+ dev->name);
+ } else if (status & TCMD_LOSTCTS)
+ printk(KERN_ERR "%s: loss of CTS detected.\n",
+ dev->name);
+ else if (status & TCMD_UNDERRUN) {
p->stats.tx_fifo_errors++;
- printk("%s: DMA underrun detected.\n",dev->name);
- }
- else if(status & TCMD_MAXCOLL) {
- printk("%s: Max. collisions exceeded.\n",dev->name);
+ printk(KERN_ERR "%s: DMA underrun detected.\n",
+ dev->name);
+ } else if (status & TCMD_MAXCOLL) {
+ printk(KERN_ERR "%s: Max. collisions exceeded.\n",
+ dev->name);
p->stats.collisions += 16;
}
}
-
#if (NUM_XMIT_BUFFS > 1)
- if( (++p->xmit_last) == NUM_XMIT_BUFFS)
+ if ((++p->xmit_last) == NUM_XMIT_BUFFS)
p->xmit_last = 0;
#endif
netif_wake_queue(dev);
@@ -1110,41 +1107,51 @@ static void startrecv586(struct net_device *dev)
{
struct priv *p = (struct priv *) dev->priv;
- WAIT_4_SCB_CMD();
- WAIT_4_SCB_CMD_RUC();
- p->scb->rfa_offset = make16(p->rfd_first);
- p->scb->cmd_ruc = RUC_START;
+ wait_for_scb_cmd(dev);
+ wait_for_scb_cmd_ruc(dev);
+ writew(make16(p->rfd_first), &p->scb->rfa_offset);
+ writeb(RUC_START, &p->scb->cmd_ruc);
ni_attn586(); /* start cmd. */
- WAIT_4_SCB_CMD_RUC(); /* wait for accept cmd. (no timeout!!) */
+ wait_for_scb_cmd_ruc(dev);
+ /* wait for accept cmd. (no timeout!!) */
}
static void ni52_timeout(struct net_device *dev)
{
struct priv *p = (struct priv *) dev->priv;
#ifndef NO_NOPCOMMANDS
- if(p->scb->cus & CU_ACTIVE) /* COMMAND-UNIT active? */
- {
+ if (readb(&p->scb->cus) & CU_ACTIVE) { /* COMMAND-UNIT active? */
netif_wake_queue(dev);
#ifdef DEBUG
- printk("%s: strange ... timeout with CU active?!?\n",dev->name);
- printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)p->xmit_cmds[0]->cmd_status,(int)p->nop_cmds[0]->cmd_status,(int)p->nop_cmds[1]->cmd_status,(int)p->nop_point);
+ printk(KERN_ERR "%s: strange ... timeout with CU active?!?\n",
+ dev->name);
+ printk(KERN_ERR "%s: X0: %04x N0: %04x N1: %04x %d\n",
+ dev->name, (int)p->xmit_cmds[0]->cmd_status,
+ readw(&p->nop_cmds[0]->cmd_status),
+ readw(&p->nop_cmds[1]->cmd_status),
+ p->nop_point);
#endif
- p->scb->cmd_cuc = CUC_ABORT;
+ writeb(CUC_ABORT, &p->scb->cmd_cuc);
ni_attn586();
- WAIT_4_SCB_CMD();
- p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
- p->scb->cmd_cuc = CUC_START;
+ wait_for_scb_cmd(dev);
+ writew(make16(p->nop_cmds[p->nop_point]), &p->scb->cbl_offset);
+ writeb(CUC_START, &p->scb->cmd_cuc);
ni_attn586();
- WAIT_4_SCB_CMD();
+ wait_for_scb_cmd(dev);
dev->trans_start = jiffies;
return 0;
}
#endif
{
#ifdef DEBUG
- printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus);
- printk("%s: command-stats: %04x %04x\n",dev->name,p->xmit_cmds[0]->cmd_status,p->xmit_cmds[1]->cmd_status);
- printk("%s: check, whether you set the right interrupt number!\n",dev->name);
+ printk(KERN_ERR "%s: xmitter timed out, try to restart! stat: %02x\n",
+ dev->name, readb(&p->scb->cus));
+ printk(KERN_ERR "%s: command-stats: %04x %04x\n",
+ dev->name,
+ readw(&p->xmit_cmds[0]->cmd_status),
+ readw(&p->xmit_cmds[1]->cmd_status));
+ printk(KERN_ERR "%s: check, whether you set the right interrupt number!\n",
+ dev->name);
#endif
ni52_close(dev);
ni52_open(dev);
@@ -1158,110 +1165,99 @@ static void ni52_timeout(struct net_device *dev)
static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev)
{
- int len,i;
+ int len, i;
#ifndef NO_NOPCOMMANDS
int next_nop;
#endif
struct priv *p = (struct priv *) dev->priv;
- if(skb->len > XMIT_BUFF_SIZE)
- {
- printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
+ if (skb->len > XMIT_BUFF_SIZE) {
+ printk(KERN_ERR "%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n", dev->name, XMIT_BUFF_SIZE, skb->len);
return 0;
}
netif_stop_queue(dev);
-#if(NUM_XMIT_BUFFS > 1)
- if(test_and_set_bit(0,(void *) &p->lock)) {
- printk("%s: Queue was locked\n",dev->name);
- return 1;
+ skb_copy_from_linear_data(skb, (char *)p->xmit_cbuffs[p->xmit_count],
+ skb->len);
+ len = skb->len;
+ if (len < ETH_ZLEN) {
+ len = ETH_ZLEN;
+ memset((char *)p->xmit_cbuffs[p->xmit_count]+skb->len, 0,
+ len - skb->len);
}
- else
-#endif
- {
- skb_copy_from_linear_data(skb, (char *) p->xmit_cbuffs[p->xmit_count], skb->len);
- len = skb->len;
- if (len < ETH_ZLEN) {
- len = ETH_ZLEN;
- memset((char *)p->xmit_cbuffs[p->xmit_count]+skb->len, 0, len - skb->len);
- }
#if (NUM_XMIT_BUFFS == 1)
# ifdef NO_NOPCOMMANDS
#ifdef DEBUG
- if(p->scb->cus & CU_ACTIVE)
- {
- printk("%s: Hmmm .. CU is still running and we wanna send a new packet.\n",dev->name);
- printk("%s: stat: %04x %04x\n",dev->name,p->scb->cus,p->xmit_cmds[0]->cmd_status);
- }
+ if (p->scb->cus & CU_ACTIVE) {
+ printk(KERN_ERR "%s: Hmmm .. CU is still running and we wanna send a new packet.\n", dev->name);
+ printk(KERN_ERR "%s: stat: %04x %04x\n",
+ dev->name, readb(&p->scb->cus),
+ readw(&p->xmit_cmds[0]->cmd_status));
+ }
#endif
-
- p->xmit_buffs[0]->size = TBD_LAST | len;
- for(i=0;i<16;i++)
- {
- p->xmit_cmds[0]->cmd_status = 0;
- WAIT_4_SCB_CMD();
- if( (p->scb->cus & CU_STATUS) == CU_SUSPEND)
- p->scb->cmd_cuc = CUC_RESUME;
- else
- {
- p->scb->cbl_offset = make16(p->xmit_cmds[0]);
- p->scb->cmd_cuc = CUC_START;
- }
-
- ni_attn586();
- dev->trans_start = jiffies;
- if(!i)
- dev_kfree_skb(skb);
- WAIT_4_SCB_CMD();
- if( (p->scb->cus & CU_ACTIVE)) /* test it, because CU sometimes doesn't start immediately */
- break;
- if(p->xmit_cmds[0]->cmd_status)
- break;
- if(i==15)
- printk("%s: Can't start transmit-command.\n",dev->name);
+ writew(TBD_LAST | len, &p->xmit_buffs[0]->size);;
+ for (i = 0; i < 16; i++) {
+ writew(0, &p->xmit_cmds[0]->cmd_status);
+ wait_for_scb_cmd(dev);
+ if ((readb(&p->scb->cus) & CU_STATUS) == CU_SUSPEND)
+ writeb(CUC_RESUME, &p->scb->cmd_cuc);
+ else {
+ writew(make16(p->xmit_cmds[0]), &p->scb->cbl_offset);
+ writeb(CUC_START, &p->scb->cmd_cuc);
}
-# else
- next_nop = (p->nop_point + 1) & 0x1;
- p->xmit_buffs[0]->size = TBD_LAST | len;
-
- p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link
- = make16((p->nop_cmds[next_nop]));
- p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
-
- p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
+ ni_attn586();
dev->trans_start = jiffies;
- p->nop_point = next_nop;
- dev_kfree_skb(skb);
+ if (!i)
+ dev_kfree_skb(skb);
+ wait_for_scb_cmd(dev);
+ /* test it, because CU sometimes doesn't start immediately */
+ if (readb(&p->scb->cus) & CU_ACTIVE)
+ break;
+ if (readw(&p->xmit_cmds[0]->cmd_status))
+ break;
+ if (i == 15)
+ printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
+ }
+# else
+ next_nop = (p->nop_point + 1) & 0x1;
+ writew(TBD_LAST | len, &p->xmit_buffs[0]->size);
+ writew(make16(p->nop_cmds[next_nop]), &p->xmit_cmds[0]->cmd_link);
+ writew(make16(p->nop_cmds[next_nop]),
+ &p->nop_cmds[next_nop]->cmd_link);
+ writew(0, &p->xmit_cmds[0]->cmd_status);
+ writew(0, &p->nop_cmds[next_nop]->cmd_status);
+
+ writew(make16(p->xmit_cmds[0]), &p->nop_cmds[p->nop_point]->cmd_link);
+ dev->trans_start = jiffies;
+ p->nop_point = next_nop;
+ dev_kfree_skb(skb);
# endif
#else
- p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
- if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )
- next_nop = 0;
-
- p->xmit_cmds[p->xmit_count]->cmd_status = 0;
- /* linkpointer of xmit-command already points to next nop cmd */
- p->nop_cmds[next_nop]->cmd_link = make16((p->nop_cmds[next_nop]));
- p->nop_cmds[next_nop]->cmd_status = 0;
-
- p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
- dev->trans_start = jiffies;
- p->xmit_count = next_nop;
-
- {
- unsigned long flags;
- save_flags(flags);
- cli();
- if(p->xmit_count != p->xmit_last)
- netif_wake_queue(dev);
- p->lock = 0;
- restore_flags(flags);
- }
- dev_kfree_skb(skb);
-#endif
+ writew(TBD_LAST | len, &p->xmit_buffs[p->xmit_count]->size);
+ next_nop = p->xmit_count + 1
+ if (next_nop == NUM_XMIT_BUFFS)
+ next_nop = 0;
+ writew(0, &p->xmit_cmds[p->xmit_count]->cmd_status);
+ /* linkpointer of xmit-command already points to next nop cmd */
+ writew(make16(p->nop_cmds[next_nop]),
+ &p->nop_cmds[next_nop]->cmd_link);
+ writew(0, &p->nop_cmds[next_nop]->cmd_status);
+ writew(make16(p->xmit_cmds[p->xmit_count]),
+ &p->nop_cmds[p->xmit_count]->cmd_link);
+ dev->trans_start = jiffies;
+ p->xmit_count = next_nop;
+ {
+ unsigned long flags;
+ spin_lock_irqsave(&p->spinlock);
+ if (p->xmit_count != p->xmit_last)
+ netif_wake_queue(dev);
+ spin_unlock_irqrestore(&p->spinlock);
}
+ dev_kfree_skb(skb);
+#endif
return 0;
}
@@ -1272,16 +1268,17 @@ static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev)
static struct net_device_stats *ni52_get_stats(struct net_device *dev)
{
struct priv *p = (struct priv *) dev->priv;
- unsigned short crc,aln,rsc,ovrn;
-
- crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */
- p->scb->crc_errs = 0;
- aln = p->scb->aln_errs;
- p->scb->aln_errs = 0;
- rsc = p->scb->rsc_errs;
- p->scb->rsc_errs = 0;
- ovrn = p->scb->ovrn_errs;
- p->scb->ovrn_errs = 0;
+ unsigned short crc, aln, rsc, ovrn;
+
+ /* Get error-statistics from the ni82586 */
+ crc = readw(&p->scb->crc_errs);
+ writew(0, &p->scb->crc_errs);
+ aln = readw(&p->scb->aln_errs);
+ writew(0, &p->scb->aln_errs);
+ rsc = readw(&p->scb->rsc_errs);
+ writew(0, &p->scb->rsc_errs);
+ ovrn = readw(&p->scb->ovrn_errs);
+ writew(0, &p->scb->ovrn_errs);
p->stats.rx_crc_errors += crc;
p->stats.rx_fifo_errors += ovrn;
@@ -1320,8 +1317,9 @@ MODULE_PARM_DESC(memend, "NI5210 memory end address,required");
int __init init_module(void)
{
- if(io <= 0x0 || !memend || !memstart || irq < 2) {
- printk("ni52: Autoprobing not allowed for modules.\nni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n");
+ if (io <= 0x0 || !memend || !memstart || irq < 2) {
+ printk(KERN_ERR "ni52: Autoprobing not allowed for modules.\n");
+ printk(KERN_ERR "ni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n");
return -ENODEV;
}
dev_ni52 = ni52_probe(-1);
@@ -1338,42 +1336,6 @@ void __exit cleanup_module(void)
}
#endif /* MODULE */
-#if 0
-/*
- * DUMP .. we expect a not running CMD unit and enough space
- */
-void ni52_dump(struct net_device *dev,void *ptr)
-{
- struct priv *p = (struct priv *) dev->priv;
- struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr;
- int i;
-
- p->scb->cmd_cuc = CUC_ABORT;
- ni_attn586();
- WAIT_4_SCB_CMD();
- WAIT_4_SCB_CMD_RUC();
-
- dump_cmd->cmd_status = 0;
- dump_cmd->cmd_cmd = CMD_DUMP | CMD_LAST;
- dump_cmd->dump_offset = make16((dump_cmd + 1));
- dump_cmd->cmd_link = 0xffff;
-
- p->scb->cbl_offset = make16(dump_cmd);
- p->scb->cmd_cuc = CUC_START;
- ni_attn586();
- WAIT_4_STAT_COMPL(dump_cmd);
-
- if( (dump_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )
- printk("%s: Can't get dump information.\n",dev->name);
-
- for(i=0;i<170;i++) {
- printk("%02x ",(int) ((unsigned char *) (dump_cmd + 1))[i]);
- if(i % 24 == 23)
- printk("\n");
- }
- printk("\n");
-}
-#endif
MODULE_LICENSE("GPL");
/*
diff --git a/drivers/net/ni52.h b/drivers/net/ni52.h
index a33ea0884aa..1f28a4d1a31 100644
--- a/drivers/net/ni52.h
+++ b/drivers/net/ni52.h
@@ -36,12 +36,12 @@
struct scp_struct
{
- unsigned short zero_dum0; /* has to be zero */
- unsigned char sysbus; /* 0=16Bit,1=8Bit */
- unsigned char zero_dum1; /* has to be zero for 586 */
- unsigned short zero_dum2;
- unsigned short zero_dum3;
- char *iscp; /* pointer to the iscp-block */
+ u16 zero_dum0; /* has to be zero */
+ u8 sysbus; /* 0=16Bit,1=8Bit */
+ u8 zero_dum1; /* has to be zero for 586 */
+ u8 zero_dum2;
+ u8 zero_dum3;
+ u32 iscp; /* pointer to the iscp-block */
};
@@ -50,10 +50,10 @@ struct scp_struct
*/
struct iscp_struct
{
- unsigned char busy; /* 586 clears after successful init */
- unsigned char zero_dummy; /* has to be zero */
- unsigned short scb_offset; /* pointeroffset to the scb_base */
- char *scb_base; /* base-address of all 16-bit offsets */
+ u8 busy; /* 586 clears after successful init */
+ u8 zero_dummy; /* has to be zero */
+ u16 scb_offset; /* pointeroffset to the scb_base */
+ u32 scb_base; /* base-address of all 16-bit offsets */
};
/*
@@ -61,16 +61,16 @@ struct iscp_struct
*/
struct scb_struct
{
- unsigned char rus;
- unsigned char cus;
- unsigned char cmd_ruc; /* command word: RU part */
- unsigned char cmd_cuc; /* command word: CU part & ACK */
- unsigned short cbl_offset; /* pointeroffset, command block list */
- unsigned short rfa_offset; /* pointeroffset, receive frame area */
- unsigned short crc_errs; /* CRC-Error counter */
- unsigned short aln_errs; /* alignmenterror counter */
- unsigned short rsc_errs; /* Resourceerror counter */
- unsigned short ovrn_errs; /* OVerrunerror counter */
+ u8 rus;
+ u8 cus;
+ u8 cmd_ruc; /* command word: RU part */
+ u8 cmd_cuc; /* command word: CU part & ACK */
+ u16 cbl_offset; /* pointeroffset, command block list */
+ u16 rfa_offset; /* pointeroffset, receive frame area */
+ u16 crc_errs; /* CRC-Error counter */
+ u16 aln_errs; /* alignmenterror counter */
+ u16 rsc_errs; /* Resourceerror counter */
+ u16 ovrn_errs; /* OVerrunerror counter */
};
/*
@@ -119,16 +119,16 @@ struct scb_struct
*/
struct rfd_struct
{
- unsigned char stat_low; /* status word */
- unsigned char stat_high; /* status word */
- unsigned char rfd_sf; /* 82596 mode only */
- unsigned char last; /* Bit15,Last Frame on List / Bit14,suspend */
- unsigned short next; /* linkoffset to next RFD */
- unsigned short rbd_offset; /* pointeroffset to RBD-buffer */
- unsigned char dest[6]; /* ethernet-address, destination */
- unsigned char source[6]; /* ethernet-address, source */
- unsigned short length; /* 802.3 frame-length */
- unsigned short zero_dummy; /* dummy */
+ u8 stat_low; /* status word */
+ u8 stat_high; /* status word */
+ u8 rfd_sf; /* 82596 mode only */
+ u8 last; /* Bit15,Last Frame on List / Bit14,suspend */
+ u16 next; /* linkoffset to next RFD */
+ u16 rbd_offset; /* pointeroffset to RBD-buffer */
+ u8 dest[6]; /* ethernet-address, destination */
+ u8 source[6]; /* ethernet-address, source */
+ u16 length; /* 802.3 frame-length */
+ u16 zero_dummy; /* dummy */
};
#define RFD_LAST 0x80 /* last: last rfd in the list */
@@ -153,11 +153,11 @@ struct rfd_struct
*/
struct rbd_struct
{
- unsigned short status; /* status word,number of used bytes in buff */
- unsigned short next; /* pointeroffset to next RBD */
- char *buffer; /* receive buffer address pointer */
- unsigned short size; /* size of this buffer */
- unsigned short zero_dummy; /* dummy */
+ u16 status; /* status word,number of used bytes in buff */
+ u16 next; /* pointeroffset to next RBD */
+ u32 buffer; /* receive buffer address pointer */
+ u16 size; /* size of this buffer */
+ u16 zero_dummy; /* dummy */
};
#define RBD_LAST 0x8000 /* last buffer */
@@ -195,9 +195,9 @@ struct rbd_struct
*/
struct nop_cmd_struct
{
- unsigned short cmd_status; /* status of this command */
- unsigned short cmd_cmd; /* the command itself (+bits) */
- unsigned short cmd_link; /* offsetpointer to next command */
+ u16 cmd_status; /* status of this command */
+ u16 cmd_cmd; /* the command itself (+bits) */
+ u16 cmd_link; /* offsetpointer to next command */
};
/*
@@ -205,10 +205,10 @@ struct nop_cmd_struct
*/
struct iasetup_cmd_struct
{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned char iaddr[6];
+ u16 cmd_status;
+ u16 cmd_cmd;
+ u16 cmd_link;
+ u8 iaddr[6];
};
/*
@@ -216,21 +216,21 @@ struct iasetup_cmd_struct
*/
struct configure_cmd_struct
{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned char byte_cnt; /* size of the config-cmd */
- unsigned char fifo; /* fifo/recv monitor */
- unsigned char sav_bf; /* save bad frames (bit7=1)*/
- unsigned char adr_len; /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/
- unsigned char priority; /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */
- unsigned char ifs; /* inter frame spacing */
- unsigned char time_low; /* slot time low */
- unsigned char time_high; /* slot time high(0-2) and max. retries(4-7) */
- unsigned char promisc; /* promisc-mode(0) , et al (1-7) */
- unsigned char carr_coll; /* carrier(0-3)/collision(4-7) stuff */
- unsigned char fram_len; /* minimal frame len */
- unsigned char dummy; /* dummy */
+ u16 cmd_status;
+ u16 cmd_cmd;
+ u16 cmd_link;
+ u8 byte_cnt; /* size of the config-cmd */
+ u8 fifo; /* fifo/recv monitor */
+ u8 sav_bf; /* save bad frames (bit7=1)*/
+ u8 adr_len; /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/
+ u8 priority; /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */
+ u8 ifs; /* inter frame spacing */
+ u8 time_low; /* slot time low */
+ u8 time_high; /* slot time high(0-2) and max. retries(4-7) */
+ u8 promisc; /* promisc-mode(0) , et al (1-7) */
+ u8 carr_coll; /* carrier(0-3)/collision(4-7) stuff */
+ u8 fram_len; /* minimal frame len */
+ u8 dummy; /* dummy */
};
/*
@@ -238,11 +238,11 @@ struct configure_cmd_struct
*/
struct mcsetup_cmd_struct
{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short mc_cnt; /* number of bytes in the MC-List */
- unsigned char mc_list[0][6]; /* pointer to 6 bytes entries */
+ u16 cmd_status;
+ u16 cmd_cmd;
+ u16 cmd_link;
+ u16 mc_cnt; /* number of bytes in the MC-List */
+ u8 mc_list[0][6]; /* pointer to 6 bytes entries */
};
/*
@@ -250,10 +250,10 @@ struct mcsetup_cmd_struct
*/
struct dump_cmd_struct
{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short dump_offset; /* pointeroffset to DUMP space */
+ u16 cmd_status;
+ u16 cmd_cmd;
+ u16 cmd_link;
+ u16 dump_offset; /* pointeroffset to DUMP space */
};
/*
@@ -261,12 +261,12 @@ struct dump_cmd_struct
*/
struct transmit_cmd_struct
{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short tbd_offset; /* pointeroffset to TBD */
- unsigned char dest[6]; /* destination address of the frame */
- unsigned short length; /* user defined: 802.3 length / Ether type */
+ u16 cmd_status;
+ u16 cmd_cmd;
+ u16 cmd_link;
+ u16 tbd_offset; /* pointeroffset to TBD */
+ u8 dest[6]; /* destination address of the frame */
+ u16 length; /* user defined: 802.3 length / Ether type */
};
#define TCMD_ERRMASK 0x0fa0
@@ -281,10 +281,10 @@ struct transmit_cmd_struct
struct tdr_cmd_struct
{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short status;
+ u16 cmd_status;
+ u16 cmd_cmd;
+ u16 cmd_link;
+ u16 status;
};
#define TDR_LNK_OK 0x8000 /* No link problem identified */
@@ -298,9 +298,9 @@ struct tdr_cmd_struct
*/
struct tbd_struct
{
- unsigned short size; /* size + EOF-Flag(15) */
- unsigned short next; /* pointeroffset to next TBD */
- char *buffer; /* pointer to buffer */
+ u16 size; /* size + EOF-Flag(15) */
+ u16 next; /* pointeroffset to next TBD */
+ u32 buffer; /* pointer to buffer */
};
#define TBD_LAST 0x8000 /* EOF-Flag, indicates last buffer in list */
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 2fe14b0c5c6..d11ba61baa4 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -33,8 +33,8 @@
#define DRV_MODULE_NAME "niu"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "0.6"
-#define DRV_MODULE_RELDATE "January 5, 2008"
+#define DRV_MODULE_VERSION "0.7"
+#define DRV_MODULE_RELDATE "February 18, 2008"
static char version[] __devinitdata =
DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
@@ -1616,12 +1616,13 @@ static int niu_enable_alt_mac(struct niu *np, int index, int on)
if (index >= niu_num_alt_addr(np))
return -EINVAL;
- if (np->flags & NIU_FLAGS_XMAC)
+ if (np->flags & NIU_FLAGS_XMAC) {
reg = XMAC_ADDR_CMPEN;
- else
+ mask = 1 << index;
+ } else {
reg = BMAC_ADDR_CMPEN;
-
- mask = 1 << index;
+ mask = 1 << (index + 1);
+ }
val = nr64_mac(reg);
if (on)
@@ -5147,7 +5148,12 @@ static void niu_set_rx_mode(struct net_device *dev)
index++;
}
} else {
- for (i = 0; i < niu_num_alt_addr(np); i++) {
+ int alt_start;
+ if (np->flags & NIU_FLAGS_XMAC)
+ alt_start = 0;
+ else
+ alt_start = 1;
+ for (i = alt_start; i < niu_num_alt_addr(np); i++) {
err = niu_enable_alt_mac(np, i, 0);
if (err)
printk(KERN_WARNING PFX "%s: Error %d "
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index 0e8626adc57..59dc05fcd37 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -499,7 +499,7 @@
#define BMAC_ADDR2 0x00110UL
#define BMAC_ADDR2_ADDR2 0x000000000000ffffULL
-#define BMAC_NUM_ALT_ADDR 7
+#define BMAC_NUM_ALT_ADDR 6
#define BMAC_ALT_ADDR0(NUM) (0x00118UL + (NUM)*0x18UL)
#define BMAC_ALT_ADDR0_ADDR0 0x000000000000ffffULL
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 6323988dfa1..fd8158a86f6 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -590,6 +590,13 @@ static int pcnet_config(struct pcmcia_device *link)
dev->if_port = 0;
}
+ if ((link->conf.ConfigBase == 0x03c0)
+ && (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) {
+ printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
+ printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
+ goto failed;
+ }
+
local_hw_info = get_hwinfo(link);
if (local_hw_info == NULL)
local_hw_info = get_prom(link);
@@ -1567,12 +1574,11 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0145),
PCMCIA_DEVICE_MANF_CARD(0x0149, 0x0230),
PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530),
-/* PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), conflict with axnet_cs */
+ PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab),
PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110),
PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041),
PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452),
-/* PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), conflict with axnet_cs */
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0307),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030a),
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index f18eca9831e..250eb1954c3 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -559,8 +559,16 @@ static int mhz_setup(struct pcmcia_device *link)
/* Read the station address from the CIS. It is stored as the last
(fourth) string in the Version 1 Version/ID tuple. */
- if (link->prod_id[3]) {
- station_addr = link->prod_id[3];
+ tuple->DesiredTuple = CISTPL_VERS_1;
+ if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
+ rc = -1;
+ goto free_cfg_mem;
+ }
+ /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
+ if (next_tuple(link, tuple, parse) != CS_SUCCESS)
+ first_tuple(link, tuple, parse);
+ if (parse->version_1.ns > 3) {
+ station_addr = parse->version_1.str + parse->version_1.ofs[3];
if (cvt_ascii_address(dev, station_addr) == 0) {
rc = 0;
goto free_cfg_mem;
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index c4b74e9fed2..4eb322e5273 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -174,7 +174,11 @@ static int homepna[MAX_UNITS];
#define RX_RING_SIZE (1 << (PCNET32_LOG_RX_BUFFERS))
#define RX_MAX_RING_SIZE (1 << (PCNET32_LOG_MAX_RX_BUFFERS))
-#define PKT_BUF_SZ 1544
+#define PKT_BUF_SKB 1544
+/* actual buffer length after being aligned */
+#define PKT_BUF_SIZE (PKT_BUF_SKB - NET_IP_ALIGN)
+/* chip wants twos complement of the (aligned) buffer length */
+#define NEG_BUF_SIZE (NET_IP_ALIGN - PKT_BUF_SKB)
/* Offsets from base I/O address. */
#define PCNET32_WIO_RDP 0x10
@@ -604,7 +608,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
/* now allocate any new buffers needed */
for (; new < size; new++ ) {
struct sk_buff *rx_skbuff;
- new_skb_list[new] = dev_alloc_skb(PKT_BUF_SZ);
+ new_skb_list[new] = dev_alloc_skb(PKT_BUF_SKB);
if (!(rx_skbuff = new_skb_list[new])) {
/* keep the original lists and buffers */
if (netif_msg_drv(lp))
@@ -613,20 +617,20 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
dev->name);
goto free_all_new;
}
- skb_reserve(rx_skbuff, 2);
+ skb_reserve(rx_skbuff, NET_IP_ALIGN);
new_dma_addr_list[new] =
pci_map_single(lp->pci_dev, rx_skbuff->data,
- PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
+ PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
new_rx_ring[new].base = cpu_to_le32(new_dma_addr_list[new]);
- new_rx_ring[new].buf_length = cpu_to_le16(2 - PKT_BUF_SZ);
+ new_rx_ring[new].buf_length = cpu_to_le16(NEG_BUF_SIZE);
new_rx_ring[new].status = cpu_to_le16(0x8000);
}
/* and free any unneeded buffers */
for (; new < lp->rx_ring_size; new++) {
if (lp->rx_skbuff[new]) {
pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[new],
- PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
+ PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
dev_kfree_skb(lp->rx_skbuff[new]);
}
}
@@ -651,7 +655,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
for (; --new >= lp->rx_ring_size; ) {
if (new_skb_list[new]) {
pci_unmap_single(lp->pci_dev, new_dma_addr_list[new],
- PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
+ PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
dev_kfree_skb(new_skb_list[new]);
}
}
@@ -678,7 +682,7 @@ static void pcnet32_purge_rx_ring(struct net_device *dev)
wmb(); /* Make sure adapter sees owner change */
if (lp->rx_skbuff[i]) {
pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i],
- PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
+ PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(lp->rx_skbuff[i]);
}
lp->rx_skbuff[i] = NULL;
@@ -1201,7 +1205,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
pkt_len = (le32_to_cpu(rxp->msg_length) & 0xfff) - 4;
/* Discard oversize frames. */
- if (unlikely(pkt_len > PKT_BUF_SZ - 2)) {
+ if (unlikely(pkt_len > PKT_BUF_SIZE)) {
if (netif_msg_drv(lp))
printk(KERN_ERR "%s: Impossible packet size %d!\n",
dev->name, pkt_len);
@@ -1218,26 +1222,26 @@ static void pcnet32_rx_entry(struct net_device *dev,
if (pkt_len > rx_copybreak) {
struct sk_buff *newskb;
- if ((newskb = dev_alloc_skb(PKT_BUF_SZ))) {
- skb_reserve(newskb, 2);
+ if ((newskb = dev_alloc_skb(PKT_BUF_SKB))) {
+ skb_reserve(newskb, NET_IP_ALIGN);
skb = lp->rx_skbuff[entry];
pci_unmap_single(lp->pci_dev,
lp->rx_dma_addr[entry],
- PKT_BUF_SZ - 2,
+ PKT_BUF_SIZE,
PCI_DMA_FROMDEVICE);
skb_put(skb, pkt_len);
lp->rx_skbuff[entry] = newskb;
lp->rx_dma_addr[entry] =
pci_map_single(lp->pci_dev,
newskb->data,
- PKT_BUF_SZ - 2,
+ PKT_BUF_SIZE,
PCI_DMA_FROMDEVICE);
rxp->base = cpu_to_le32(lp->rx_dma_addr[entry]);
rx_in_place = 1;
} else
skb = NULL;
} else {
- skb = dev_alloc_skb(pkt_len + 2);
+ skb = dev_alloc_skb(pkt_len + NET_IP_ALIGN);
}
if (skb == NULL) {
@@ -1250,7 +1254,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
}
skb->dev = dev;
if (!rx_in_place) {
- skb_reserve(skb, 2); /* 16 byte align */
+ skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pkt_len); /* Make room */
pci_dma_sync_single_for_cpu(lp->pci_dev,
lp->rx_dma_addr[entry],
@@ -1291,7 +1295,7 @@ static int pcnet32_rx(struct net_device *dev, int budget)
* The docs say that the buffer length isn't touched, but Andrew
* Boyd of QNX reports that some revs of the 79C965 clear it.
*/
- rxp->buf_length = cpu_to_le16(2 - PKT_BUF_SZ);
+ rxp->buf_length = cpu_to_le16(NEG_BUF_SIZE);
wmb(); /* Make sure owner changes after others are visible */
rxp->status = cpu_to_le16(0x8000);
entry = (++lp->cur_rx) & lp->rx_mod_mask;
@@ -1774,8 +1778,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
if (pcnet32_debug & NETIF_MSG_PROBE) {
- for (i = 0; i < 6; i++)
- printk(" %2.2x", dev->dev_addr[i]);
+ DECLARE_MAC_BUF(mac);
+ printk(" %s", print_mac(mac, dev->dev_addr));
/* Version 0x2623 and 0x2624 */
if (((chip_version + 1) & 0xfffe) == 0x2624) {
@@ -2396,7 +2400,7 @@ static int pcnet32_init_ring(struct net_device *dev)
if (rx_skbuff == NULL) {
if (!
(rx_skbuff = lp->rx_skbuff[i] =
- dev_alloc_skb(PKT_BUF_SZ))) {
+ dev_alloc_skb(PKT_BUF_SKB))) {
/* there is not much, we can do at this point */
if (netif_msg_drv(lp))
printk(KERN_ERR
@@ -2404,16 +2408,16 @@ static int pcnet32_init_ring(struct net_device *dev)
dev->name);
return -1;
}
- skb_reserve(rx_skbuff, 2);
+ skb_reserve(rx_skbuff, NET_IP_ALIGN);
}
rmb();
if (lp->rx_dma_addr[i] == 0)
lp->rx_dma_addr[i] =
pci_map_single(lp->pci_dev, rx_skbuff->data,
- PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
+ PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
lp->rx_ring[i].base = cpu_to_le32(lp->rx_dma_addr[i]);
- lp->rx_ring[i].buf_length = cpu_to_le16(2 - PKT_BUF_SZ);
+ lp->rx_ring[i].buf_length = cpu_to_le16(NEG_BUF_SIZE);
wmb(); /* Make sure owner changes after all others are visible */
lp->rx_ring[i].status = cpu_to_le16(0x8000);
}
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 73b6d39ef6b..ca9b040f9ad 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -236,12 +236,12 @@ module_init(fixed_mdio_bus_init);
static void __exit fixed_mdio_bus_exit(void)
{
struct fixed_mdio_bus *fmb = &platform_fmb;
- struct fixed_phy *fp;
+ struct fixed_phy *fp, *tmp;
mdiobus_unregister(&fmb->mii_bus);
platform_device_unregister(pdev);
- list_for_each_entry(fp, &fmb->phys, node) {
+ list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
list_del(&fp->node);
kfree(fp);
}
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 6e9f619c491..963630c65ca 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -49,13 +49,13 @@ int mdiobus_register(struct mii_bus *bus)
int i;
int err = 0;
- mutex_init(&bus->mdio_lock);
-
if (NULL == bus || NULL == bus->name ||
NULL == bus->read ||
NULL == bus->write)
return -EINVAL;
+ mutex_init(&bus->mdio_lock);
+
if (bus->reset)
bus->reset(bus);
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index e0b072d9fdb..86e5dba079f 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -455,6 +455,7 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
skb_queue_len(&session->reorder_q));
__skb_unlink(skb, &session->reorder_q);
kfree_skb(skb);
+ sock_put(session->sock);
continue;
}
@@ -1110,6 +1111,8 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) {
again:
hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
+ struct sk_buff *skb;
+
session = hlist_entry(walk, struct pppol2tp_session, hlist);
sk = session->sock;
@@ -1138,7 +1141,10 @@ again:
/* Purge any queued data */
skb_queue_purge(&sk->sk_receive_queue);
skb_queue_purge(&sk->sk_write_queue);
- skb_queue_purge(&session->reorder_q);
+ while ((skb = skb_dequeue(&session->reorder_q))) {
+ kfree_skb(skb);
+ sock_put(sk);
+ }
release_sock(sk);
sock_put(sk);
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 055af081e02..7eb6e7e848f 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -46,29 +46,25 @@
#include <asm/lv1call.h>
#include "ps3_gelic_net.h"
+#include "ps3_gelic_wireless.h"
#define DRV_NAME "Gelic Network Driver"
-#define DRV_VERSION "1.0"
+#define DRV_VERSION "2.0"
MODULE_AUTHOR("SCE Inc.");
MODULE_DESCRIPTION("Gelic Network driver");
MODULE_LICENSE("GPL");
-static inline struct device *ctodev(struct gelic_net_card *card)
-{
- return &card->dev->core;
-}
-static inline u64 bus_id(struct gelic_net_card *card)
-{
- return card->dev->bus_id;
-}
-static inline u64 dev_id(struct gelic_net_card *card)
-{
- return card->dev->dev_id;
-}
+
+static inline void gelic_card_enable_rxdmac(struct gelic_card *card);
+static inline void gelic_card_disable_rxdmac(struct gelic_card *card);
+static inline void gelic_card_disable_txdmac(struct gelic_card *card);
+static inline void gelic_card_reset_chain(struct gelic_card *card,
+ struct gelic_descr_chain *chain,
+ struct gelic_descr *start_descr);
/* set irq_mask */
-static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask)
+int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask)
{
int status;
@@ -76,54 +72,110 @@ static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask)
mask, 0);
if (status)
dev_info(ctodev(card),
- "lv1_net_set_interrupt_mask failed %d\n", status);
+ "%s failed %d\n", __func__, status);
return status;
}
-static inline void gelic_net_rx_irq_on(struct gelic_net_card *card)
+
+static inline void gelic_card_rx_irq_on(struct gelic_card *card)
{
- gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT);
+ card->irq_mask |= GELIC_CARD_RXINT;
+ gelic_card_set_irq_mask(card, card->irq_mask);
}
-static inline void gelic_net_rx_irq_off(struct gelic_net_card *card)
+static inline void gelic_card_rx_irq_off(struct gelic_card *card)
{
- gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT);
+ card->irq_mask &= ~GELIC_CARD_RXINT;
+ gelic_card_set_irq_mask(card, card->irq_mask);
+}
+
+static void gelic_card_get_ether_port_status(struct gelic_card *card,
+ int inform)
+{
+ u64 v2;
+ struct net_device *ether_netdev;
+
+ lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_LV1_GET_ETH_PORT_STATUS,
+ GELIC_LV1_VLAN_TX_ETHERNET, 0, 0,
+ &card->ether_port_status, &v2);
+
+ if (inform) {
+ ether_netdev = card->netdev[GELIC_PORT_ETHERNET];
+ if (card->ether_port_status & GELIC_LV1_ETHER_LINK_UP)
+ netif_carrier_on(ether_netdev);
+ else
+ netif_carrier_off(ether_netdev);
+ }
+}
+
+void gelic_card_up(struct gelic_card *card)
+{
+ pr_debug("%s: called\n", __func__);
+ down(&card->updown_lock);
+ if (atomic_inc_return(&card->users) == 1) {
+ pr_debug("%s: real do\n", __func__);
+ /* enable irq */
+ gelic_card_set_irq_mask(card, card->irq_mask);
+ /* start rx */
+ gelic_card_enable_rxdmac(card);
+
+ napi_enable(&card->napi);
+ }
+ up(&card->updown_lock);
+ pr_debug("%s: done\n", __func__);
}
+
+void gelic_card_down(struct gelic_card *card)
+{
+ u64 mask;
+ pr_debug("%s: called\n", __func__);
+ down(&card->updown_lock);
+ if (atomic_dec_if_positive(&card->users) == 0) {
+ pr_debug("%s: real do\n", __func__);
+ napi_disable(&card->napi);
+ /*
+ * Disable irq. Wireless interrupts will
+ * be disabled later if any
+ */
+ mask = card->irq_mask & (GELIC_CARD_WLAN_EVENT_RECEIVED |
+ GELIC_CARD_WLAN_COMMAND_COMPLETED);
+ gelic_card_set_irq_mask(card, mask);
+ /* stop rx */
+ gelic_card_disable_rxdmac(card);
+ gelic_card_reset_chain(card, &card->rx_chain,
+ card->descr + GELIC_NET_TX_DESCRIPTORS);
+ /* stop tx */
+ gelic_card_disable_txdmac(card);
+ }
+ up(&card->updown_lock);
+ pr_debug("%s: done\n", __func__);
+}
+
/**
- * gelic_net_get_descr_status -- returns the status of a descriptor
+ * gelic_descr_get_status -- returns the status of a descriptor
* @descr: descriptor to look at
*
* returns the status as in the dmac_cmd_status field of the descriptor
*/
-static enum gelic_net_descr_status
-gelic_net_get_descr_status(struct gelic_net_descr *descr)
+static enum gelic_descr_dma_status
+gelic_descr_get_status(struct gelic_descr *descr)
{
- u32 cmd_status;
-
- cmd_status = descr->dmac_cmd_status;
- cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT;
- return cmd_status;
+ return be32_to_cpu(descr->dmac_cmd_status) & GELIC_DESCR_DMA_STAT_MASK;
}
/**
- * gelic_net_set_descr_status -- sets the status of a descriptor
+ * gelic_descr_set_status -- sets the status of a descriptor
* @descr: descriptor to change
* @status: status to set in the descriptor
*
* changes the status to the specified value. Doesn't change other bits
* in the status
*/
-static void gelic_net_set_descr_status(struct gelic_net_descr *descr,
- enum gelic_net_descr_status status)
+static void gelic_descr_set_status(struct gelic_descr *descr,
+ enum gelic_descr_dma_status status)
{
- u32 cmd_status;
-
- /* read the status */
- cmd_status = descr->dmac_cmd_status;
- /* clean the upper 4 bits */
- cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO;
- /* add the status to it */
- cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT;
- /* and write it back */
- descr->dmac_cmd_status = cmd_status;
+ descr->dmac_cmd_status = cpu_to_be32(status |
+ (be32_to_cpu(descr->dmac_cmd_status) &
+ ~GELIC_DESCR_DMA_STAT_MASK));
/*
* dma_cmd_status field is used to indicate whether the descriptor
* is valid or not.
@@ -134,24 +186,24 @@ static void gelic_net_set_descr_status(struct gelic_net_descr *descr,
}
/**
- * gelic_net_free_chain - free descriptor chain
+ * gelic_card_free_chain - free descriptor chain
* @card: card structure
* @descr_in: address of desc
*/
-static void gelic_net_free_chain(struct gelic_net_card *card,
- struct gelic_net_descr *descr_in)
+static void gelic_card_free_chain(struct gelic_card *card,
+ struct gelic_descr *descr_in)
{
- struct gelic_net_descr *descr;
+ struct gelic_descr *descr;
for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) {
dma_unmap_single(ctodev(card), descr->bus_addr,
- GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL);
+ GELIC_DESCR_SIZE, DMA_BIDIRECTIONAL);
descr->bus_addr = 0;
}
}
/**
- * gelic_net_init_chain - links descriptor chain
+ * gelic_card_init_chain - links descriptor chain
* @card: card structure
* @chain: address of chain
* @start_descr: address of descriptor array
@@ -162,22 +214,22 @@ static void gelic_net_free_chain(struct gelic_net_card *card,
*
* returns 0 on success, <0 on failure
*/
-static int gelic_net_init_chain(struct gelic_net_card *card,
- struct gelic_net_descr_chain *chain,
- struct gelic_net_descr *start_descr, int no)
+static int gelic_card_init_chain(struct gelic_card *card,
+ struct gelic_descr_chain *chain,
+ struct gelic_descr *start_descr, int no)
{
int i;
- struct gelic_net_descr *descr;
+ struct gelic_descr *descr;
descr = start_descr;
memset(descr, 0, sizeof(*descr) * no);
/* set up the hardware pointers in each descriptor */
for (i = 0; i < no; i++, descr++) {
- gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
descr->bus_addr =
dma_map_single(ctodev(card), descr,
- GELIC_NET_DESCR_SIZE,
+ GELIC_DESCR_SIZE,
DMA_BIDIRECTIONAL);
if (!descr->bus_addr)
@@ -193,7 +245,7 @@ static int gelic_net_init_chain(struct gelic_net_card *card,
/* chain bus addr of hw descriptor */
descr = start_descr;
for (i = 0; i < no; i++, descr++) {
- descr->next_descr_addr = descr->next->bus_addr;
+ descr->next_descr_addr = cpu_to_be32(descr->next->bus_addr);
}
chain->head = start_descr;
@@ -208,13 +260,38 @@ iommu_error:
for (i--, descr--; 0 <= i; i--, descr--)
if (descr->bus_addr)
dma_unmap_single(ctodev(card), descr->bus_addr,
- GELIC_NET_DESCR_SIZE,
+ GELIC_DESCR_SIZE,
DMA_BIDIRECTIONAL);
return -ENOMEM;
}
/**
- * gelic_net_prepare_rx_descr - reinitializes a rx descriptor
+ * gelic_card_reset_chain - reset status of a descriptor chain
+ * @card: card structure
+ * @chain: address of chain
+ * @start_descr: address of descriptor array
+ *
+ * Reset the status of dma descriptors to ready state
+ * and re-initialize the hardware chain for later use
+ */
+static void gelic_card_reset_chain(struct gelic_card *card,
+ struct gelic_descr_chain *chain,
+ struct gelic_descr *start_descr)
+{
+ struct gelic_descr *descr;
+
+ for (descr = start_descr; start_descr != descr->next; descr++) {
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_CARDOWNED);
+ descr->next_descr_addr = cpu_to_be32(descr->next->bus_addr);
+ }
+
+ chain->head = start_descr;
+ chain->tail = (descr - 1);
+
+ (descr - 1)->next_descr_addr = 0;
+}
+/**
+ * gelic_descr_prepare_rx - reinitializes a rx descriptor
* @card: card structure
* @descr: descriptor to re-init
*
@@ -223,29 +300,27 @@ iommu_error:
* allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
* Activate the descriptor state-wise
*/
-static int gelic_net_prepare_rx_descr(struct gelic_net_card *card,
- struct gelic_net_descr *descr)
+static int gelic_descr_prepare_rx(struct gelic_card *card,
+ struct gelic_descr *descr)
{
int offset;
unsigned int bufsize;
- if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) {
+ if (gelic_descr_get_status(descr) != GELIC_DESCR_DMA_NOT_IN_USE)
dev_info(ctodev(card), "%s: ERROR status \n", __func__);
- }
/* we need to round up the buffer size to a multiple of 128 */
bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);
/* and we need to have it 128 byte aligned, therefore we allocate a
* bit more */
- descr->skb = netdev_alloc_skb(card->netdev,
- bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+ descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
if (!descr->skb) {
descr->buf_addr = 0; /* tell DMAC don't touch memory */
dev_info(ctodev(card),
"%s:allocate skb failed !!\n", __func__);
return -ENOMEM;
}
- descr->buf_size = bufsize;
+ descr->buf_size = cpu_to_be32(bufsize);
descr->dmac_cmd_status = 0;
descr->result_size = 0;
descr->valid_size = 0;
@@ -256,63 +331,64 @@ static int gelic_net_prepare_rx_descr(struct gelic_net_card *card,
if (offset)
skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
/* io-mmu-map the skb */
- descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data,
- GELIC_NET_MAX_MTU,
- DMA_FROM_DEVICE);
+ descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card),
+ descr->skb->data,
+ GELIC_NET_MAX_MTU,
+ DMA_FROM_DEVICE));
if (!descr->buf_addr) {
dev_kfree_skb_any(descr->skb);
descr->skb = NULL;
dev_info(ctodev(card),
"%s:Could not iommu-map rx buffer\n", __func__);
- gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
return -ENOMEM;
} else {
- gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED);
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_CARDOWNED);
return 0;
}
}
/**
- * gelic_net_release_rx_chain - free all skb of rx descr
+ * gelic_card_release_rx_chain - free all skb of rx descr
* @card: card structure
*
*/
-static void gelic_net_release_rx_chain(struct gelic_net_card *card)
+static void gelic_card_release_rx_chain(struct gelic_card *card)
{
- struct gelic_net_descr *descr = card->rx_chain.head;
+ struct gelic_descr *descr = card->rx_chain.head;
do {
if (descr->skb) {
dma_unmap_single(ctodev(card),
- descr->buf_addr,
+ be32_to_cpu(descr->buf_addr),
descr->skb->len,
DMA_FROM_DEVICE);
descr->buf_addr = 0;
dev_kfree_skb_any(descr->skb);
descr->skb = NULL;
- gelic_net_set_descr_status(descr,
- GELIC_NET_DESCR_NOT_IN_USE);
+ gelic_descr_set_status(descr,
+ GELIC_DESCR_DMA_NOT_IN_USE);
}
descr = descr->next;
} while (descr != card->rx_chain.head);
}
/**
- * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains
+ * gelic_card_fill_rx_chain - fills descriptors/skbs in the rx chains
* @card: card structure
*
* fills all descriptors in the rx chain: allocates skbs
* and iommu-maps them.
- * returns 0 on success, <0 on failure
+ * returns 0 on success, < 0 on failure
*/
-static int gelic_net_fill_rx_chain(struct gelic_net_card *card)
+static int gelic_card_fill_rx_chain(struct gelic_card *card)
{
- struct gelic_net_descr *descr = card->rx_chain.head;
+ struct gelic_descr *descr = card->rx_chain.head;
int ret;
do {
if (!descr->skb) {
- ret = gelic_net_prepare_rx_descr(card, descr);
+ ret = gelic_descr_prepare_rx(card, descr);
if (ret)
goto rewind;
}
@@ -321,41 +397,41 @@ static int gelic_net_fill_rx_chain(struct gelic_net_card *card)
return 0;
rewind:
- gelic_net_release_rx_chain(card);
+ gelic_card_release_rx_chain(card);
return ret;
}
/**
- * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
+ * gelic_card_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
* @card: card structure
*
- * returns 0 on success, <0 on failure
+ * returns 0 on success, < 0 on failure
*/
-static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card)
+static int gelic_card_alloc_rx_skbs(struct gelic_card *card)
{
- struct gelic_net_descr_chain *chain;
+ struct gelic_descr_chain *chain;
int ret;
chain = &card->rx_chain;
- ret = gelic_net_fill_rx_chain(card);
- chain->head = card->rx_top->prev; /* point to the last */
+ ret = gelic_card_fill_rx_chain(card);
+ chain->tail = card->rx_top->prev; /* point to the last */
return ret;
}
/**
- * gelic_net_release_tx_descr - processes a used tx descriptor
+ * gelic_descr_release_tx - processes a used tx descriptor
* @card: card structure
* @descr: descriptor to release
*
* releases a used tx descriptor (unmapping, freeing of skb)
*/
-static void gelic_net_release_tx_descr(struct gelic_net_card *card,
- struct gelic_net_descr *descr)
+static void gelic_descr_release_tx(struct gelic_card *card,
+ struct gelic_descr *descr)
{
struct sk_buff *skb = descr->skb;
- BUG_ON(!(descr->data_status & (1 << GELIC_NET_TXDESC_TAIL)));
+ BUG_ON(!(be32_to_cpu(descr->data_status) & GELIC_DESCR_TX_TAIL));
- dma_unmap_single(ctodev(card), descr->buf_addr, skb->len,
+ dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr), skb->len,
DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
@@ -369,59 +445,75 @@ static void gelic_net_release_tx_descr(struct gelic_net_card *card,
descr->skb = NULL;
/* set descr status */
- gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
+}
+
+static void gelic_card_stop_queues(struct gelic_card *card)
+{
+ netif_stop_queue(card->netdev[GELIC_PORT_ETHERNET]);
+
+ if (card->netdev[GELIC_PORT_WIRELESS])
+ netif_stop_queue(card->netdev[GELIC_PORT_WIRELESS]);
}
+static void gelic_card_wake_queues(struct gelic_card *card)
+{
+ netif_wake_queue(card->netdev[GELIC_PORT_ETHERNET]);
+ if (card->netdev[GELIC_PORT_WIRELESS])
+ netif_wake_queue(card->netdev[GELIC_PORT_WIRELESS]);
+}
/**
- * gelic_net_release_tx_chain - processes sent tx descriptors
+ * gelic_card_release_tx_chain - processes sent tx descriptors
* @card: adapter structure
* @stop: net_stop sequence
*
* releases the tx descriptors that gelic has finished with
*/
-static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
+static void gelic_card_release_tx_chain(struct gelic_card *card, int stop)
{
- struct gelic_net_descr_chain *tx_chain;
- enum gelic_net_descr_status status;
+ struct gelic_descr_chain *tx_chain;
+ enum gelic_descr_dma_status status;
+ struct net_device *netdev;
int release = 0;
for (tx_chain = &card->tx_chain;
tx_chain->head != tx_chain->tail && tx_chain->tail;
tx_chain->tail = tx_chain->tail->next) {
- status = gelic_net_get_descr_status(tx_chain->tail);
+ status = gelic_descr_get_status(tx_chain->tail);
+ netdev = tx_chain->tail->skb->dev;
switch (status) {
- case GELIC_NET_DESCR_RESPONSE_ERROR:
- case GELIC_NET_DESCR_PROTECTION_ERROR:
- case GELIC_NET_DESCR_FORCE_END:
+ case GELIC_DESCR_DMA_RESPONSE_ERROR:
+ case GELIC_DESCR_DMA_PROTECTION_ERROR:
+ case GELIC_DESCR_DMA_FORCE_END:
if (printk_ratelimit())
dev_info(ctodev(card),
"%s: forcing end of tx descriptor " \
"with status %x\n",
__func__, status);
- card->netdev->stats.tx_dropped++;
+ netdev->stats.tx_dropped++;
break;
- case GELIC_NET_DESCR_COMPLETE:
+ case GELIC_DESCR_DMA_COMPLETE:
if (tx_chain->tail->skb) {
- card->netdev->stats.tx_packets++;
- card->netdev->stats.tx_bytes +=
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes +=
tx_chain->tail->skb->len;
}
break;
- case GELIC_NET_DESCR_CARDOWNED:
+ case GELIC_DESCR_DMA_CARDOWNED:
/* pending tx request */
default:
- /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
+ /* any other value (== GELIC_DESCR_DMA_NOT_IN_USE) */
if (!stop)
goto out;
}
- gelic_net_release_tx_descr(card, tx_chain->tail);
+ gelic_descr_release_tx(card, tx_chain->tail);
release ++;
}
out:
if (!stop && release)
- netif_wake_queue(card->netdev);
+ gelic_card_wake_queues(card);
}
/**
@@ -432,9 +524,9 @@ out:
* netdev interface. It also sets up multicast, allmulti and promisc
* flags appropriately
*/
-static void gelic_net_set_multi(struct net_device *netdev)
+void gelic_net_set_multi(struct net_device *netdev)
{
- struct gelic_net_card *card = netdev_priv(netdev);
+ struct gelic_card *card = netdev_card(netdev);
struct dev_mc_list *mc;
unsigned int i;
uint8_t *p;
@@ -456,8 +548,8 @@ static void gelic_net_set_multi(struct net_device *netdev)
"lv1_net_add_multicast_address failed, %d\n",
status);
- if (netdev->flags & IFF_ALLMULTI
- || netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */
+ if ((netdev->flags & IFF_ALLMULTI) ||
+ (netdev->mc_count > GELIC_NET_MC_COUNT_MAX)) {
status = lv1_net_add_multicast_address(bus_id(card),
dev_id(card),
0, 1);
@@ -468,7 +560,7 @@ static void gelic_net_set_multi(struct net_device *netdev)
return;
}
- /* set multicast address */
+ /* set multicast addresses */
for (mc = netdev->mc_list; mc; mc = mc->next) {
addr = 0;
p = mc->dmi_addr;
@@ -487,31 +579,42 @@ static void gelic_net_set_multi(struct net_device *netdev)
}
/**
- * gelic_net_enable_rxdmac - enables the receive DMA controller
+ * gelic_card_enable_rxdmac - enables the receive DMA controller
* @card: card structure
*
- * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
+ * gelic_card_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
* in the GDADMACCNTR register
*/
-static inline void gelic_net_enable_rxdmac(struct gelic_net_card *card)
+static inline void gelic_card_enable_rxdmac(struct gelic_card *card)
{
int status;
+#ifdef DEBUG
+ if (gelic_descr_get_status(card->rx_chain.head) !=
+ GELIC_DESCR_DMA_CARDOWNED) {
+ printk(KERN_ERR "%s: status=%x\n", __func__,
+ be32_to_cpu(card->rx_chain.head->dmac_cmd_status));
+ printk(KERN_ERR "%s: nextphy=%x\n", __func__,
+ be32_to_cpu(card->rx_chain.head->next_descr_addr));
+ printk(KERN_ERR "%s: head=%p\n", __func__,
+ card->rx_chain.head);
+ }
+#endif
status = lv1_net_start_rx_dma(bus_id(card), dev_id(card),
- card->rx_chain.tail->bus_addr, 0);
+ card->rx_chain.head->bus_addr, 0);
if (status)
dev_info(ctodev(card),
"lv1_net_start_rx_dma failed, status=%d\n", status);
}
/**
- * gelic_net_disable_rxdmac - disables the receive DMA controller
+ * gelic_card_disable_rxdmac - disables the receive DMA controller
* @card: card structure
*
- * gelic_net_disable_rxdmac terminates processing on the DMA controller by
+ * gelic_card_disable_rxdmac terminates processing on the DMA controller by
* turing off DMA and issueing a force end
*/
-static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card)
+static inline void gelic_card_disable_rxdmac(struct gelic_card *card)
{
int status;
@@ -523,13 +626,13 @@ static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card)
}
/**
- * gelic_net_disable_txdmac - disables the transmit DMA controller
+ * gelic_card_disable_txdmac - disables the transmit DMA controller
* @card: card structure
*
- * gelic_net_disable_txdmac terminates processing on the DMA controller by
+ * gelic_card_disable_txdmac terminates processing on the DMA controller by
* turing off DMA and issueing a force end
*/
-static inline void gelic_net_disable_txdmac(struct gelic_net_card *card)
+static inline void gelic_card_disable_txdmac(struct gelic_card *card)
{
int status;
@@ -546,51 +649,37 @@ static inline void gelic_net_disable_txdmac(struct gelic_net_card *card)
*
* always returns 0
*/
-static int gelic_net_stop(struct net_device *netdev)
+int gelic_net_stop(struct net_device *netdev)
{
- struct gelic_net_card *card = netdev_priv(netdev);
-
- napi_disable(&card->napi);
- netif_stop_queue(netdev);
+ struct gelic_card *card;
- /* turn off DMA, force end */
- gelic_net_disable_rxdmac(card);
- gelic_net_disable_txdmac(card);
-
- gelic_net_set_irq_mask(card, 0);
-
- /* disconnect event port */
- free_irq(card->netdev->irq, card->netdev);
- ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
- card->netdev->irq = NO_IRQ;
+ pr_debug("%s: start\n", __func__);
+ netif_stop_queue(netdev);
netif_carrier_off(netdev);
- /* release chains */
- gelic_net_release_tx_chain(card, 1);
- gelic_net_release_rx_chain(card);
-
- gelic_net_free_chain(card, card->tx_top);
- gelic_net_free_chain(card, card->rx_top);
+ card = netdev_card(netdev);
+ gelic_card_down(card);
+ pr_debug("%s: done\n", __func__);
return 0;
}
/**
- * gelic_net_get_next_tx_descr - returns the next available tx descriptor
+ * gelic_card_get_next_tx_descr - returns the next available tx descriptor
* @card: device structure to get descriptor from
*
* returns the address of the next descriptor, or NULL if not available.
*/
-static struct gelic_net_descr *
-gelic_net_get_next_tx_descr(struct gelic_net_card *card)
+static struct gelic_descr *
+gelic_card_get_next_tx_descr(struct gelic_card *card)
{
if (!card->tx_chain.head)
return NULL;
/* see if the next descriptor is free */
if (card->tx_chain.tail != card->tx_chain.head->next &&
- gelic_net_get_descr_status(card->tx_chain.head) ==
- GELIC_NET_DESCR_NOT_IN_USE)
+ gelic_descr_get_status(card->tx_chain.head) ==
+ GELIC_DESCR_DMA_NOT_IN_USE)
return card->tx_chain.head;
else
return NULL;
@@ -606,32 +695,33 @@ gelic_net_get_next_tx_descr(struct gelic_net_card *card)
* depending on hardware checksum settings. This function assumes a wmb()
* has executed before.
*/
-static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr,
- struct sk_buff *skb)
+static void gelic_descr_set_tx_cmdstat(struct gelic_descr *descr,
+ struct sk_buff *skb)
{
if (skb->ip_summed != CHECKSUM_PARTIAL)
- descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS |
- GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+ descr->dmac_cmd_status =
+ cpu_to_be32(GELIC_DESCR_DMA_CMD_NO_CHKSUM |
+ GELIC_DESCR_TX_DMA_FRAME_TAIL);
else {
/* is packet ip?
* if yes: tcp? udp? */
if (skb->protocol == htons(ETH_P_IP)) {
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
descr->dmac_cmd_status =
- GELIC_NET_DMAC_CMDSTAT_TCPCS |
- GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+ cpu_to_be32(GELIC_DESCR_DMA_CMD_TCP_CHKSUM |
+ GELIC_DESCR_TX_DMA_FRAME_TAIL);
else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
descr->dmac_cmd_status =
- GELIC_NET_DMAC_CMDSTAT_UDPCS |
- GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+ cpu_to_be32(GELIC_DESCR_DMA_CMD_UDP_CHKSUM |
+ GELIC_DESCR_TX_DMA_FRAME_TAIL);
else /*
* the stack should checksum non-tcp and non-udp
* packets on his own: NETIF_F_IP_CSUM
*/
descr->dmac_cmd_status =
- GELIC_NET_DMAC_CMDSTAT_NOCS |
- GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+ cpu_to_be32(GELIC_DESCR_DMA_CMD_NO_CHKSUM |
+ GELIC_DESCR_TX_DMA_FRAME_TAIL);
}
}
}
@@ -662,7 +752,7 @@ static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb,
}
/**
- * gelic_net_prepare_tx_descr_v - get dma address of skb_data
+ * gelic_descr_prepare_tx - setup a descriptor for sending packets
* @card: card structure
* @descr: descriptor structure
* @skb: packet to use
@@ -670,16 +760,19 @@ static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb,
* returns 0 on success, <0 on failure.
*
*/
-static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
- struct gelic_net_descr *descr,
- struct sk_buff *skb)
+static int gelic_descr_prepare_tx(struct gelic_card *card,
+ struct gelic_descr *descr,
+ struct sk_buff *skb)
{
dma_addr_t buf;
- if (card->vlan_index != -1) {
+ if (card->vlan_required) {
struct sk_buff *skb_tmp;
+ enum gelic_port_type type;
+
+ type = netdev_port(skb->dev)->type;
skb_tmp = gelic_put_vlan_tag(skb,
- card->vlan_id[card->vlan_index]);
+ card->vlan[type].tx);
if (!skb_tmp)
return -ENOMEM;
skb = skb_tmp;
@@ -694,12 +787,12 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
return -ENOMEM;
}
- descr->buf_addr = buf;
- descr->buf_size = skb->len;
+ descr->buf_addr = cpu_to_be32(buf);
+ descr->buf_size = cpu_to_be32(skb->len);
descr->skb = skb;
descr->data_status = 0;
descr->next_descr_addr = 0; /* terminate hw descr */
- gelic_net_set_txdescr_cmdstat(descr, skb);
+ gelic_descr_set_tx_cmdstat(descr, skb);
/* bump free descriptor pointer */
card->tx_chain.head = descr->next;
@@ -707,20 +800,20 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
}
/**
- * gelic_net_kick_txdma - enables TX DMA processing
+ * gelic_card_kick_txdma - enables TX DMA processing
* @card: card structure
* @descr: descriptor address to enable TX processing at
*
*/
-static int gelic_net_kick_txdma(struct gelic_net_card *card,
- struct gelic_net_descr *descr)
+static int gelic_card_kick_txdma(struct gelic_card *card,
+ struct gelic_descr *descr)
{
int status = 0;
if (card->tx_dma_progress)
return 0;
- if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) {
+ if (gelic_descr_get_status(descr) == GELIC_DESCR_DMA_CARDOWNED) {
card->tx_dma_progress = 1;
status = lv1_net_start_tx_dma(bus_id(card), dev_id(card),
descr->bus_addr, 0);
@@ -738,56 +831,56 @@ static int gelic_net_kick_txdma(struct gelic_net_card *card,
*
* returns 0 on success, <0 on failure
*/
-static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
{
- struct gelic_net_card *card = netdev_priv(netdev);
- struct gelic_net_descr *descr;
+ struct gelic_card *card = netdev_card(netdev);
+ struct gelic_descr *descr;
int result;
unsigned long flags;
- spin_lock_irqsave(&card->tx_dma_lock, flags);
+ spin_lock_irqsave(&card->tx_lock, flags);
- gelic_net_release_tx_chain(card, 0);
+ gelic_card_release_tx_chain(card, 0);
- descr = gelic_net_get_next_tx_descr(card);
+ descr = gelic_card_get_next_tx_descr(card);
if (!descr) {
/*
* no more descriptors free
*/
- netif_stop_queue(netdev);
- spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ gelic_card_stop_queues(card);
+ spin_unlock_irqrestore(&card->tx_lock, flags);
return NETDEV_TX_BUSY;
}
- result = gelic_net_prepare_tx_descr_v(card, descr, skb);
+ result = gelic_descr_prepare_tx(card, descr, skb);
if (result) {
/*
* DMA map failed. As chanses are that failure
* would continue, just release skb and return
*/
- card->netdev->stats.tx_dropped++;
+ netdev->stats.tx_dropped++;
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ spin_unlock_irqrestore(&card->tx_lock, flags);
return NETDEV_TX_OK;
}
/*
* link this prepared descriptor to previous one
* to achieve high performance
*/
- descr->prev->next_descr_addr = descr->bus_addr;
+ descr->prev->next_descr_addr = cpu_to_be32(descr->bus_addr);
/*
* as hardware descriptor is modified in the above lines,
* ensure that the hardware sees it
*/
wmb();
- if (gelic_net_kick_txdma(card, descr)) {
+ if (gelic_card_kick_txdma(card, descr)) {
/*
* kick failed.
* release descriptors which were just prepared
*/
- card->netdev->stats.tx_dropped++;
- gelic_net_release_tx_descr(card, descr);
- gelic_net_release_tx_descr(card, descr->next);
+ netdev->stats.tx_dropped++;
+ gelic_descr_release_tx(card, descr);
+ gelic_descr_release_tx(card, descr->next);
card->tx_chain.tail = descr->next->next;
dev_info(ctodev(card), "%s: kick failure\n", __func__);
} else {
@@ -795,7 +888,7 @@ static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
netdev->trans_start = jiffies;
}
- spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ spin_unlock_irqrestore(&card->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -803,30 +896,34 @@ static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
* gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on
* @descr: descriptor to process
* @card: card structure
+ * @netdev: net_device structure to be passed packet
*
* iommu-unmaps the skb, fills out skb structure and passes the data to the
* stack. The descriptor state is not changed.
*/
-static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
- struct gelic_net_card *card)
+static void gelic_net_pass_skb_up(struct gelic_descr *descr,
+ struct gelic_card *card,
+ struct net_device *netdev)
+
{
- struct sk_buff *skb;
- struct net_device *netdev;
+ struct sk_buff *skb = descr->skb;
u32 data_status, data_error;
- data_status = descr->data_status;
- data_error = descr->data_error;
- netdev = card->netdev;
+ data_status = be32_to_cpu(descr->data_status);
+ data_error = be32_to_cpu(descr->data_error);
/* unmap skb buffer */
- skb = descr->skb;
- dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU,
+ dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr),
+ GELIC_NET_MAX_MTU,
DMA_FROM_DEVICE);
- skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size);
+ skb_put(skb, be32_to_cpu(descr->valid_size)?
+ be32_to_cpu(descr->valid_size) :
+ be32_to_cpu(descr->result_size));
if (!descr->valid_size)
dev_info(ctodev(card), "buffer full %x %x %x\n",
- descr->result_size, descr->buf_size,
- descr->dmac_cmd_status);
+ be32_to_cpu(descr->result_size),
+ be32_to_cpu(descr->buf_size),
+ be32_to_cpu(descr->dmac_cmd_status));
descr->skb = NULL;
/*
@@ -838,8 +935,8 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
/* checksum offload */
if (card->rx_csum) {
- if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) &&
- (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK)))
+ if ((data_status & GELIC_DESCR_DATA_STATUS_CHK_MASK) &&
+ (!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
skb->ip_summed = CHECKSUM_NONE;
@@ -847,15 +944,15 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
skb->ip_summed = CHECKSUM_NONE;
/* update netdevice statistics */
- card->netdev->stats.rx_packets++;
- card->netdev->stats.rx_bytes += skb->len;
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += skb->len;
/* pass skb up to stack */
netif_receive_skb(skb);
}
/**
- * gelic_net_decode_one_descr - processes an rx descriptor
+ * gelic_card_decode_one_descr - processes an rx descriptor
* @card: card structure
*
* returns 1 if a packet has been sent to the stack, otherwise 0
@@ -863,36 +960,56 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
* processes an rx descriptor by iommu-unmapping the data buffer and passing
* the packet up to the stack
*/
-static int gelic_net_decode_one_descr(struct gelic_net_card *card)
+static int gelic_card_decode_one_descr(struct gelic_card *card)
{
- enum gelic_net_descr_status status;
- struct gelic_net_descr_chain *chain = &card->rx_chain;
- struct gelic_net_descr *descr = chain->tail;
+ enum gelic_descr_dma_status status;
+ struct gelic_descr_chain *chain = &card->rx_chain;
+ struct gelic_descr *descr = chain->head;
+ struct net_device *netdev = NULL;
int dmac_chain_ended;
- status = gelic_net_get_descr_status(descr);
+ status = gelic_descr_get_status(descr);
/* is this descriptor terminated with next_descr == NULL? */
dmac_chain_ended =
- descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS;
+ be32_to_cpu(descr->dmac_cmd_status) &
+ GELIC_DESCR_RX_DMA_CHAIN_END;
- if (status == GELIC_NET_DESCR_CARDOWNED)
+ if (status == GELIC_DESCR_DMA_CARDOWNED)
return 0;
- if (status == GELIC_NET_DESCR_NOT_IN_USE) {
+ if (status == GELIC_DESCR_DMA_NOT_IN_USE) {
dev_dbg(ctodev(card), "dormant descr? %p\n", descr);
return 0;
}
- if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) ||
- (status == GELIC_NET_DESCR_PROTECTION_ERROR) ||
- (status == GELIC_NET_DESCR_FORCE_END)) {
+ /* netdevice select */
+ if (card->vlan_required) {
+ unsigned int i;
+ u16 vid;
+ vid = *(u16 *)(descr->skb->data) & VLAN_VID_MASK;
+ for (i = 0; i < GELIC_PORT_MAX; i++) {
+ if (card->vlan[i].rx == vid) {
+ netdev = card->netdev[i];
+ break;
+ }
+ };
+ if (GELIC_PORT_MAX <= i) {
+ pr_info("%s: unknown packet vid=%x\n", __func__, vid);
+ goto refill;
+ }
+ } else
+ netdev = card->netdev[GELIC_PORT_ETHERNET];
+
+ if ((status == GELIC_DESCR_DMA_RESPONSE_ERROR) ||
+ (status == GELIC_DESCR_DMA_PROTECTION_ERROR) ||
+ (status == GELIC_DESCR_DMA_FORCE_END)) {
dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
status);
- card->netdev->stats.rx_dropped++;
+ netdev->stats.rx_dropped++;
goto refill;
}
- if (status == GELIC_NET_DESCR_BUFFER_FULL) {
+ if (status == GELIC_DESCR_DMA_BUFFER_FULL) {
/*
* Buffer full would occur if and only if
* the frame length was longer than the size of this
@@ -909,14 +1026,14 @@ static int gelic_net_decode_one_descr(struct gelic_net_card *card)
* descriptoers any other than FRAME_END here should
* be treated as error.
*/
- if (status != GELIC_NET_DESCR_FRAME_END) {
+ if (status != GELIC_DESCR_DMA_FRAME_END) {
dev_dbg(ctodev(card), "RX descriptor with state %x\n",
status);
goto refill;
}
/* ok, we've got a packet in descr */
- gelic_net_pass_skb_up(descr, card);
+ gelic_net_pass_skb_up(descr, card, netdev);
refill:
/*
* So that always DMAC can see the end
@@ -926,21 +1043,21 @@ refill:
descr->next_descr_addr = 0;
/* change the descriptor state: */
- gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
/*
* this call can fail, but for now, just leave this
* decriptor without skb
*/
- gelic_net_prepare_rx_descr(card, descr);
+ gelic_descr_prepare_rx(card, descr);
- chain->head = descr;
- chain->tail = descr->next;
+ chain->tail = descr;
+ chain->head = descr->next;
/*
* Set this descriptor the end of the chain.
*/
- descr->prev->next_descr_addr = descr->bus_addr;
+ descr->prev->next_descr_addr = cpu_to_be32(descr->bus_addr);
/*
* If dmac chain was met, DMAC stopped.
@@ -956,29 +1073,27 @@ refill:
/**
* gelic_net_poll - NAPI poll function called by the stack to return packets
- * @netdev: interface device structure
+ * @napi: napi structure
* @budget: number of packets we can pass to the stack at most
*
- * returns 0 if no more packets available to the driver/stack. Returns 1,
- * if the quota is exceeded, but the driver has still packets.
+ * returns the number of the processed packets
*
*/
static int gelic_net_poll(struct napi_struct *napi, int budget)
{
- struct gelic_net_card *card = container_of(napi, struct gelic_net_card, napi);
- struct net_device *netdev = card->netdev;
+ struct gelic_card *card = container_of(napi, struct gelic_card, napi);
int packets_done = 0;
while (packets_done < budget) {
- if (!gelic_net_decode_one_descr(card))
+ if (!gelic_card_decode_one_descr(card))
break;
packets_done++;
}
if (packets_done < budget) {
- netif_rx_complete(netdev, napi);
- gelic_net_rx_irq_on(card);
+ napi_complete(napi);
+ gelic_card_rx_irq_on(card);
}
return packets_done;
}
@@ -989,7 +1104,7 @@ static int gelic_net_poll(struct napi_struct *napi, int budget)
*
* returns 0 on success, <0 on failure
*/
-static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
+int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
{
/* no need to re-alloc skbs or so -- the max mtu is about 2.3k
* and mtu is outbound only anyway */
@@ -1002,13 +1117,12 @@ static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
}
/**
- * gelic_net_interrupt - event handler for gelic_net
+ * gelic_card_interrupt - event handler for gelic_net
*/
-static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
+static irqreturn_t gelic_card_interrupt(int irq, void *ptr)
{
unsigned long flags;
- struct net_device *netdev = ptr;
- struct gelic_net_card *card = netdev_priv(netdev);
+ struct gelic_card *card = ptr;
u64 status;
status = card->irq_status;
@@ -1016,24 +1130,37 @@ static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
if (!status)
return IRQ_NONE;
+ status &= card->irq_mask;
+
if (card->rx_dma_restart_required) {
card->rx_dma_restart_required = 0;
- gelic_net_enable_rxdmac(card);
+ gelic_card_enable_rxdmac(card);
}
- if (status & GELIC_NET_RXINT) {
- gelic_net_rx_irq_off(card);
- netif_rx_schedule(netdev, &card->napi);
+ if (status & GELIC_CARD_RXINT) {
+ gelic_card_rx_irq_off(card);
+ napi_schedule(&card->napi);
}
- if (status & GELIC_NET_TXINT) {
- spin_lock_irqsave(&card->tx_dma_lock, flags);
+ if (status & GELIC_CARD_TXINT) {
+ spin_lock_irqsave(&card->tx_lock, flags);
card->tx_dma_progress = 0;
- gelic_net_release_tx_chain(card, 0);
+ gelic_card_release_tx_chain(card, 0);
/* kick outstanding tx descriptor if any */
- gelic_net_kick_txdma(card, card->tx_chain.tail);
- spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ gelic_card_kick_txdma(card, card->tx_chain.tail);
+ spin_unlock_irqrestore(&card->tx_lock, flags);
}
+
+ /* ether port status changed */
+ if (status & GELIC_CARD_PORT_STATUS_CHANGED)
+ gelic_card_get_ether_port_status(card, 1);
+
+#ifdef CONFIG_GELIC_WIRELESS
+ if (status & (GELIC_CARD_WLAN_EVENT_RECEIVED |
+ GELIC_CARD_WLAN_COMMAND_COMPLETED))
+ gelic_wl_interrupt(card->netdev[GELIC_PORT_WIRELESS], status);
+#endif
+
return IRQ_HANDLED;
}
@@ -1044,55 +1171,17 @@ static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
*
* see Documentation/networking/netconsole.txt
*/
-static void gelic_net_poll_controller(struct net_device *netdev)
+void gelic_net_poll_controller(struct net_device *netdev)
{
- struct gelic_net_card *card = netdev_priv(netdev);
+ struct gelic_card *card = netdev_card(netdev);
- gelic_net_set_irq_mask(card, 0);
- gelic_net_interrupt(netdev->irq, netdev);
- gelic_net_set_irq_mask(card, card->ghiintmask);
+ gelic_card_set_irq_mask(card, 0);
+ gelic_card_interrupt(netdev->irq, netdev);
+ gelic_card_set_irq_mask(card, card->irq_mask);
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
/**
- * gelic_net_open_device - open device and map dma region
- * @card: card structure
- */
-static int gelic_net_open_device(struct gelic_net_card *card)
-{
- int result;
-
- result = ps3_sb_event_receive_port_setup(card->dev, PS3_BINDING_CPU_ANY,
- &card->netdev->irq);
-
- if (result) {
- dev_info(ctodev(card),
- "%s:%d: gelic_net_open_device failed (%d)\n",
- __func__, __LINE__, result);
- result = -EPERM;
- goto fail_alloc_irq;
- }
-
- result = request_irq(card->netdev->irq, gelic_net_interrupt,
- IRQF_DISABLED, card->netdev->name, card->netdev);
-
- if (result) {
- dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n",
- __func__, __LINE__, result);
- goto fail_request_irq;
- }
-
- return 0;
-
-fail_request_irq:
- ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
- card->netdev->irq = NO_IRQ;
-fail_alloc_irq:
- return result;
-}
-
-
-/**
* gelic_net_open - called upon ifonfig up
* @netdev: interface device structure
*
@@ -1101,169 +1190,88 @@ fail_alloc_irq:
* gelic_net_open allocates all the descriptors and memory needed for
* operation, sets up multicast list and enables interrupts
*/
-static int gelic_net_open(struct net_device *netdev)
+int gelic_net_open(struct net_device *netdev)
{
- struct gelic_net_card *card = netdev_priv(netdev);
-
- dev_dbg(ctodev(card), " -> %s:%d\n", __func__, __LINE__);
-
- gelic_net_open_device(card);
-
- if (gelic_net_init_chain(card, &card->tx_chain,
- card->descr, GELIC_NET_TX_DESCRIPTORS))
- goto alloc_tx_failed;
- if (gelic_net_init_chain(card, &card->rx_chain,
- card->descr + GELIC_NET_TX_DESCRIPTORS,
- GELIC_NET_RX_DESCRIPTORS))
- goto alloc_rx_failed;
-
- /* head of chain */
- card->tx_top = card->tx_chain.head;
- card->rx_top = card->rx_chain.head;
- dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n",
- card->rx_top, card->tx_top, sizeof(struct gelic_net_descr),
- GELIC_NET_RX_DESCRIPTORS);
- /* allocate rx skbs */
- if (gelic_net_alloc_rx_skbs(card))
- goto alloc_skbs_failed;
+ struct gelic_card *card = netdev_card(netdev);
- napi_enable(&card->napi);
-
- card->tx_dma_progress = 0;
- card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT;
+ dev_dbg(ctodev(card), " -> %s %p\n", __func__, netdev);
- gelic_net_set_irq_mask(card, card->ghiintmask);
- gelic_net_enable_rxdmac(card);
+ gelic_card_up(card);
netif_start_queue(netdev);
- netif_carrier_on(netdev);
+ gelic_card_get_ether_port_status(card, 1);
+ dev_dbg(ctodev(card), " <- %s\n", __func__);
return 0;
-
-alloc_skbs_failed:
- gelic_net_free_chain(card, card->rx_top);
-alloc_rx_failed:
- gelic_net_free_chain(card, card->tx_top);
-alloc_tx_failed:
- return -ENOMEM;
}
-static void gelic_net_get_drvinfo (struct net_device *netdev,
- struct ethtool_drvinfo *info)
+void gelic_net_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *info)
{
strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1);
strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1);
}
-static int gelic_net_get_settings(struct net_device *netdev,
- struct ethtool_cmd *cmd)
+static int gelic_ether_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *cmd)
{
- struct gelic_net_card *card = netdev_priv(netdev);
- int status;
- u64 v1, v2;
- int speed, duplex;
+ struct gelic_card *card = netdev_card(netdev);
- speed = duplex = -1;
- status = lv1_net_control(bus_id(card), dev_id(card),
- GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
- &v1, &v2);
- if (status) {
- /* link down */
- } else {
- if (v1 & GELIC_NET_FULL_DUPLEX) {
- duplex = DUPLEX_FULL;
- } else {
- duplex = DUPLEX_HALF;
- }
+ gelic_card_get_ether_port_status(card, 0);
- if (v1 & GELIC_NET_SPEED_10 ) {
- speed = SPEED_10;
- } else if (v1 & GELIC_NET_SPEED_100) {
- speed = SPEED_100;
- } else if (v1 & GELIC_NET_SPEED_1000) {
- speed = SPEED_1000;
- }
+ if (card->ether_port_status & GELIC_LV1_ETHER_FULL_DUPLEX)
+ cmd->duplex = DUPLEX_FULL;
+ else
+ cmd->duplex = DUPLEX_HALF;
+
+ switch (card->ether_port_status & GELIC_LV1_ETHER_SPEED_MASK) {
+ case GELIC_LV1_ETHER_SPEED_10:
+ cmd->speed = SPEED_10;
+ break;
+ case GELIC_LV1_ETHER_SPEED_100:
+ cmd->speed = SPEED_100;
+ break;
+ case GELIC_LV1_ETHER_SPEED_1000:
+ cmd->speed = SPEED_1000;
+ break;
+ default:
+ pr_info("%s: speed unknown\n", __func__);
+ cmd->speed = SPEED_10;
+ break;
}
+
cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
cmd->advertising = cmd->supported;
- cmd->speed = speed;
- cmd->duplex = duplex;
cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
cmd->port = PORT_TP;
return 0;
}
-static u32 gelic_net_get_link(struct net_device *netdev)
+u32 gelic_net_get_rx_csum(struct net_device *netdev)
{
- struct gelic_net_card *card = netdev_priv(netdev);
- int status;
- u64 v1, v2;
- int link;
-
- status = lv1_net_control(bus_id(card), dev_id(card),
- GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
- &v1, &v2);
- if (status)
- return 0; /* link down */
-
- if (v1 & GELIC_NET_LINK_UP)
- link = 1;
- else
- link = 0;
-
- return link;
-}
-
-static int gelic_net_nway_reset(struct net_device *netdev)
-{
- if (netif_running(netdev)) {
- gelic_net_stop(netdev);
- gelic_net_open(netdev);
- }
- return 0;
-}
-
-static u32 gelic_net_get_tx_csum(struct net_device *netdev)
-{
- return (netdev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-static int gelic_net_set_tx_csum(struct net_device *netdev, u32 data)
-{
- if (data)
- netdev->features |= NETIF_F_IP_CSUM;
- else
- netdev->features &= ~NETIF_F_IP_CSUM;
-
- return 0;
-}
-
-static u32 gelic_net_get_rx_csum(struct net_device *netdev)
-{
- struct gelic_net_card *card = netdev_priv(netdev);
+ struct gelic_card *card = netdev_card(netdev);
return card->rx_csum;
}
-static int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
+int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
{
- struct gelic_net_card *card = netdev_priv(netdev);
+ struct gelic_card *card = netdev_card(netdev);
card->rx_csum = data;
return 0;
}
-static struct ethtool_ops gelic_net_ethtool_ops = {
+static struct ethtool_ops gelic_ether_ethtool_ops = {
.get_drvinfo = gelic_net_get_drvinfo,
- .get_settings = gelic_net_get_settings,
- .get_link = gelic_net_get_link,
- .nway_reset = gelic_net_nway_reset,
- .get_tx_csum = gelic_net_get_tx_csum,
- .set_tx_csum = gelic_net_set_tx_csum,
+ .get_settings = gelic_ether_get_settings,
+ .get_link = ethtool_op_get_link,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
.get_rx_csum = gelic_net_get_rx_csum,
.set_rx_csum = gelic_net_set_rx_csum,
};
@@ -1277,9 +1285,9 @@ static struct ethtool_ops gelic_net_ethtool_ops = {
*/
static void gelic_net_tx_timeout_task(struct work_struct *work)
{
- struct gelic_net_card *card =
- container_of(work, struct gelic_net_card, tx_timeout_task);
- struct net_device *netdev = card->netdev;
+ struct gelic_card *card =
+ container_of(work, struct gelic_card, tx_timeout_task);
+ struct net_device *netdev = card->netdev[GELIC_PORT_ETHERNET];
dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__);
@@ -1302,11 +1310,11 @@ out:
*
* called, if tx hangs. Schedules a task that resets the interface
*/
-static void gelic_net_tx_timeout(struct net_device *netdev)
+void gelic_net_tx_timeout(struct net_device *netdev)
{
- struct gelic_net_card *card;
+ struct gelic_card *card;
- card = netdev_priv(netdev);
+ card = netdev_card(netdev);
atomic_inc(&card->tx_timeout_task_counter);
if (netdev->flags & IFF_UP)
schedule_work(&card->tx_timeout_task);
@@ -1315,12 +1323,13 @@ static void gelic_net_tx_timeout(struct net_device *netdev)
}
/**
- * gelic_net_setup_netdev_ops - initialization of net_device operations
+ * gelic_ether_setup_netdev_ops - initialization of net_device operations
* @netdev: net_device structure
*
* fills out function pointers in the net_device structure
*/
-static void gelic_net_setup_netdev_ops(struct net_device *netdev)
+static void gelic_ether_setup_netdev_ops(struct net_device *netdev,
+ struct napi_struct *napi)
{
netdev->open = &gelic_net_open;
netdev->stop = &gelic_net_stop;
@@ -1330,163 +1339,239 @@ static void gelic_net_setup_netdev_ops(struct net_device *netdev)
/* tx watchdog */
netdev->tx_timeout = &gelic_net_tx_timeout;
netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
- netdev->ethtool_ops = &gelic_net_ethtool_ops;
+ /* NAPI */
+ netif_napi_add(netdev, napi,
+ gelic_net_poll, GELIC_NET_NAPI_WEIGHT);
+ netdev->ethtool_ops = &gelic_ether_ethtool_ops;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ netdev->poll_controller = gelic_net_poll_controller;
+#endif
}
/**
- * gelic_net_setup_netdev - initialization of net_device
+ * gelic_ether_setup_netdev - initialization of net_device
+ * @netdev: net_device structure
* @card: card structure
*
* Returns 0 on success or <0 on failure
*
- * gelic_net_setup_netdev initializes the net_device structure
+ * gelic_ether_setup_netdev initializes the net_device structure
+ * and register it.
**/
-static int gelic_net_setup_netdev(struct gelic_net_card *card)
+int gelic_net_setup_netdev(struct net_device *netdev, struct gelic_card *card)
{
- struct net_device *netdev = card->netdev;
- struct sockaddr addr;
- unsigned int i;
int status;
u64 v1, v2;
DECLARE_MAC_BUF(mac);
- SET_NETDEV_DEV(netdev, &card->dev->core);
- spin_lock_init(&card->tx_dma_lock);
-
- card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT;
-
- gelic_net_setup_netdev_ops(netdev);
-
- netif_napi_add(netdev, &card->napi,
- gelic_net_poll, GELIC_NET_NAPI_WEIGHT);
-
netdev->features = NETIF_F_IP_CSUM;
status = lv1_net_control(bus_id(card), dev_id(card),
- GELIC_NET_GET_MAC_ADDRESS,
+ GELIC_LV1_GET_MAC_ADDRESS,
0, 0, 0, &v1, &v2);
+ v1 <<= 16;
if (status || !is_valid_ether_addr((u8 *)&v1)) {
dev_info(ctodev(card),
"%s:lv1_net_control GET_MAC_ADDR failed %d\n",
__func__, status);
return -EINVAL;
}
- v1 <<= 16;
- memcpy(addr.sa_data, &v1, ETH_ALEN);
- memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN);
- dev_info(ctodev(card), "MAC addr %s\n",
- print_mac(mac, netdev->dev_addr));
+ memcpy(netdev->dev_addr, &v1, ETH_ALEN);
- card->vlan_index = -1; /* no vlan */
- for (i = 0; i < GELIC_NET_VLAN_MAX; i++) {
- status = lv1_net_control(bus_id(card), dev_id(card),
- GELIC_NET_GET_VLAN_ID,
- i + 1, /* index; one based */
- 0, 0, &v1, &v2);
- if (status == GELIC_NET_VLAN_NO_ENTRY) {
- dev_dbg(ctodev(card),
- "GELIC_VLAN_ID no entry:%d, VLAN disabled\n",
- status);
- card->vlan_id[i] = 0;
- } else if (status) {
- dev_dbg(ctodev(card),
- "%s:GELIC_NET_VLAN_ID faild, status=%d\n",
- __func__, status);
- card->vlan_id[i] = 0;
- } else {
- card->vlan_id[i] = (u32)v1;
- dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1);
- }
- }
-
- if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1]) {
- card->vlan_index = GELIC_NET_VLAN_WIRED - 1;
+ if (card->vlan_required) {
netdev->hard_header_len += VLAN_HLEN;
+ /*
+ * As vlan is internally used,
+ * we can not receive vlan packets
+ */
+ netdev->features |= NETIF_F_VLAN_CHALLENGED;
}
status = register_netdev(netdev);
if (status) {
- dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n",
- __func__, status);
+ dev_err(ctodev(card), "%s:Couldn't register %s %d\n",
+ __func__, netdev->name, status);
return status;
}
+ dev_info(ctodev(card), "%s: MAC addr %s\n",
+ netdev->name,
+ print_mac(mac, netdev->dev_addr));
return 0;
}
/**
- * gelic_net_alloc_card - allocates net_device and card structure
+ * gelic_alloc_card_net - allocates net_device and card structure
*
* returns the card structure or NULL in case of errors
*
* the card and net_device structures are linked to each other
*/
-static struct gelic_net_card *gelic_net_alloc_card(void)
+#define GELIC_ALIGN (32)
+static struct gelic_card *gelic_alloc_card_net(struct net_device **netdev)
{
- struct net_device *netdev;
- struct gelic_net_card *card;
+ struct gelic_card *card;
+ struct gelic_port *port;
+ void *p;
size_t alloc_size;
-
- alloc_size = sizeof (*card) +
- sizeof (struct gelic_net_descr) * GELIC_NET_RX_DESCRIPTORS +
- sizeof (struct gelic_net_descr) * GELIC_NET_TX_DESCRIPTORS;
/*
- * we assume private data is allocated 32 bytes (or more) aligned
- * so that gelic_net_descr should be 32 bytes aligned.
- * Current alloc_etherdev() does do it because NETDEV_ALIGN
- * is 32.
- * check this assumption here.
+ * gelic requires dma descriptor is 32 bytes aligned and
+ * the hypervisor requires irq_status is 8 bytes aligned.
*/
- BUILD_BUG_ON(NETDEV_ALIGN < 32);
- BUILD_BUG_ON(offsetof(struct gelic_net_card, irq_status) % 8);
- BUILD_BUG_ON(offsetof(struct gelic_net_card, descr) % 32);
+ BUILD_BUG_ON(offsetof(struct gelic_card, irq_status) % 8);
+ BUILD_BUG_ON(offsetof(struct gelic_card, descr) % 32);
+ alloc_size =
+ sizeof(struct gelic_card) +
+ sizeof(struct gelic_descr) * GELIC_NET_RX_DESCRIPTORS +
+ sizeof(struct gelic_descr) * GELIC_NET_TX_DESCRIPTORS +
+ GELIC_ALIGN - 1;
+
+ p = kzalloc(alloc_size, GFP_KERNEL);
+ if (!p)
+ return NULL;
+ card = PTR_ALIGN(p, GELIC_ALIGN);
+ card->unalign = p;
- netdev = alloc_etherdev(alloc_size);
- if (!netdev)
+ /*
+ * alloc netdev
+ */
+ *netdev = alloc_etherdev(sizeof(struct gelic_port));
+ if (!netdev) {
+ kfree(card->unalign);
return NULL;
+ }
+ port = netdev_priv(*netdev);
+
+ /* gelic_port */
+ port->netdev = *netdev;
+ port->card = card;
+ port->type = GELIC_PORT_ETHERNET;
+
+ /* gelic_card */
+ card->netdev[GELIC_PORT_ETHERNET] = *netdev;
- card = netdev_priv(netdev);
- card->netdev = netdev;
INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
init_waitqueue_head(&card->waitq);
atomic_set(&card->tx_timeout_task_counter, 0);
+ init_MUTEX(&card->updown_lock);
+ atomic_set(&card->users, 0);
return card;
}
+static void gelic_card_get_vlan_info(struct gelic_card *card)
+{
+ u64 v1, v2;
+ int status;
+ unsigned int i;
+ struct {
+ int tx;
+ int rx;
+ } vlan_id_ix[2] = {
+ [GELIC_PORT_ETHERNET] = {
+ .tx = GELIC_LV1_VLAN_TX_ETHERNET,
+ .rx = GELIC_LV1_VLAN_RX_ETHERNET
+ },
+ [GELIC_PORT_WIRELESS] = {
+ .tx = GELIC_LV1_VLAN_TX_WIRELESS,
+ .rx = GELIC_LV1_VLAN_RX_WIRELESS
+ }
+ };
+
+ for (i = 0; i < ARRAY_SIZE(vlan_id_ix); i++) {
+ /* tx tag */
+ status = lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_LV1_GET_VLAN_ID,
+ vlan_id_ix[i].tx,
+ 0, 0, &v1, &v2);
+ if (status || !v1) {
+ if (status != LV1_NO_ENTRY)
+ dev_dbg(ctodev(card),
+ "get vlan id for tx(%d) failed(%d)\n",
+ vlan_id_ix[i].tx, status);
+ card->vlan[i].tx = 0;
+ card->vlan[i].rx = 0;
+ continue;
+ }
+ card->vlan[i].tx = (u16)v1;
+
+ /* rx tag */
+ status = lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_LV1_GET_VLAN_ID,
+ vlan_id_ix[i].rx,
+ 0, 0, &v1, &v2);
+ if (status || !v1) {
+ if (status != LV1_NO_ENTRY)
+ dev_info(ctodev(card),
+ "get vlan id for rx(%d) failed(%d)\n",
+ vlan_id_ix[i].rx, status);
+ card->vlan[i].tx = 0;
+ card->vlan[i].rx = 0;
+ continue;
+ }
+ card->vlan[i].rx = (u16)v1;
+
+ dev_dbg(ctodev(card), "vlan_id[%d] tx=%02x rx=%02x\n",
+ i, card->vlan[i].tx, card->vlan[i].rx);
+ }
+
+ if (card->vlan[GELIC_PORT_ETHERNET].tx) {
+ BUG_ON(!card->vlan[GELIC_PORT_WIRELESS].tx);
+ card->vlan_required = 1;
+ } else
+ card->vlan_required = 0;
+
+ /* check wirelss capable firmware */
+ if (ps3_compare_firmware_version(1, 6, 0) < 0) {
+ card->vlan[GELIC_PORT_WIRELESS].tx = 0;
+ card->vlan[GELIC_PORT_WIRELESS].rx = 0;
+ }
+
+ dev_info(ctodev(card), "internal vlan %s\n",
+ card->vlan_required? "enabled" : "disabled");
+}
/**
* ps3_gelic_driver_probe - add a device to the control of this driver
*/
-static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
+static int ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
{
- struct gelic_net_card *card = gelic_net_alloc_card();
+ struct gelic_card *card;
+ struct net_device *netdev;
int result;
- if (!card) {
- dev_info(&dev->core, "gelic_net_alloc_card failed\n");
- result = -ENOMEM;
- goto fail_alloc_card;
- }
-
- ps3_system_bus_set_driver_data(dev, card);
- card->dev = dev;
-
+ pr_debug("%s: called\n", __func__);
result = ps3_open_hv_device(dev);
if (result) {
- dev_dbg(&dev->core, "ps3_open_hv_device failed\n");
+ dev_dbg(&dev->core, "%s:ps3_open_hv_device failed\n",
+ __func__);
goto fail_open;
}
result = ps3_dma_region_create(dev->d_region);
if (result) {
- dev_dbg(&dev->core, "ps3_dma_region_create failed(%d)\n",
- result);
+ dev_dbg(&dev->core, "%s:ps3_dma_region_create failed(%d)\n",
+ __func__, result);
BUG_ON("check region type");
goto fail_dma_region;
}
+ /* alloc card/netdevice */
+ card = gelic_alloc_card_net(&netdev);
+ if (!card) {
+ dev_info(&dev->core, "%s:gelic_net_alloc_card failed\n",
+ __func__);
+ result = -ENOMEM;
+ goto fail_alloc_card;
+ }
+ ps3_system_bus_set_driver_data(dev, card);
+ card->dev = dev;
+
+ /* get internal vlan info */
+ gelic_card_get_vlan_info(card);
+
+ /* setup interrupt */
result = lv1_net_set_interrupt_status_indicator(bus_id(card),
dev_id(card),
ps3_mm_phys_to_lpar(__pa(&card->irq_status)),
@@ -1494,34 +1579,101 @@ static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
if (result) {
dev_dbg(&dev->core,
- "lv1_net_set_interrupt_status_indicator failed: %s\n",
- ps3_result(result));
+ "%s:set_interrupt_status_indicator failed: %s\n",
+ __func__, ps3_result(result));
result = -EIO;
goto fail_status_indicator;
}
- result = gelic_net_setup_netdev(card);
+ result = ps3_sb_event_receive_port_setup(dev, PS3_BINDING_CPU_ANY,
+ &card->irq);
+
+ if (result) {
+ dev_info(ctodev(card),
+ "%s:gelic_net_open_device failed (%d)\n",
+ __func__, result);
+ result = -EPERM;
+ goto fail_alloc_irq;
+ }
+ result = request_irq(card->irq, gelic_card_interrupt,
+ IRQF_DISABLED, netdev->name, card);
+
+ if (result) {
+ dev_info(ctodev(card), "%s:request_irq failed (%d)\n",
+ __func__, result);
+ goto fail_request_irq;
+ }
+
+ /* setup card structure */
+ card->irq_mask = GELIC_CARD_RXINT | GELIC_CARD_TXINT |
+ GELIC_CARD_PORT_STATUS_CHANGED;
+ card->rx_csum = GELIC_CARD_RX_CSUM_DEFAULT;
+
+ if (gelic_card_init_chain(card, &card->tx_chain,
+ card->descr, GELIC_NET_TX_DESCRIPTORS))
+ goto fail_alloc_tx;
+ if (gelic_card_init_chain(card, &card->rx_chain,
+ card->descr + GELIC_NET_TX_DESCRIPTORS,
+ GELIC_NET_RX_DESCRIPTORS))
+ goto fail_alloc_rx;
+
+ /* head of chain */
+ card->tx_top = card->tx_chain.head;
+ card->rx_top = card->rx_chain.head;
+ dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n",
+ card->rx_top, card->tx_top, sizeof(struct gelic_descr),
+ GELIC_NET_RX_DESCRIPTORS);
+ /* allocate rx skbs */
+ if (gelic_card_alloc_rx_skbs(card))
+ goto fail_alloc_skbs;
+
+ spin_lock_init(&card->tx_lock);
+ card->tx_dma_progress = 0;
+
+ /* setup net_device structure */
+ netdev->irq = card->irq;
+ SET_NETDEV_DEV(netdev, &card->dev->core);
+ gelic_ether_setup_netdev_ops(netdev, &card->napi);
+ result = gelic_net_setup_netdev(netdev, card);
if (result) {
- dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
- "(%d)\n", __func__, __LINE__, result);
+ dev_dbg(&dev->core, "%s: setup_netdev failed %d",
+ __func__, result);
goto fail_setup_netdev;
}
+#ifdef CONFIG_GELIC_WIRELESS
+ if (gelic_wl_driver_probe(card)) {
+ dev_dbg(&dev->core, "%s: WL init failed\n", __func__);
+ goto fail_setup_netdev;
+ }
+#endif
+ pr_debug("%s: done\n", __func__);
return 0;
fail_setup_netdev:
+fail_alloc_skbs:
+ gelic_card_free_chain(card, card->rx_chain.head);
+fail_alloc_rx:
+ gelic_card_free_chain(card, card->tx_chain.head);
+fail_alloc_tx:
+ free_irq(card->irq, card);
+ netdev->irq = NO_IRQ;
+fail_request_irq:
+ ps3_sb_event_receive_port_destroy(dev, card->irq);
+fail_alloc_irq:
lv1_net_set_interrupt_status_indicator(bus_id(card),
bus_id(card),
- 0 , 0);
+ 0, 0);
fail_status_indicator:
+ ps3_system_bus_set_driver_data(dev, NULL);
+ kfree(netdev_card(netdev)->unalign);
+ free_netdev(netdev);
+fail_alloc_card:
ps3_dma_region_free(dev->d_region);
fail_dma_region:
ps3_close_hv_device(dev);
fail_open:
- ps3_system_bus_set_driver_data(dev, NULL);
- free_netdev(card->netdev);
-fail_alloc_card:
return result;
}
@@ -1529,9 +1681,34 @@ fail_alloc_card:
* ps3_gelic_driver_remove - remove a device from the control of this driver
*/
-static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
+static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev)
{
- struct gelic_net_card *card = ps3_system_bus_get_driver_data(dev);
+ struct gelic_card *card = ps3_system_bus_get_driver_data(dev);
+ struct net_device *netdev0;
+ pr_debug("%s: called\n", __func__);
+
+#ifdef CONFIG_GELIC_WIRELESS
+ gelic_wl_driver_remove(card);
+#endif
+ /* stop interrupt */
+ gelic_card_set_irq_mask(card, 0);
+
+ /* turn off DMA, force end */
+ gelic_card_disable_rxdmac(card);
+ gelic_card_disable_txdmac(card);
+
+ /* release chains */
+ gelic_card_release_tx_chain(card, 1);
+ gelic_card_release_rx_chain(card);
+
+ gelic_card_free_chain(card, card->tx_top);
+ gelic_card_free_chain(card, card->rx_top);
+
+ netdev0 = card->netdev[GELIC_PORT_ETHERNET];
+ /* disconnect event port */
+ free_irq(card->irq, card);
+ netdev0->irq = NO_IRQ;
+ ps3_sb_event_receive_port_destroy(card->dev, card->irq);
wait_event(card->waitq,
atomic_read(&card->tx_timeout_task_counter) == 0);
@@ -1539,8 +1716,9 @@ static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card),
0 , 0);
- unregister_netdev(card->netdev);
- free_netdev(card->netdev);
+ unregister_netdev(netdev0);
+ kfree(netdev_card(netdev0)->unalign);
+ free_netdev(netdev0);
ps3_system_bus_set_driver_data(dev, NULL);
@@ -1548,6 +1726,7 @@ static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
ps3_close_hv_device(dev);
+ pr_debug("%s: done\n", __func__);
return 0;
}
@@ -1572,8 +1751,8 @@ static void __exit ps3_gelic_driver_exit (void)
ps3_system_bus_driver_unregister(&ps3_gelic_driver);
}
-module_init (ps3_gelic_driver_init);
-module_exit (ps3_gelic_driver_exit);
+module_init(ps3_gelic_driver_init);
+module_exit(ps3_gelic_driver_exit);
MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC);
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
index 968560269a3..1d39d06797e 100644
--- a/drivers/net/ps3_gelic_net.h
+++ b/drivers/net/ps3_gelic_net.h
@@ -35,198 +35,323 @@
#define GELIC_NET_MAX_MTU VLAN_ETH_FRAME_LEN
#define GELIC_NET_MIN_MTU VLAN_ETH_ZLEN
#define GELIC_NET_RXBUF_ALIGN 128
-#define GELIC_NET_RX_CSUM_DEFAULT 1 /* hw chksum */
+#define GELIC_CARD_RX_CSUM_DEFAULT 1 /* hw chksum */
#define GELIC_NET_WATCHDOG_TIMEOUT 5*HZ
#define GELIC_NET_NAPI_WEIGHT (GELIC_NET_RX_DESCRIPTORS)
#define GELIC_NET_BROADCAST_ADDR 0xffffffffffffL
-#define GELIC_NET_VLAN_POS (VLAN_ETH_ALEN * 2)
-#define GELIC_NET_VLAN_MAX 4
+
#define GELIC_NET_MC_COUNT_MAX 32 /* multicast address list */
-enum gelic_net_int0_status {
- GELIC_NET_GDTDCEINT = 24,
- GELIC_NET_GRFANMINT = 28,
-};
+/* virtual interrupt status register bits */
+ /* INT1 */
+#define GELIC_CARD_TX_RAM_FULL_ERR 0x0000000000000001L
+#define GELIC_CARD_RX_RAM_FULL_ERR 0x0000000000000002L
+#define GELIC_CARD_TX_SHORT_FRAME_ERR 0x0000000000000004L
+#define GELIC_CARD_TX_INVALID_DESCR_ERR 0x0000000000000008L
+#define GELIC_CARD_RX_FIFO_FULL_ERR 0x0000000000002000L
+#define GELIC_CARD_RX_DESCR_CHAIN_END 0x0000000000004000L
+#define GELIC_CARD_RX_INVALID_DESCR_ERR 0x0000000000008000L
+#define GELIC_CARD_TX_RESPONCE_ERR 0x0000000000010000L
+#define GELIC_CARD_RX_RESPONCE_ERR 0x0000000000100000L
+#define GELIC_CARD_TX_PROTECTION_ERR 0x0000000000400000L
+#define GELIC_CARD_RX_PROTECTION_ERR 0x0000000004000000L
+#define GELIC_CARD_TX_TCP_UDP_CHECKSUM_ERR 0x0000000008000000L
+#define GELIC_CARD_PORT_STATUS_CHANGED 0x0000000020000000L
+#define GELIC_CARD_WLAN_EVENT_RECEIVED 0x0000000040000000L
+#define GELIC_CARD_WLAN_COMMAND_COMPLETED 0x0000000080000000L
+ /* INT 0 */
+#define GELIC_CARD_TX_FLAGGED_DESCR 0x0004000000000000L
+#define GELIC_CARD_RX_FLAGGED_DESCR 0x0040000000000000L
+#define GELIC_CARD_TX_TRANSFER_END 0x0080000000000000L
+#define GELIC_CARD_TX_DESCR_CHAIN_END 0x0100000000000000L
+#define GELIC_CARD_NUMBER_OF_RX_FRAME 0x1000000000000000L
+#define GELIC_CARD_ONE_TIME_COUNT_TIMER 0x4000000000000000L
+#define GELIC_CARD_FREE_RUN_COUNT_TIMER 0x8000000000000000L
+
+/* initial interrupt mask */
+#define GELIC_CARD_TXINT GELIC_CARD_TX_DESCR_CHAIN_END
-/* GHIINT1STS bits */
-enum gelic_net_int1_status {
- GELIC_NET_GDADCEINT = 14,
+#define GELIC_CARD_RXINT (GELIC_CARD_RX_DESCR_CHAIN_END | \
+ GELIC_CARD_NUMBER_OF_RX_FRAME)
+
+ /* RX descriptor data_status bits */
+enum gelic_descr_rx_status {
+ GELIC_DESCR_RXDMADU = 0x80000000, /* destination MAC addr unknown */
+ GELIC_DESCR_RXLSTFBF = 0x40000000, /* last frame buffer */
+ GELIC_DESCR_RXIPCHK = 0x20000000, /* IP checksum performed */
+ GELIC_DESCR_RXTCPCHK = 0x10000000, /* TCP/UDP checksup performed */
+ GELIC_DESCR_RXWTPKT = 0x00C00000, /*
+ * wakeup trigger packet
+ * 01: Magic Packet (TM)
+ * 10: ARP packet
+ * 11: Multicast MAC addr
+ */
+ GELIC_DESCR_RXVLNPKT = 0x00200000, /* VLAN packet */
+ /* bit 20..16 reserved */
+ GELIC_DESCR_RXRRECNUM = 0x0000ff00, /* reception receipt number */
+ /* bit 7..0 reserved */
};
-/* interrupt mask */
-#define GELIC_NET_TXINT (1L << (GELIC_NET_GDTDCEINT + 32))
+#define GELIC_DESCR_DATA_STATUS_CHK_MASK \
+ (GELIC_DESCR_RXIPCHK | GELIC_DESCR_RXTCPCHK)
-#define GELIC_NET_RXINT0 (1L << (GELIC_NET_GRFANMINT + 32))
-#define GELIC_NET_RXINT1 (1L << GELIC_NET_GDADCEINT)
-#define GELIC_NET_RXINT (GELIC_NET_RXINT0 | GELIC_NET_RXINT1)
+ /* TX descriptor data_status bits */
+enum gelic_descr_tx_status {
+ GELIC_DESCR_TX_TAIL = 0x00000001, /* gelic treated this
+ * descriptor was end of
+ * a tx frame
+ */
+};
- /* RX descriptor data_status bits */
-#define GELIC_NET_RXDMADU 0x80000000 /* destination MAC addr unknown */
-#define GELIC_NET_RXLSTFBF 0x40000000 /* last frame buffer */
-#define GELIC_NET_RXIPCHK 0x20000000 /* IP checksum performed */
-#define GELIC_NET_RXTCPCHK 0x10000000 /* TCP/UDP checksup performed */
-#define GELIC_NET_RXIPSPKT 0x08000000 /* IPsec packet */
-#define GELIC_NET_RXIPSAHPRT 0x04000000 /* IPsec AH protocol performed */
-#define GELIC_NET_RXIPSESPPRT 0x02000000 /* IPsec ESP protocol performed */
-#define GELIC_NET_RXSESPAH 0x01000000 /*
- * IPsec ESP protocol auth
- * performed
- */
-
-#define GELIC_NET_RXWTPKT 0x00C00000 /*
- * wakeup trigger packet
- * 01: Magic Packet (TM)
- * 10: ARP packet
- * 11: Multicast MAC addr
- */
-#define GELIC_NET_RXVLNPKT 0x00200000 /* VLAN packet */
-/* bit 20..16 reserved */
-#define GELIC_NET_RXRRECNUM 0x0000ff00 /* reception receipt number */
-#define GELIC_NET_RXRRECNUM_SHIFT 8
-/* bit 7..0 reserved */
-
-#define GELIC_NET_TXDESC_TAIL 0
-#define GELIC_NET_DATA_STATUS_CHK_MASK (GELIC_NET_RXIPCHK | GELIC_NET_RXTCPCHK)
-
-/* RX descriptor data_error bits */
-/* bit 31 reserved */
-#define GELIC_NET_RXALNERR 0x40000000 /* alignement error 10/100M */
-#define GELIC_NET_RXOVERERR 0x20000000 /* oversize error */
-#define GELIC_NET_RXRNTERR 0x10000000 /* Runt error */
-#define GELIC_NET_RXIPCHKERR 0x08000000 /* IP checksum error */
-#define GELIC_NET_RXTCPCHKERR 0x04000000 /* TCP/UDP checksum error */
-#define GELIC_NET_RXUMCHSP 0x02000000 /* unmatched sp on sp */
-#define GELIC_NET_RXUMCHSPI 0x01000000 /* unmatched SPI on SAD */
-#define GELIC_NET_RXUMCHSAD 0x00800000 /* unmatched SAD */
-#define GELIC_NET_RXIPSAHERR 0x00400000 /* auth error on AH protocol
- * processing */
-#define GELIC_NET_RXIPSESPAHERR 0x00200000 /* auth error on ESP protocol
- * processing */
-#define GELIC_NET_RXDRPPKT 0x00100000 /* drop packet */
-#define GELIC_NET_RXIPFMTERR 0x00080000 /* IP packet format error */
-/* bit 18 reserved */
-#define GELIC_NET_RXDATAERR 0x00020000 /* IP packet format error */
-#define GELIC_NET_RXCALERR 0x00010000 /* cariier extension length
- * error */
-#define GELIC_NET_RXCREXERR 0x00008000 /* carrier extention error */
-#define GELIC_NET_RXMLTCST 0x00004000 /* multicast address frame */
-/* bit 13..0 reserved */
-#define GELIC_NET_DATA_ERROR_CHK_MASK \
- (GELIC_NET_RXIPCHKERR | GELIC_NET_RXTCPCHKERR)
+/* RX descriptor data error bits */
+enum gelic_descr_rx_error {
+ /* bit 31 reserved */
+ GELIC_DESCR_RXALNERR = 0x40000000, /* alignement error 10/100M */
+ GELIC_DESCR_RXOVERERR = 0x20000000, /* oversize error */
+ GELIC_DESCR_RXRNTERR = 0x10000000, /* Runt error */
+ GELIC_DESCR_RXIPCHKERR = 0x08000000, /* IP checksum error */
+ GELIC_DESCR_RXTCPCHKERR = 0x04000000, /* TCP/UDP checksum error */
+ GELIC_DESCR_RXDRPPKT = 0x00100000, /* drop packet */
+ GELIC_DESCR_RXIPFMTERR = 0x00080000, /* IP packet format error */
+ /* bit 18 reserved */
+ GELIC_DESCR_RXDATAERR = 0x00020000, /* IP packet format error */
+ GELIC_DESCR_RXCALERR = 0x00010000, /* cariier extension length
+ * error */
+ GELIC_DESCR_RXCREXERR = 0x00008000, /* carrier extention error */
+ GELIC_DESCR_RXMLTCST = 0x00004000, /* multicast address frame */
+ /* bit 13..0 reserved */
+};
+#define GELIC_DESCR_DATA_ERROR_CHK_MASK \
+ (GELIC_DESCR_RXIPCHKERR | GELIC_DESCR_RXTCPCHKERR)
+/* DMA command and status (RX and TX)*/
+enum gelic_descr_dma_status {
+ GELIC_DESCR_DMA_COMPLETE = 0x00000000, /* used in tx */
+ GELIC_DESCR_DMA_BUFFER_FULL = 0x00000000, /* used in rx */
+ GELIC_DESCR_DMA_RESPONSE_ERROR = 0x10000000, /* used in rx, tx */
+ GELIC_DESCR_DMA_PROTECTION_ERROR = 0x20000000, /* used in rx, tx */
+ GELIC_DESCR_DMA_FRAME_END = 0x40000000, /* used in rx */
+ GELIC_DESCR_DMA_FORCE_END = 0x50000000, /* used in rx, tx */
+ GELIC_DESCR_DMA_CARDOWNED = 0xa0000000, /* used in rx, tx */
+ GELIC_DESCR_DMA_NOT_IN_USE = 0xb0000000, /* any other value */
+};
+
+#define GELIC_DESCR_DMA_STAT_MASK (0xf0000000)
/* tx descriptor command and status */
-#define GELIC_NET_DMAC_CMDSTAT_NOCS 0xa0080000 /* middle of frame */
-#define GELIC_NET_DMAC_CMDSTAT_TCPCS 0xa00a0000
-#define GELIC_NET_DMAC_CMDSTAT_UDPCS 0xa00b0000
-#define GELIC_NET_DMAC_CMDSTAT_END_FRAME 0x00040000 /* end of frame */
-
-#define GELIC_NET_DMAC_CMDSTAT_RXDCEIS 0x00000002 /* descriptor chain end
- * interrupt status */
-
-#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END 0x00000002 /* RXDCEIS:DMA stopped */
-#define GELIC_NET_DESCR_IND_PROC_SHIFT 28
-#define GELIC_NET_DESCR_IND_PROC_MASKO 0x0fffffff
-
-
-enum gelic_net_descr_status {
- GELIC_NET_DESCR_COMPLETE = 0x00, /* used in tx */
- GELIC_NET_DESCR_BUFFER_FULL = 0x00, /* used in rx */
- GELIC_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */
- GELIC_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */
- GELIC_NET_DESCR_FRAME_END = 0x04, /* used in rx */
- GELIC_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */
- GELIC_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */
- GELIC_NET_DESCR_NOT_IN_USE = 0x0b /* any other value */
+enum gelic_descr_tx_dma_status {
+ /* [19] */
+ GELIC_DESCR_TX_DMA_IKE = 0x00080000, /* IPSEC off */
+ /* [18] */
+ GELIC_DESCR_TX_DMA_FRAME_TAIL = 0x00040000, /* last descriptor of
+ * the packet
+ */
+ /* [17..16] */
+ GELIC_DESCR_TX_DMA_TCP_CHKSUM = 0x00020000, /* TCP packet */
+ GELIC_DESCR_TX_DMA_UDP_CHKSUM = 0x00030000, /* UDP packet */
+ GELIC_DESCR_TX_DMA_NO_CHKSUM = 0x00000000, /* no checksum */
+
+ /* [1] */
+ GELIC_DESCR_TX_DMA_CHAIN_END = 0x00000002, /* DMA terminated
+ * due to chain end
+ */
};
+
+#define GELIC_DESCR_DMA_CMD_NO_CHKSUM \
+ (GELIC_DESCR_DMA_CARDOWNED | GELIC_DESCR_TX_DMA_IKE | \
+ GELIC_DESCR_TX_DMA_NO_CHKSUM)
+
+#define GELIC_DESCR_DMA_CMD_TCP_CHKSUM \
+ (GELIC_DESCR_DMA_CARDOWNED | GELIC_DESCR_TX_DMA_IKE | \
+ GELIC_DESCR_TX_DMA_TCP_CHKSUM)
+
+#define GELIC_DESCR_DMA_CMD_UDP_CHKSUM \
+ (GELIC_DESCR_DMA_CARDOWNED | GELIC_DESCR_TX_DMA_IKE | \
+ GELIC_DESCR_TX_DMA_UDP_CHKSUM)
+
+enum gelic_descr_rx_dma_status {
+ /* [ 1 ] */
+ GELIC_DESCR_RX_DMA_CHAIN_END = 0x00000002, /* DMA terminated
+ * due to chain end
+ */
+};
+
/* for lv1_net_control */
-#define GELIC_NET_GET_MAC_ADDRESS 0x0000000000000001
-#define GELIC_NET_GET_ETH_PORT_STATUS 0x0000000000000002
-#define GELIC_NET_SET_NEGOTIATION_MODE 0x0000000000000003
-#define GELIC_NET_GET_VLAN_ID 0x0000000000000004
-
-#define GELIC_NET_LINK_UP 0x0000000000000001
-#define GELIC_NET_FULL_DUPLEX 0x0000000000000002
-#define GELIC_NET_AUTO_NEG 0x0000000000000004
-#define GELIC_NET_SPEED_10 0x0000000000000010
-#define GELIC_NET_SPEED_100 0x0000000000000020
-#define GELIC_NET_SPEED_1000 0x0000000000000040
-
-#define GELIC_NET_VLAN_ALL 0x0000000000000001
-#define GELIC_NET_VLAN_WIRED 0x0000000000000002
-#define GELIC_NET_VLAN_WIRELESS 0x0000000000000003
-#define GELIC_NET_VLAN_PSP 0x0000000000000004
-#define GELIC_NET_VLAN_PORT0 0x0000000000000010
-#define GELIC_NET_VLAN_PORT1 0x0000000000000011
-#define GELIC_NET_VLAN_PORT2 0x0000000000000012
-#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS 0x0000000000000013
-#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS 0x0000000000000014
-#define GELIC_NET_VLAN_NO_ENTRY -6
-
-#define GELIC_NET_PORT 2 /* for port status */
+enum gelic_lv1_net_control_code {
+ GELIC_LV1_GET_MAC_ADDRESS = 1,
+ GELIC_LV1_GET_ETH_PORT_STATUS = 2,
+ GELIC_LV1_SET_NEGOTIATION_MODE = 3,
+ GELIC_LV1_GET_VLAN_ID = 4,
+ GELIC_LV1_GET_CHANNEL = 6,
+ GELIC_LV1_POST_WLAN_CMD = 9,
+ GELIC_LV1_GET_WLAN_CMD_RESULT = 10,
+ GELIC_LV1_GET_WLAN_EVENT = 11
+};
+
+/* status returened from GET_ETH_PORT_STATUS */
+enum gelic_lv1_ether_port_status {
+ GELIC_LV1_ETHER_LINK_UP = 0x0000000000000001L,
+ GELIC_LV1_ETHER_FULL_DUPLEX = 0x0000000000000002L,
+ GELIC_LV1_ETHER_AUTO_NEG = 0x0000000000000004L,
+
+ GELIC_LV1_ETHER_SPEED_10 = 0x0000000000000010L,
+ GELIC_LV1_ETHER_SPEED_100 = 0x0000000000000020L,
+ GELIC_LV1_ETHER_SPEED_1000 = 0x0000000000000040L,
+ GELIC_LV1_ETHER_SPEED_MASK = 0x0000000000000070L
+};
+
+enum gelic_lv1_vlan_index {
+ /* for outgoing packets */
+ GELIC_LV1_VLAN_TX_ETHERNET = 0x0000000000000002L,
+ GELIC_LV1_VLAN_TX_WIRELESS = 0x0000000000000003L,
+ /* for incoming packets */
+ GELIC_LV1_VLAN_RX_ETHERNET = 0x0000000000000012L,
+ GELIC_LV1_VLAN_RX_WIRELESS = 0x0000000000000013L
+};
/* size of hardware part of gelic descriptor */
-#define GELIC_NET_DESCR_SIZE (32)
-struct gelic_net_descr {
+#define GELIC_DESCR_SIZE (32)
+
+enum gelic_port_type {
+ GELIC_PORT_ETHERNET = 0,
+ GELIC_PORT_WIRELESS = 1,
+ GELIC_PORT_MAX
+};
+
+struct gelic_descr {
/* as defined by the hardware */
- u32 buf_addr;
- u32 buf_size;
- u32 next_descr_addr;
- u32 dmac_cmd_status;
- u32 result_size;
- u32 valid_size; /* all zeroes for tx */
- u32 data_status;
- u32 data_error; /* all zeroes for tx */
+ __be32 buf_addr;
+ __be32 buf_size;
+ __be32 next_descr_addr;
+ __be32 dmac_cmd_status;
+ __be32 result_size;
+ __be32 valid_size; /* all zeroes for tx */
+ __be32 data_status;
+ __be32 data_error; /* all zeroes for tx */
/* used in the driver */
struct sk_buff *skb;
dma_addr_t bus_addr;
- struct gelic_net_descr *next;
- struct gelic_net_descr *prev;
- struct vlan_ethhdr vlan;
+ struct gelic_descr *next;
+ struct gelic_descr *prev;
} __attribute__((aligned(32)));
-struct gelic_net_descr_chain {
+struct gelic_descr_chain {
/* we walk from tail to head */
- struct gelic_net_descr *head;
- struct gelic_net_descr *tail;
+ struct gelic_descr *head;
+ struct gelic_descr *tail;
};
-struct gelic_net_card {
- struct net_device *netdev;
+struct gelic_vlan_id {
+ u16 tx;
+ u16 rx;
+};
+
+struct gelic_card {
struct napi_struct napi;
+ struct net_device *netdev[GELIC_PORT_MAX];
/*
* hypervisor requires irq_status should be
* 8 bytes aligned, but u64 member is
* always disposed in that manner
*/
u64 irq_status;
- u64 ghiintmask;
+ u64 irq_mask;
struct ps3_system_bus_device *dev;
- u32 vlan_id[GELIC_NET_VLAN_MAX];
- int vlan_index;
+ struct gelic_vlan_id vlan[GELIC_PORT_MAX];
+ int vlan_required;
- struct gelic_net_descr_chain tx_chain;
- struct gelic_net_descr_chain rx_chain;
+ struct gelic_descr_chain tx_chain;
+ struct gelic_descr_chain rx_chain;
int rx_dma_restart_required;
- /* gurad dmac descriptor chain*/
- spinlock_t chain_lock;
-
int rx_csum;
- /* guard tx_dma_progress */
- spinlock_t tx_dma_lock;
+ /*
+ * tx_lock guards tx descriptor list and
+ * tx_dma_progress.
+ */
+ spinlock_t tx_lock;
int tx_dma_progress;
struct work_struct tx_timeout_task;
atomic_t tx_timeout_task_counter;
wait_queue_head_t waitq;
- struct gelic_net_descr *tx_top, *rx_top;
- struct gelic_net_descr descr[0];
+ /* only first user should up the card */
+ struct semaphore updown_lock;
+ atomic_t users;
+
+ u64 ether_port_status;
+ /* original address returned by kzalloc */
+ void *unalign;
+
+ /*
+ * each netdevice has copy of irq
+ */
+ unsigned int irq;
+ struct gelic_descr *tx_top, *rx_top;
+ struct gelic_descr descr[0]; /* must be the last */
+};
+
+struct gelic_port {
+ struct gelic_card *card;
+ struct net_device *netdev;
+ enum gelic_port_type type;
+ long priv[0]; /* long for alignment */
};
+static inline struct gelic_card *port_to_card(struct gelic_port *p)
+{
+ return p->card;
+}
+static inline struct net_device *port_to_netdev(struct gelic_port *p)
+{
+ return p->netdev;
+}
+static inline struct gelic_card *netdev_card(struct net_device *d)
+{
+ return ((struct gelic_port *)netdev_priv(d))->card;
+}
+static inline struct gelic_port *netdev_port(struct net_device *d)
+{
+ return (struct gelic_port *)netdev_priv(d);
+}
+static inline struct device *ctodev(struct gelic_card *card)
+{
+ return &card->dev->core;
+}
+static inline u64 bus_id(struct gelic_card *card)
+{
+ return card->dev->bus_id;
+}
+static inline u64 dev_id(struct gelic_card *card)
+{
+ return card->dev->dev_id;
+}
+
+static inline void *port_priv(struct gelic_port *port)
+{
+ return port->priv;
+}
+
+extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask);
+/* shared netdev ops */
+extern void gelic_card_up(struct gelic_card *card);
+extern void gelic_card_down(struct gelic_card *card);
+extern int gelic_net_open(struct net_device *netdev);
+extern int gelic_net_stop(struct net_device *netdev);
+extern int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
+extern void gelic_net_set_multi(struct net_device *netdev);
+extern void gelic_net_tx_timeout(struct net_device *netdev);
+extern int gelic_net_change_mtu(struct net_device *netdev, int new_mtu);
+extern int gelic_net_setup_netdev(struct net_device *netdev,
+ struct gelic_card *card);
-extern unsigned long p_to_lp(long pa);
+/* shared ethtool ops */
+extern void gelic_net_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *info);
+extern u32 gelic_net_get_rx_csum(struct net_device *netdev);
+extern int gelic_net_set_rx_csum(struct net_device *netdev, u32 data);
+extern void gelic_net_poll_controller(struct net_device *netdev);
#endif /* _GELIC_NET_H */
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
new file mode 100644
index 00000000000..daf5abab953
--- /dev/null
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -0,0 +1,2754 @@
+/*
+ * PS3 gelic network driver.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corporation
+ *
+ * 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 published by the Free Software Foundation.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/wireless.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <net/iw_handler.h>
+#include <net/ieee80211.h>
+
+#include <linux/dma-mapping.h>
+#include <net/checksum.h>
+#include <asm/firmware.h>
+#include <asm/ps3.h>
+#include <asm/lv1call.h>
+
+#include "ps3_gelic_net.h"
+#include "ps3_gelic_wireless.h"
+
+
+static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan);
+static int gelic_wl_try_associate(struct net_device *netdev);
+
+/*
+ * tables
+ */
+
+/* 802.11b/g channel to freq in MHz */
+static const int channel_freq[] = {
+ 2412, 2417, 2422, 2427, 2432,
+ 2437, 2442, 2447, 2452, 2457,
+ 2462, 2467, 2472, 2484
+};
+#define NUM_CHANNELS ARRAY_SIZE(channel_freq)
+
+/* in bps */
+static const int bitrate_list[] = {
+ 1000000,
+ 2000000,
+ 5500000,
+ 11000000,
+ 6000000,
+ 9000000,
+ 12000000,
+ 18000000,
+ 24000000,
+ 36000000,
+ 48000000,
+ 54000000
+};
+#define NUM_BITRATES ARRAY_SIZE(bitrate_list)
+
+/*
+ * wpa2 support requires the hypervisor version 2.0 or later
+ */
+static inline int wpa2_capable(void)
+{
+ return (0 <= ps3_compare_firmware_version(2, 0, 0));
+}
+
+static inline int precise_ie(void)
+{
+ return 0; /* FIXME */
+}
+/*
+ * post_eurus_cmd helpers
+ */
+struct eurus_cmd_arg_info {
+ int pre_arg; /* command requres arg1, arg2 at POST COMMAND */
+ int post_arg; /* command requires arg1, arg2 at GET_RESULT */
+};
+
+static const struct eurus_cmd_arg_info cmd_info[GELIC_EURUS_CMD_MAX_INDEX] = {
+ [GELIC_EURUS_CMD_SET_COMMON_CFG] = { .pre_arg = 1},
+ [GELIC_EURUS_CMD_SET_WEP_CFG] = { .pre_arg = 1},
+ [GELIC_EURUS_CMD_SET_WPA_CFG] = { .pre_arg = 1},
+ [GELIC_EURUS_CMD_GET_COMMON_CFG] = { .post_arg = 1},
+ [GELIC_EURUS_CMD_GET_WEP_CFG] = { .post_arg = 1},
+ [GELIC_EURUS_CMD_GET_WPA_CFG] = { .post_arg = 1},
+ [GELIC_EURUS_CMD_GET_RSSI_CFG] = { .post_arg = 1},
+ [GELIC_EURUS_CMD_GET_SCAN] = { .post_arg = 1},
+};
+
+#ifdef DEBUG
+static const char *cmdstr(enum gelic_eurus_command ix)
+{
+ switch (ix) {
+ case GELIC_EURUS_CMD_ASSOC:
+ return "ASSOC";
+ case GELIC_EURUS_CMD_DISASSOC:
+ return "DISASSOC";
+ case GELIC_EURUS_CMD_START_SCAN:
+ return "SCAN";
+ case GELIC_EURUS_CMD_GET_SCAN:
+ return "GET SCAN";
+ case GELIC_EURUS_CMD_SET_COMMON_CFG:
+ return "SET_COMMON_CFG";
+ case GELIC_EURUS_CMD_GET_COMMON_CFG:
+ return "GET_COMMON_CFG";
+ case GELIC_EURUS_CMD_SET_WEP_CFG:
+ return "SET_WEP_CFG";
+ case GELIC_EURUS_CMD_GET_WEP_CFG:
+ return "GET_WEP_CFG";
+ case GELIC_EURUS_CMD_SET_WPA_CFG:
+ return "SET_WPA_CFG";
+ case GELIC_EURUS_CMD_GET_WPA_CFG:
+ return "GET_WPA_CFG";
+ case GELIC_EURUS_CMD_GET_RSSI_CFG:
+ return "GET_RSSI";
+ default:
+ break;
+ }
+ return "";
+};
+#else
+static inline const char *cmdstr(enum gelic_eurus_command ix)
+{
+ return "";
+}
+#endif
+
+/* synchronously do eurus commands */
+static void gelic_eurus_sync_cmd_worker(struct work_struct *work)
+{
+ struct gelic_eurus_cmd *cmd;
+ struct gelic_card *card;
+ struct gelic_wl_info *wl;
+
+ u64 arg1, arg2;
+
+ pr_debug("%s: <-\n", __func__);
+ cmd = container_of(work, struct gelic_eurus_cmd, work);
+ BUG_ON(cmd_info[cmd->cmd].pre_arg &&
+ cmd_info[cmd->cmd].post_arg);
+ wl = cmd->wl;
+ card = port_to_card(wl_port(wl));
+
+ if (cmd_info[cmd->cmd].pre_arg) {
+ arg1 = ps3_mm_phys_to_lpar(__pa(cmd->buffer));
+ arg2 = cmd->buf_size;
+ } else {
+ arg1 = 0;
+ arg2 = 0;
+ }
+ init_completion(&wl->cmd_done_intr);
+ pr_debug("%s: cmd='%s' start\n", __func__, cmdstr(cmd->cmd));
+ cmd->status = lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_LV1_POST_WLAN_CMD,
+ cmd->cmd, arg1, arg2,
+ &cmd->tag, &cmd->size);
+ if (cmd->status) {
+ complete(&cmd->done);
+ pr_info("%s: cmd issue failed\n", __func__);
+ return;
+ }
+
+ wait_for_completion(&wl->cmd_done_intr);
+
+ if (cmd_info[cmd->cmd].post_arg) {
+ arg1 = ps3_mm_phys_to_lpar(__pa(cmd->buffer));
+ arg2 = cmd->buf_size;
+ } else {
+ arg1 = 0;
+ arg2 = 0;
+ }
+
+ cmd->status = lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_LV1_GET_WLAN_CMD_RESULT,
+ cmd->tag, arg1, arg2,
+ &cmd->cmd_status, &cmd->size);
+#ifdef DEBUG
+ if (cmd->status || cmd->cmd_status) {
+ pr_debug("%s: cmd done tag=%#lx arg1=%#lx, arg2=%#lx\n", __func__,
+ cmd->tag, arg1, arg2);
+ pr_debug("%s: cmd done status=%#x cmd_status=%#lx size=%#lx\n",
+ __func__, cmd->status, cmd->cmd_status, cmd->size);
+ }
+#endif
+ complete(&cmd->done);
+ pr_debug("%s: cmd='%s' done\n", __func__, cmdstr(cmd->cmd));
+}
+
+static struct gelic_eurus_cmd *gelic_eurus_sync_cmd(struct gelic_wl_info *wl,
+ unsigned int eurus_cmd,
+ void *buffer,
+ unsigned int buf_size)
+{
+ struct gelic_eurus_cmd *cmd;
+
+ /* allocate cmd */
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (!cmd)
+ return NULL;
+
+ /* initialize members */
+ cmd->cmd = eurus_cmd;
+ cmd->buffer = buffer;
+ cmd->buf_size = buf_size;
+ cmd->wl = wl;
+ INIT_WORK(&cmd->work, gelic_eurus_sync_cmd_worker);
+ init_completion(&cmd->done);
+ queue_work(wl->eurus_cmd_queue, &cmd->work);
+
+ /* wait for command completion */
+ wait_for_completion(&cmd->done);
+
+ return cmd;
+}
+
+static u32 gelic_wl_get_link(struct net_device *netdev)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_port(netdev));
+ u32 ret;
+
+ pr_debug("%s: <-\n", __func__);
+ down(&wl->assoc_stat_lock);
+ if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED)
+ ret = 1;
+ else
+ ret = 0;
+ up(&wl->assoc_stat_lock);
+ pr_debug("%s: ->\n", __func__);
+ return ret;
+}
+
+static void gelic_wl_send_iwap_event(struct gelic_wl_info *wl, u8 *bssid)
+{
+ union iwreq_data data;
+
+ memset(&data, 0, sizeof(data));
+ if (bssid)
+ memcpy(data.ap_addr.sa_data, bssid, ETH_ALEN);
+ data.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(port_to_netdev(wl_port(wl)), SIOCGIWAP,
+ &data, NULL);
+}
+
+/*
+ * wireless extension handlers and helpers
+ */
+
+/* SIOGIWNAME */
+static int gelic_wl_get_name(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *iwreq, char *extra)
+{
+ strcpy(iwreq->name, "IEEE 802.11bg");
+ return 0;
+}
+
+static void gelic_wl_get_ch_info(struct gelic_wl_info *wl)
+{
+ struct gelic_card *card = port_to_card(wl_port(wl));
+ u64 ch_info_raw, tmp;
+ int status;
+
+ if (!test_and_set_bit(GELIC_WL_STAT_CH_INFO, &wl->stat)) {
+ status = lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_LV1_GET_CHANNEL, 0, 0, 0,
+ &ch_info_raw,
+ &tmp);
+ /* some fw versions may return error */
+ if (status) {
+ if (status != LV1_NO_ENTRY)
+ pr_info("%s: available ch unknown\n", __func__);
+ wl->ch_info = 0x07ff;/* 11 ch */
+ } else
+ /* 16 bits of MSB has available channels */
+ wl->ch_info = ch_info_raw >> 48;
+ }
+ return;
+}
+
+/* SIOGIWRANGE */
+static int gelic_wl_get_range(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *iwreq, char *extra)
+{
+ struct iw_point *point = &iwreq->data;
+ struct iw_range *range = (struct iw_range *)extra;
+ struct gelic_wl_info *wl = port_wl(netdev_port(netdev));
+ unsigned int i, chs;
+
+ pr_debug("%s: <-\n", __func__);
+ point->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(struct iw_range));
+
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 22;
+
+ /* available channels and frequencies */
+ gelic_wl_get_ch_info(wl);
+
+ for (i = 0, chs = 0;
+ i < NUM_CHANNELS && chs < IW_MAX_FREQUENCIES; i++)
+ if (wl->ch_info & (1 << i)) {
+ range->freq[chs].i = i + 1;
+ range->freq[chs].m = channel_freq[i];
+ range->freq[chs].e = 6;
+ chs++;
+ }
+ range->num_frequency = chs;
+ range->old_num_frequency = chs;
+ range->num_channels = chs;
+ range->old_num_channels = chs;
+
+ /* bitrates */
+ for (i = 0; i < NUM_BITRATES; i++)
+ range->bitrate[i] = bitrate_list[i];
+ range->num_bitrates = i;
+
+ /* signal levels */
+ range->max_qual.qual = 100; /* relative value */
+ range->max_qual.level = 100;
+ range->avg_qual.qual = 50;
+ range->avg_qual.level = 50;
+ range->sensitivity = 0;
+
+ /* Event capability */
+ IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+
+ /* encryption capability */
+ range->enc_capa = IW_ENC_CAPA_WPA |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+ if (wpa2_capable())
+ range->enc_capa |= IW_ENC_CAPA_WPA2;
+ range->encoding_size[0] = 5; /* 40bit WEP */
+ range->encoding_size[1] = 13; /* 104bit WEP */
+ range->encoding_size[2] = 32; /* WPA-PSK */
+ range->num_encoding_sizes = 3;
+ range->max_encoding_tokens = GELIC_WEP_KEYS;
+
+ pr_debug("%s: ->\n", __func__);
+ return 0;
+
+}
+
+/* SIOC{G,S}IWSCAN */
+static int gelic_wl_set_scan(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+
+ return gelic_wl_start_scan(wl, 1);
+}
+
+#define OUI_LEN 3
+static const u8 rsn_oui[OUI_LEN] = { 0x00, 0x0f, 0xac };
+static const u8 wpa_oui[OUI_LEN] = { 0x00, 0x50, 0xf2 };
+
+/*
+ * synthesize WPA/RSN IE data
+ * See WiFi WPA specification and IEEE 802.11-2007 7.3.2.25
+ * for the format
+ */
+static size_t gelic_wl_synthesize_ie(u8 *buf,
+ struct gelic_eurus_scan_info *scan)
+{
+
+ const u8 *oui_header;
+ u8 *start = buf;
+ int rsn;
+ int ccmp;
+
+ pr_debug("%s: <- sec=%16x\n", __func__, scan->security);
+ switch (be16_to_cpu(scan->security) & GELIC_EURUS_SCAN_SEC_MASK) {
+ case GELIC_EURUS_SCAN_SEC_WPA:
+ rsn = 0;
+ break;
+ case GELIC_EURUS_SCAN_SEC_WPA2:
+ rsn = 1;
+ break;
+ default:
+ /* WEP or none. No IE returned */
+ return 0;
+ }
+
+ switch (be16_to_cpu(scan->security) & GELIC_EURUS_SCAN_SEC_WPA_MASK) {
+ case GELIC_EURUS_SCAN_SEC_WPA_TKIP:
+ ccmp = 0;
+ break;
+ case GELIC_EURUS_SCAN_SEC_WPA_AES:
+ ccmp = 1;
+ break;
+ default:
+ if (rsn) {
+ ccmp = 1;
+ pr_info("%s: no cipher info. defaulted to CCMP\n",
+ __func__);
+ } else {
+ ccmp = 0;
+ pr_info("%s: no cipher info. defaulted to TKIP\n",
+ __func__);
+ }
+ }
+
+ if (rsn)
+ oui_header = rsn_oui;
+ else
+ oui_header = wpa_oui;
+
+ /* element id */
+ if (rsn)
+ *buf++ = MFIE_TYPE_RSN;
+ else
+ *buf++ = MFIE_TYPE_GENERIC;
+
+ /* length filed; set later */
+ buf++;
+
+ /* wpa special header */
+ if (!rsn) {
+ memcpy(buf, wpa_oui, OUI_LEN);
+ buf += OUI_LEN;
+ *buf++ = 0x01;
+ }
+
+ /* version */
+ *buf++ = 0x01; /* version 1.0 */
+ *buf++ = 0x00;
+
+ /* group cipher */
+ memcpy(buf, oui_header, OUI_LEN);
+ buf += OUI_LEN;
+
+ if (ccmp)
+ *buf++ = 0x04; /* CCMP */
+ else
+ *buf++ = 0x02; /* TKIP */
+
+ /* pairwise key count always 1 */
+ *buf++ = 0x01;
+ *buf++ = 0x00;
+
+ /* pairwise key suit */
+ memcpy(buf, oui_header, OUI_LEN);
+ buf += OUI_LEN;
+ if (ccmp)
+ *buf++ = 0x04; /* CCMP */
+ else
+ *buf++ = 0x02; /* TKIP */
+
+ /* AKM count is 1 */
+ *buf++ = 0x01;
+ *buf++ = 0x00;
+
+ /* AKM suite is assumed as PSK*/
+ memcpy(buf, oui_header, OUI_LEN);
+ buf += OUI_LEN;
+ *buf++ = 0x02; /* PSK */
+
+ /* RSN capabilities is 0 */
+ *buf++ = 0x00;
+ *buf++ = 0x00;
+
+ /* set length field */
+ start[1] = (buf - start - 2);
+
+ pr_debug("%s: ->\n", __func__);
+ return (buf - start);
+}
+
+struct ie_item {
+ u8 *data;
+ u8 len;
+};
+
+struct ie_info {
+ struct ie_item wpa;
+ struct ie_item rsn;
+};
+
+static void gelic_wl_parse_ie(u8 *data, size_t len,
+ struct ie_info *ie_info)
+{
+ size_t data_left = len;
+ u8 *pos = data;
+ u8 item_len;
+ u8 item_id;
+
+ pr_debug("%s: data=%p len=%ld \n", __func__,
+ data, len);
+ memset(ie_info, 0, sizeof(struct ie_info));
+
+ while (0 < data_left) {
+ item_id = *pos++;
+ item_len = *pos++;
+
+ switch (item_id) {
+ case MFIE_TYPE_GENERIC:
+ if (!memcmp(pos, wpa_oui, OUI_LEN) &&
+ pos[OUI_LEN] == 0x01) {
+ ie_info->wpa.data = pos - 2;
+ ie_info->wpa.len = item_len + 2;
+ }
+ break;
+ case MFIE_TYPE_RSN:
+ ie_info->rsn.data = pos - 2;
+ /* length includes the header */
+ ie_info->rsn.len = item_len + 2;
+ break;
+ default:
+ pr_debug("%s: ignore %#x,%d\n", __func__,
+ item_id, item_len);
+ break;
+ }
+ pos += item_len;
+ data_left -= item_len + 2;
+ }
+ pr_debug("%s: wpa=%p,%d wpa2=%p,%d\n", __func__,
+ ie_info->wpa.data, ie_info->wpa.len,
+ ie_info->rsn.data, ie_info->rsn.len);
+}
+
+
+/*
+ * translate the scan informations from hypervisor to a
+ * independent format
+ */
+static char *gelic_wl_translate_scan(struct net_device *netdev,
+ char *ev,
+ char *stop,
+ struct gelic_wl_scan_info *network)
+{
+ struct iw_event iwe;
+ struct gelic_eurus_scan_info *scan = network->hwinfo;
+ char *tmp;
+ u8 rate;
+ unsigned int i, j, len;
+ u8 buf[MAX_WPA_IE_LEN];
+
+ pr_debug("%s: <-\n", __func__);
+
+ /* first entry should be AP's mac address */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN);
+ ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_ADDR_LEN);
+
+ /* ESSID */
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ iwe.u.data.length = strnlen(scan->essid, 32);
+ ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid);
+
+ /* FREQUENCY */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = be16_to_cpu(scan->channel);
+ iwe.u.freq.e = 0; /* table value in MHz */
+ iwe.u.freq.i = 0;
+ ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_FREQ_LEN);
+
+ /* RATES */
+ iwe.cmd = SIOCGIWRATE;
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+ /* to stuff multiple values in one event */
+ tmp = ev + IW_EV_LCP_LEN;
+ /* put them in ascendant order (older is first) */
+ i = 0;
+ j = 0;
+ pr_debug("%s: rates=%d rate=%d\n", __func__,
+ network->rate_len, network->rate_ext_len);
+ while (i < network->rate_len) {
+ if (j < network->rate_ext_len &&
+ ((scan->ext_rate[j] & 0x7f) < (scan->rate[i] & 0x7f)))
+ rate = scan->ext_rate[j++] & 0x7f;
+ else
+ rate = scan->rate[i++] & 0x7f;
+ iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */
+ tmp = iwe_stream_add_value(ev, tmp, stop, &iwe,
+ IW_EV_PARAM_LEN);
+ }
+ while (j < network->rate_ext_len) {
+ iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000;
+ tmp = iwe_stream_add_value(ev, tmp, stop, &iwe,
+ IW_EV_PARAM_LEN);
+ }
+ /* Check if we added any rate */
+ if (IW_EV_LCP_LEN < (tmp - ev))
+ ev = tmp;
+
+ /* ENCODE */
+ iwe.cmd = SIOCGIWENCODE;
+ if (be16_to_cpu(scan->capability) & 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;
+ ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid);
+
+ /* MODE */
+ iwe.cmd = SIOCGIWMODE;
+ if (be16_to_cpu(scan->capability) &
+ (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+ if (be16_to_cpu(scan->capability) & WLAN_CAPABILITY_ESS)
+ iwe.u.mode = IW_MODE_MASTER;
+ else
+ iwe.u.mode = IW_MODE_ADHOC;
+ ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_UINT_LEN);
+ }
+
+ /* QUAL */
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.updated = IW_QUAL_ALL_UPDATED |
+ IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
+ iwe.u.qual.level = be16_to_cpu(scan->rssi);
+ iwe.u.qual.qual = be16_to_cpu(scan->rssi);
+ iwe.u.qual.noise = 0;
+ ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_QUAL_LEN);
+
+ /* RSN */
+ memset(&iwe, 0, sizeof(iwe));
+ if (be16_to_cpu(scan->size) <= sizeof(*scan)) {
+ /* If wpa[2] capable station, synthesize IE and put it */
+ len = gelic_wl_synthesize_ie(buf, scan);
+ if (len) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = len;
+ ev = iwe_stream_add_point(ev, stop, &iwe, buf);
+ }
+ } else {
+ /* this scan info has IE data */
+ struct ie_info ie_info;
+ size_t data_len;
+
+ data_len = be16_to_cpu(scan->size) - sizeof(*scan);
+
+ gelic_wl_parse_ie(scan->elements, data_len, &ie_info);
+
+ if (ie_info.wpa.len && (ie_info.wpa.len <= sizeof(buf))) {
+ memcpy(buf, ie_info.wpa.data, ie_info.wpa.len);
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = ie_info.wpa.len;
+ ev = iwe_stream_add_point(ev, stop, &iwe, buf);
+ }
+
+ if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) {
+ memset(&iwe, 0, sizeof(iwe));
+ memcpy(buf, ie_info.rsn.data, ie_info.rsn.len);
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = ie_info.rsn.len;
+ ev = iwe_stream_add_point(ev, stop, &iwe, buf);
+ }
+ }
+
+ pr_debug("%s: ->\n", __func__);
+ return ev;
+}
+
+
+static int gelic_wl_get_scan(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ struct gelic_wl_scan_info *scan_info;
+ char *ev = extra;
+ char *stop = ev + wrqu->data.length;
+ int ret = 0;
+ unsigned long this_time = jiffies;
+
+ pr_debug("%s: <-\n", __func__);
+ if (down_interruptible(&wl->scan_lock))
+ return -EAGAIN;
+
+ switch (wl->scan_stat) {
+ case GELIC_WL_SCAN_STAT_SCANNING:
+ /* If a scan in progress, caller should call me again */
+ ret = -EAGAIN;
+ goto out;
+ break;
+
+ case GELIC_WL_SCAN_STAT_INIT:
+ /* last scan request failed or never issued */
+ ret = -ENODEV;
+ goto out;
+ break;
+ case GELIC_WL_SCAN_STAT_GOT_LIST:
+ /* ok, use current list */
+ break;
+ }
+
+ list_for_each_entry(scan_info, &wl->network_list, list) {
+ if (wl->scan_age == 0 ||
+ time_after(scan_info->last_scanned + wl->scan_age,
+ this_time))
+ ev = gelic_wl_translate_scan(netdev, ev, stop,
+ scan_info);
+ else
+ pr_debug("%s:entry too old\n", __func__);
+
+ if (stop - ev <= IW_EV_ADDR_LEN) {
+ ret = -E2BIG;
+ goto out;
+ }
+ }
+
+ wrqu->data.length = ev - extra;
+ wrqu->data.flags = 0;
+out:
+ up(&wl->scan_lock);
+ pr_debug("%s: -> %d %d\n", __func__, ret, wrqu->data.length);
+ return ret;
+}
+
+#ifdef DEBUG
+static void scan_list_dump(struct gelic_wl_info *wl)
+{
+ struct gelic_wl_scan_info *scan_info;
+ int i;
+ DECLARE_MAC_BUF(mac);
+
+ i = 0;
+ list_for_each_entry(scan_info, &wl->network_list, list) {
+ pr_debug("%s: item %d\n", __func__, i++);
+ pr_debug("valid=%d eurusindex=%d last=%lx\n",
+ scan_info->valid, scan_info->eurus_index,
+ scan_info->last_scanned);
+ pr_debug("r_len=%d r_ext_len=%d essid_len=%d\n",
+ scan_info->rate_len, scan_info->rate_ext_len,
+ scan_info->essid_len);
+ /* -- */
+ pr_debug("bssid=%s\n",
+ print_mac(mac, &scan_info->hwinfo->bssid[2]));
+ pr_debug("essid=%s\n", scan_info->hwinfo->essid);
+ }
+}
+#endif
+
+static int gelic_wl_set_auth(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct iw_param *param = &data->param;
+ struct gelic_wl_info *wl = port_wl(netdev_port(netdev));
+ unsigned long irqflag;
+ int ret = 0;
+
+ pr_debug("%s: <- %d\n", __func__, param->flags & IW_AUTH_INDEX);
+ spin_lock_irqsave(&wl->lock, irqflag);
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
+ pr_debug("%s: NO WPA selected\n", __func__);
+ wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE;
+ wl->group_cipher_method = GELIC_WL_CIPHER_WEP;
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_WEP;
+ }
+ if (param->value & IW_AUTH_WPA_VERSION_WPA) {
+ pr_debug("%s: WPA version 1 selected\n", __func__);
+ wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA;
+ wl->group_cipher_method = GELIC_WL_CIPHER_TKIP;
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_TKIP;
+ wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+ }
+ if (param->value & IW_AUTH_WPA_VERSION_WPA2) {
+ /*
+ * As the hypervisor may not tell the cipher
+ * information of the AP if it is WPA2,
+ * you will not decide suitable cipher from
+ * its beacon.
+ * You should have knowledge about the AP's
+ * cipher infomation in other method prior to
+ * the association.
+ */
+ if (!precise_ie())
+ pr_info("%s: WPA2 may not work\n", __func__);
+ if (wpa2_capable()) {
+ wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA2;
+ wl->group_cipher_method = GELIC_WL_CIPHER_AES;
+ wl->pairwise_cipher_method =
+ GELIC_WL_CIPHER_AES;
+ wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+ } else
+ ret = -EINVAL;
+ }
+ break;
+
+ case IW_AUTH_CIPHER_PAIRWISE:
+ if (param->value &
+ (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
+ pr_debug("%s: WEP selected\n", __func__);
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_WEP;
+ }
+ if (param->value & IW_AUTH_CIPHER_TKIP) {
+ pr_debug("%s: TKIP selected\n", __func__);
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_TKIP;
+ }
+ if (param->value & IW_AUTH_CIPHER_CCMP) {
+ pr_debug("%s: CCMP selected\n", __func__);
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_AES;
+ }
+ if (param->value & IW_AUTH_CIPHER_NONE) {
+ pr_debug("%s: no auth selected\n", __func__);
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_NONE;
+ }
+ break;
+ case IW_AUTH_CIPHER_GROUP:
+ if (param->value &
+ (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
+ pr_debug("%s: WEP selected\n", __func__);
+ wl->group_cipher_method = GELIC_WL_CIPHER_WEP;
+ }
+ if (param->value & IW_AUTH_CIPHER_TKIP) {
+ pr_debug("%s: TKIP selected\n", __func__);
+ wl->group_cipher_method = GELIC_WL_CIPHER_TKIP;
+ }
+ if (param->value & IW_AUTH_CIPHER_CCMP) {
+ pr_debug("%s: CCMP selected\n", __func__);
+ wl->group_cipher_method = GELIC_WL_CIPHER_AES;
+ }
+ if (param->value & IW_AUTH_CIPHER_NONE) {
+ pr_debug("%s: no auth selected\n", __func__);
+ wl->group_cipher_method = GELIC_WL_CIPHER_NONE;
+ }
+ break;
+ case IW_AUTH_80211_AUTH_ALG:
+ if (param->value & IW_AUTH_ALG_SHARED_KEY) {
+ pr_debug("%s: shared key specified\n", __func__);
+ wl->auth_method = GELIC_EURUS_AUTH_SHARED;
+ } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
+ pr_debug("%s: open system specified\n", __func__);
+ wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+ } else
+ ret = -EINVAL;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ if (param->value) {
+ pr_debug("%s: WPA enabled\n", __func__);
+ wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA;
+ } else {
+ pr_debug("%s: WPA disabled\n", __func__);
+ wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE;
+ }
+ break;
+
+ case IW_AUTH_KEY_MGMT:
+ if (param->value & IW_AUTH_KEY_MGMT_PSK)
+ break;
+ /* intentionally fall through */
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ };
+
+ if (!ret)
+ set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ pr_debug("%s: -> %d\n", __func__, ret);
+ return ret;
+}
+
+static int gelic_wl_get_auth(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *iwreq, char *extra)
+{
+ struct iw_param *param = &iwreq->param;
+ struct gelic_wl_info *wl = port_wl(netdev_port(netdev));
+ unsigned long irqflag;
+ int ret = 0;
+
+ pr_debug("%s: <- %d\n", __func__, param->flags & IW_AUTH_INDEX);
+ spin_lock_irqsave(&wl->lock, irqflag);
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ switch (wl->wpa_level) {
+ case GELIC_WL_WPA_LEVEL_WPA:
+ param->value |= IW_AUTH_WPA_VERSION_WPA;
+ break;
+ case GELIC_WL_WPA_LEVEL_WPA2:
+ param->value |= IW_AUTH_WPA_VERSION_WPA2;
+ break;
+ default:
+ param->value |= IW_AUTH_WPA_VERSION_DISABLED;
+ }
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ if (wl->auth_method == GELIC_EURUS_AUTH_SHARED)
+ param->value = IW_AUTH_ALG_SHARED_KEY;
+ else if (wl->auth_method == GELIC_EURUS_AUTH_OPEN)
+ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ switch (wl->wpa_level) {
+ case GELIC_WL_WPA_LEVEL_WPA:
+ case GELIC_WL_WPA_LEVEL_WPA2:
+ param->value = 1;
+ break;
+ default:
+ param->value = 0;
+ break;
+ }
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ pr_debug("%s: -> %d\n", __func__, ret);
+ return ret;
+}
+
+/* SIOC{S,G}IWESSID */
+static int gelic_wl_set_essid(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ unsigned long irqflag;
+
+ pr_debug("%s: <- l=%d f=%d\n", __func__,
+ data->essid.length, data->essid.flags);
+ if (IW_ESSID_MAX_SIZE < data->essid.length)
+ return -EINVAL;
+
+ spin_lock_irqsave(&wl->lock, irqflag);
+ if (data->essid.flags) {
+ wl->essid_len = data->essid.length;
+ memcpy(wl->essid, extra, wl->essid_len);
+ pr_debug("%s: essid = '%s'\n", __func__, extra);
+ set_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat);
+ } else {
+ pr_debug("%s: ESSID any \n", __func__);
+ clear_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat);
+ }
+ set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+
+
+ gelic_wl_try_associate(netdev); /* FIXME */
+ pr_debug("%s: -> \n", __func__);
+ return 0;
+}
+
+static int gelic_wl_get_essid(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ unsigned long irqflag;
+
+ pr_debug("%s: <- \n", __func__);
+ down(&wl->assoc_stat_lock);
+ spin_lock_irqsave(&wl->lock, irqflag);
+ if (test_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat) ||
+ wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) {
+ memcpy(extra, wl->essid, wl->essid_len);
+ data->essid.length = wl->essid_len;
+ data->essid.flags = 1;
+ } else
+ data->essid.flags = 0;
+
+ up(&wl->assoc_stat_lock);
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ pr_debug("%s: -> len=%d \n", __func__, data->essid.length);
+
+ return 0;
+}
+
+/* SIO{S,G}IWENCODE */
+static int gelic_wl_set_encode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ struct iw_point *enc = &data->encoding;
+ __u16 flags;
+ unsigned int irqflag;
+ int key_index, index_specified;
+ int ret = 0;
+
+ pr_debug("%s: <- \n", __func__);
+ flags = enc->flags & IW_ENCODE_FLAGS;
+ key_index = enc->flags & IW_ENCODE_INDEX;
+
+ pr_debug("%s: key_index = %d\n", __func__, key_index);
+ pr_debug("%s: key_len = %d\n", __func__, enc->length);
+ pr_debug("%s: flag=%x\n", __func__, enc->flags & IW_ENCODE_FLAGS);
+
+ if (GELIC_WEP_KEYS < key_index)
+ return -EINVAL;
+
+ spin_lock_irqsave(&wl->lock, irqflag);
+ if (key_index) {
+ index_specified = 1;
+ key_index--;
+ } else {
+ index_specified = 0;
+ key_index = wl->current_key;
+ }
+
+ if (flags & IW_ENCODE_NOKEY) {
+ /* if just IW_ENCODE_NOKEY, change current key index */
+ if (!flags && index_specified) {
+ wl->current_key = key_index;
+ goto done;
+ }
+
+ if (flags & IW_ENCODE_DISABLED) {
+ if (!index_specified) {
+ /* disable encryption */
+ wl->group_cipher_method = GELIC_WL_CIPHER_NONE;
+ wl->pairwise_cipher_method =
+ GELIC_WL_CIPHER_NONE;
+ /* invalidate all key */
+ wl->key_enabled = 0;
+ } else
+ clear_bit(key_index, &wl->key_enabled);
+ }
+
+ if (flags & IW_ENCODE_OPEN)
+ wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+ if (flags & IW_ENCODE_RESTRICTED) {
+ pr_info("%s: shared key mode enabled\n", __func__);
+ wl->auth_method = GELIC_EURUS_AUTH_SHARED;
+ }
+ } else {
+ if (IW_ENCODING_TOKEN_MAX < enc->length) {
+ ret = -EINVAL;
+ goto done;
+ }
+ wl->key_len[key_index] = enc->length;
+ memcpy(wl->key[key_index], extra, enc->length);
+ set_bit(key_index, &wl->key_enabled);
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_WEP;
+ wl->group_cipher_method = GELIC_WL_CIPHER_WEP;
+ }
+ set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+done:
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ pr_debug("%s: -> \n", __func__);
+ return ret;
+}
+
+static int gelic_wl_get_encode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ struct iw_point *enc = &data->encoding;
+ unsigned int irqflag;
+ unsigned int key_index, index_specified;
+ int ret = 0;
+
+ pr_debug("%s: <- \n", __func__);
+ key_index = enc->flags & IW_ENCODE_INDEX;
+ pr_debug("%s: flag=%#x point=%p len=%d extra=%p\n", __func__,
+ enc->flags, enc->pointer, enc->length, extra);
+ if (GELIC_WEP_KEYS < key_index)
+ return -EINVAL;
+
+ spin_lock_irqsave(&wl->lock, irqflag);
+ if (key_index) {
+ index_specified = 1;
+ key_index--;
+ } else {
+ index_specified = 0;
+ key_index = wl->current_key;
+ }
+
+ if (wl->group_cipher_method == GELIC_WL_CIPHER_WEP) {
+ switch (wl->auth_method) {
+ case GELIC_EURUS_AUTH_OPEN:
+ enc->flags = IW_ENCODE_OPEN;
+ break;
+ case GELIC_EURUS_AUTH_SHARED:
+ enc->flags = IW_ENCODE_RESTRICTED;
+ break;
+ }
+ } else
+ enc->flags = IW_ENCODE_DISABLED;
+
+ if (test_bit(key_index, &wl->key_enabled)) {
+ if (enc->length < wl->key_len[key_index]) {
+ ret = -EINVAL;
+ goto done;
+ }
+ enc->length = wl->key_len[key_index];
+ memcpy(extra, wl->key[key_index], wl->key_len[key_index]);
+ } else {
+ enc->length = 0;
+ enc->flags |= IW_ENCODE_NOKEY;
+ }
+ enc->flags |= key_index + 1;
+ pr_debug("%s: -> flag=%x len=%d\n", __func__,
+ enc->flags, enc->length);
+
+done:
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ return ret;
+}
+
+/* SIOC{S,G}IWAP */
+static int gelic_wl_set_ap(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ unsigned long irqflag;
+
+ pr_debug("%s: <-\n", __func__);
+ if (data->ap_addr.sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ spin_lock_irqsave(&wl->lock, irqflag);
+ if (is_valid_ether_addr(data->ap_addr.sa_data)) {
+ memcpy(wl->bssid, data->ap_addr.sa_data,
+ ETH_ALEN);
+ set_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat);
+ set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+ pr_debug("%s: bss=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ __func__,
+ wl->bssid[0], wl->bssid[1],
+ wl->bssid[2], wl->bssid[3],
+ wl->bssid[4], wl->bssid[5]);
+ } else {
+ pr_debug("%s: clear bssid\n", __func__);
+ clear_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat);
+ memset(wl->bssid, 0, ETH_ALEN);
+ }
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ pr_debug("%s: ->\n", __func__);
+ return 0;
+}
+
+static int gelic_wl_get_ap(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ unsigned long irqflag;
+
+ pr_debug("%s: <-\n", __func__);
+ down(&wl->assoc_stat_lock);
+ spin_lock_irqsave(&wl->lock, irqflag);
+ if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) {
+ data->ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(data->ap_addr.sa_data, wl->active_bssid,
+ ETH_ALEN);
+ } else
+ memset(data->ap_addr.sa_data, 0, ETH_ALEN);
+
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ up(&wl->assoc_stat_lock);
+ pr_debug("%s: ->\n", __func__);
+ return 0;
+}
+
+/* SIOC{S,G}IWENCODEEXT */
+static int gelic_wl_set_encodeext(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ struct iw_point *enc = &data->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ __u16 alg;
+ __u16 flags;
+ unsigned int irqflag;
+ int key_index;
+ int ret = 0;
+
+ pr_debug("%s: <- \n", __func__);
+ flags = enc->flags & IW_ENCODE_FLAGS;
+ alg = ext->alg;
+ key_index = enc->flags & IW_ENCODE_INDEX;
+
+ pr_debug("%s: key_index = %d\n", __func__, key_index);
+ pr_debug("%s: key_len = %d\n", __func__, enc->length);
+ pr_debug("%s: flag=%x\n", __func__, enc->flags & IW_ENCODE_FLAGS);
+ pr_debug("%s: ext_flag=%x\n", __func__, ext->ext_flags);
+ pr_debug("%s: ext_key_len=%x\n", __func__, ext->key_len);
+
+ if (GELIC_WEP_KEYS < key_index)
+ return -EINVAL;
+
+ spin_lock_irqsave(&wl->lock, irqflag);
+ if (key_index)
+ key_index--;
+ else
+ key_index = wl->current_key;
+
+ if (!enc->length && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
+ /* reques to change default key index */
+ pr_debug("%s: request to change default key to %d\n",
+ __func__, key_index);
+ wl->current_key = key_index;
+ goto done;
+ }
+
+ if (alg == IW_ENCODE_ALG_NONE || (flags & IW_ENCODE_DISABLED)) {
+ pr_debug("%s: alg disabled\n", __func__);
+ wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE;
+ wl->group_cipher_method = GELIC_WL_CIPHER_NONE;
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_NONE;
+ wl->auth_method = GELIC_EURUS_AUTH_OPEN; /* should be open */
+ } else if (alg == IW_ENCODE_ALG_WEP) {
+ pr_debug("%s: WEP requested\n", __func__);
+ if (flags & IW_ENCODE_OPEN) {
+ pr_debug("%s: open key mode\n", __func__);
+ wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+ }
+ if (flags & IW_ENCODE_RESTRICTED) {
+ pr_debug("%s: shared key mode\n", __func__);
+ wl->auth_method = GELIC_EURUS_AUTH_SHARED;
+ }
+ if (IW_ENCODING_TOKEN_MAX < ext->key_len) {
+ pr_info("%s: key is too long %d\n", __func__,
+ ext->key_len);
+ ret = -EINVAL;
+ goto done;
+ }
+ /* OK, update the key */
+ wl->key_len[key_index] = ext->key_len;
+ memset(wl->key[key_index], 0, IW_ENCODING_TOKEN_MAX);
+ memcpy(wl->key[key_index], ext->key, ext->key_len);
+ set_bit(key_index, &wl->key_enabled);
+ /* remember wep info changed */
+ set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+ } else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
+ pr_debug("%s: TKIP/CCMP requested alg=%d\n", __func__, alg);
+ /* check key length */
+ if (IW_ENCODING_TOKEN_MAX < ext->key_len) {
+ pr_info("%s: key is too long %d\n", __func__,
+ ext->key_len);
+ ret = -EINVAL;
+ goto done;
+ }
+ if (alg == IW_ENCODE_ALG_CCMP) {
+ pr_debug("%s: AES selected\n", __func__);
+ wl->group_cipher_method = GELIC_WL_CIPHER_AES;
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_AES;
+ wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA2;
+ } else {
+ pr_debug("%s: TKIP selected, WPA forced\n", __func__);
+ wl->group_cipher_method = GELIC_WL_CIPHER_TKIP;
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_TKIP;
+ /* FIXME: how do we do if WPA2 + TKIP? */
+ wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA;
+ }
+ if (flags & IW_ENCODE_RESTRICTED)
+ BUG();
+ wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+ /* We should use same key for both and unicast */
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+ pr_debug("%s: group key \n", __func__);
+ else
+ pr_debug("%s: unicast key \n", __func__);
+ /* OK, update the key */
+ wl->key_len[key_index] = ext->key_len;
+ memset(wl->key[key_index], 0, IW_ENCODING_TOKEN_MAX);
+ memcpy(wl->key[key_index], ext->key, ext->key_len);
+ set_bit(key_index, &wl->key_enabled);
+ /* remember info changed */
+ set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+ }
+done:
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ pr_debug("%s: -> \n", __func__);
+ return ret;
+}
+
+static int gelic_wl_get_encodeext(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ struct iw_point *enc = &data->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ unsigned int irqflag;
+ int key_index;
+ int ret = 0;
+ int max_key_len;
+
+ pr_debug("%s: <- \n", __func__);
+
+ max_key_len = enc->length - sizeof(struct iw_encode_ext);
+ if (max_key_len < 0)
+ return -EINVAL;
+ key_index = enc->flags & IW_ENCODE_INDEX;
+
+ pr_debug("%s: key_index = %d\n", __func__, key_index);
+ pr_debug("%s: key_len = %d\n", __func__, enc->length);
+ pr_debug("%s: flag=%x\n", __func__, enc->flags & IW_ENCODE_FLAGS);
+
+ if (GELIC_WEP_KEYS < key_index)
+ return -EINVAL;
+
+ spin_lock_irqsave(&wl->lock, irqflag);
+ if (key_index)
+ key_index--;
+ else
+ key_index = wl->current_key;
+
+ memset(ext, 0, sizeof(struct iw_encode_ext));
+ switch (wl->group_cipher_method) {
+ case GELIC_WL_CIPHER_WEP:
+ ext->alg = IW_ENCODE_ALG_WEP;
+ enc->flags |= IW_ENCODE_ENABLED;
+ break;
+ case GELIC_WL_CIPHER_TKIP:
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ enc->flags |= IW_ENCODE_ENABLED;
+ break;
+ case GELIC_WL_CIPHER_AES:
+ ext->alg = IW_ENCODE_ALG_CCMP;
+ enc->flags |= IW_ENCODE_ENABLED;
+ break;
+ case GELIC_WL_CIPHER_NONE:
+ default:
+ ext->alg = IW_ENCODE_ALG_NONE;
+ enc->flags |= IW_ENCODE_NOKEY;
+ break;
+ }
+
+ if (!(enc->flags & IW_ENCODE_NOKEY)) {
+ if (max_key_len < wl->key_len[key_index]) {
+ ret = -E2BIG;
+ goto out;
+ }
+ if (test_bit(key_index, &wl->key_enabled))
+ memcpy(ext->key, wl->key[key_index],
+ wl->key_len[key_index]);
+ else
+ pr_debug("%s: disabled key requested ix=%d\n",
+ __func__, key_index);
+ }
+out:
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ pr_debug("%s: -> \n", __func__);
+ return ret;
+}
+/* SIOC{S,G}IWMODE */
+static int gelic_wl_set_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ __u32 mode = data->mode;
+ int ret;
+
+ pr_debug("%s: <- \n", __func__);
+ if (mode == IW_MODE_INFRA)
+ ret = 0;
+ else
+ ret = -EOPNOTSUPP;
+ pr_debug("%s: -> %d\n", __func__, ret);
+ return ret;
+}
+
+static int gelic_wl_get_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ __u32 *mode = &data->mode;
+ pr_debug("%s: <- \n", __func__);
+ *mode = IW_MODE_INFRA;
+ pr_debug("%s: ->\n", __func__);
+ return 0;
+}
+
+/* SIOCIWFIRSTPRIV */
+static int hex2bin(u8 *str, u8 *bin, unsigned int len)
+{
+ unsigned int i;
+ static unsigned char *hex = "0123456789ABCDEF";
+ unsigned char *p, *q;
+ u8 tmp;
+
+ if (len != WPA_PSK_LEN * 2)
+ return -EINVAL;
+
+ for (i = 0; i < WPA_PSK_LEN * 2; i += 2) {
+ p = strchr(hex, toupper(str[i]));
+ q = strchr(hex, toupper(str[i + 1]));
+ if (!p || !q) {
+ pr_info("%s: unconvertible PSK digit=%d\n",
+ __func__, i);
+ return -EINVAL;
+ }
+ tmp = ((p - hex) << 4) + (q - hex);
+ *bin++ = tmp;
+ }
+ return 0;
+};
+
+static int gelic_wl_priv_set_psk(struct net_device *net_dev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));
+ unsigned int len;
+ unsigned int irqflag;
+ int ret = 0;
+
+ pr_debug("%s:<- len=%d\n", __func__, data->data.length);
+ len = data->data.length - 1;
+ if (len <= 2)
+ return -EINVAL;
+
+ spin_lock_irqsave(&wl->lock, irqflag);
+ if (extra[0] == '"' && extra[len - 1] == '"') {
+ pr_debug("%s: passphrase mode\n", __func__);
+ /* pass phrase */
+ if (GELIC_WL_EURUS_PSK_MAX_LEN < (len - 2)) {
+ pr_info("%s: passphrase too long\n", __func__);
+ ret = -E2BIG;
+ goto out;
+ }
+ memset(wl->psk, 0, sizeof(wl->psk));
+ wl->psk_len = len - 2;
+ memcpy(wl->psk, &(extra[1]), wl->psk_len);
+ wl->psk_type = GELIC_EURUS_WPA_PSK_PASSPHRASE;
+ } else {
+ ret = hex2bin(extra, wl->psk, len);
+ if (ret)
+ goto out;
+ wl->psk_len = WPA_PSK_LEN;
+ wl->psk_type = GELIC_EURUS_WPA_PSK_BIN;
+ }
+ set_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat);
+out:
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ pr_debug("%s:->\n", __func__);
+ return ret;
+}
+
+static int gelic_wl_priv_get_psk(struct net_device *net_dev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));
+ char *p;
+ unsigned int irqflag;
+ unsigned int i;
+
+ pr_debug("%s:<-\n", __func__);
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ spin_lock_irqsave(&wl->lock, irqflag);
+ p = extra;
+ if (test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat)) {
+ if (wl->psk_type == GELIC_EURUS_WPA_PSK_BIN) {
+ for (i = 0; i < wl->psk_len; i++) {
+ sprintf(p, "%02xu", wl->psk[i]);
+ p += 2;
+ }
+ *p = '\0';
+ data->data.length = wl->psk_len * 2;
+ } else {
+ *p++ = '"';
+ memcpy(p, wl->psk, wl->psk_len);
+ p += wl->psk_len;
+ *p++ = '"';
+ *p = '\0';
+ data->data.length = wl->psk_len + 2;
+ }
+ } else
+ /* no psk set */
+ data->data.length = 0;
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+ pr_debug("%s:-> %d\n", __func__, data->data.length);
+ return 0;
+}
+
+/* SIOCGIWNICKN */
+static int gelic_wl_get_nick(struct net_device *net_dev,
+ struct iw_request_info *info,
+ union iwreq_data *data, char *extra)
+{
+ strcpy(extra, "gelic_wl");
+ data->data.length = strlen(extra);
+ data->data.flags = 1;
+ return 0;
+}
+
+
+/* --- */
+
+static struct iw_statistics *gelic_wl_get_wireless_stats(
+ struct net_device *netdev)
+{
+
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ struct gelic_eurus_cmd *cmd;
+ struct iw_statistics *is;
+ struct gelic_eurus_rssi_info *rssi;
+
+ pr_debug("%s: <-\n", __func__);
+
+ is = &wl->iwstat;
+ memset(is, 0, sizeof(*is));
+ cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_GET_RSSI_CFG,
+ wl->buf, sizeof(*rssi));
+ if (cmd && !cmd->status && !cmd->cmd_status) {
+ rssi = wl->buf;
+ is->qual.level = be16_to_cpu(rssi->rssi);
+ is->qual.updated = IW_QUAL_LEVEL_UPDATED |
+ IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
+ } else
+ /* not associated */
+ is->qual.updated = IW_QUAL_ALL_INVALID;
+
+ kfree(cmd);
+ pr_debug("%s: ->\n", __func__);
+ return is;
+}
+
+/*
+ * scanning helpers
+ */
+static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan)
+{
+ struct gelic_eurus_cmd *cmd;
+ int ret = 0;
+
+ pr_debug("%s: <- always=%d\n", __func__, always_scan);
+ if (down_interruptible(&wl->scan_lock))
+ return -ERESTARTSYS;
+
+ /*
+ * If already a scan in progress, do not trigger more
+ */
+ if (wl->scan_stat == GELIC_WL_SCAN_STAT_SCANNING) {
+ pr_debug("%s: scanning now\n", __func__);
+ goto out;
+ }
+
+ init_completion(&wl->scan_done);
+ /*
+ * If we have already a bss list, don't try to get new
+ */
+ if (!always_scan && wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) {
+ pr_debug("%s: already has the list\n", __func__);
+ complete(&wl->scan_done);
+ goto out;
+ }
+ /*
+ * issue start scan request
+ */
+ wl->scan_stat = GELIC_WL_SCAN_STAT_SCANNING;
+ cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_START_SCAN,
+ NULL, 0);
+ if (!cmd || cmd->status || cmd->cmd_status) {
+ wl->scan_stat = GELIC_WL_SCAN_STAT_INIT;
+ complete(&wl->scan_done);
+ ret = -ENOMEM;
+ goto out;
+ }
+ kfree(cmd);
+out:
+ up(&wl->scan_lock);
+ pr_debug("%s: ->\n", __func__);
+ return ret;
+}
+
+/*
+ * retrieve scan result from the chip (hypervisor)
+ * this function is invoked by schedule work.
+ */
+static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
+{
+ struct gelic_eurus_cmd *cmd = NULL;
+ struct gelic_wl_scan_info *target, *tmp;
+ struct gelic_wl_scan_info *oldest = NULL;
+ struct gelic_eurus_scan_info *scan_info;
+ unsigned int scan_info_size;
+ union iwreq_data data;
+ unsigned long this_time = jiffies;
+ unsigned int data_len, i, found, r;
+ DECLARE_MAC_BUF(mac);
+
+ pr_debug("%s:start\n", __func__);
+ down(&wl->scan_lock);
+
+ if (wl->scan_stat != GELIC_WL_SCAN_STAT_SCANNING) {
+ /*
+ * stop() may be called while scanning, ignore result
+ */
+ pr_debug("%s: scan complete when stat != scanning(%d)\n",
+ __func__, wl->scan_stat);
+ goto out;
+ }
+
+ cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_GET_SCAN,
+ wl->buf, PAGE_SIZE);
+ if (!cmd || cmd->status || cmd->cmd_status) {
+ wl->scan_stat = GELIC_WL_SCAN_STAT_INIT;
+ pr_info("%s:cmd failed\n", __func__);
+ kfree(cmd);
+ goto out;
+ }
+ data_len = cmd->size;
+ pr_debug("%s: data_len = %d\n", __func__, data_len);
+ kfree(cmd);
+
+ /* OK, bss list retrieved */
+ wl->scan_stat = GELIC_WL_SCAN_STAT_GOT_LIST;
+
+ /* mark all entries are old */
+ list_for_each_entry_safe(target, tmp, &wl->network_list, list) {
+ target->valid = 0;
+ /* expire too old entries */
+ if (time_before(target->last_scanned + wl->scan_age,
+ this_time)) {
+ kfree(target->hwinfo);
+ target->hwinfo = NULL;
+ list_move_tail(&target->list, &wl->network_free_list);
+ }
+ }
+
+ /* put them in the newtork_list */
+ scan_info = wl->buf;
+ scan_info_size = 0;
+ i = 0;
+ while (scan_info_size < data_len) {
+ pr_debug("%s:size=%d bssid=%s scan_info=%p\n", __func__,
+ be16_to_cpu(scan_info->size),
+ print_mac(mac, &scan_info->bssid[2]), scan_info);
+ found = 0;
+ oldest = NULL;
+ list_for_each_entry(target, &wl->network_list, list) {
+ if (!compare_ether_addr(&target->hwinfo->bssid[2],
+ &scan_info->bssid[2])) {
+ found = 1;
+ pr_debug("%s: same BBS found scanned list\n",
+ __func__);
+ break;
+ }
+ if (!oldest ||
+ (target->last_scanned < oldest->last_scanned))
+ oldest = target;
+ }
+
+ if (!found) {
+ /* not found in the list */
+ if (list_empty(&wl->network_free_list)) {
+ /* expire oldest */
+ target = oldest;
+ } else {
+ target = list_entry(wl->network_free_list.next,
+ struct gelic_wl_scan_info,
+ list);
+ }
+ }
+
+ /* update the item */
+ target->last_scanned = this_time;
+ target->valid = 1;
+ target->eurus_index = i;
+ kfree(target->hwinfo);
+ target->hwinfo = kzalloc(be16_to_cpu(scan_info->size),
+ GFP_KERNEL);
+ if (!target->hwinfo) {
+ pr_info("%s: kzalloc failed\n", __func__);
+ i++;
+ scan_info_size += be16_to_cpu(scan_info->size);
+ scan_info = (void *)scan_info +
+ be16_to_cpu(scan_info->size);
+ continue;
+ }
+ /* copy hw scan info */
+ memcpy(target->hwinfo, scan_info, scan_info->size);
+ target->essid_len = strnlen(scan_info->essid,
+ sizeof(scan_info->essid));
+ target->rate_len = 0;
+ for (r = 0; r < MAX_RATES_LENGTH; r++)
+ if (scan_info->rate[r])
+ target->rate_len++;
+ if (8 < target->rate_len)
+ pr_info("%s: AP returns %d rates\n", __func__,
+ target->rate_len);
+ target->rate_ext_len = 0;
+ for (r = 0; r < MAX_RATES_EX_LENGTH; r++)
+ if (scan_info->ext_rate[r])
+ target->rate_ext_len++;
+ list_move_tail(&target->list, &wl->network_list);
+ /* bump pointer */
+ i++;
+ scan_info_size += be16_to_cpu(scan_info->size);
+ scan_info = (void *)scan_info + be16_to_cpu(scan_info->size);
+ }
+ memset(&data, 0, sizeof(data));
+ wireless_send_event(port_to_netdev(wl_port(wl)), SIOCGIWSCAN, &data,
+ NULL);
+out:
+ complete(&wl->scan_done);
+ up(&wl->scan_lock);
+ pr_debug("%s:end\n", __func__);
+}
+
+/*
+ * Select an appropriate bss from current scan list regarding
+ * current settings from userspace.
+ * The caller must hold wl->scan_lock,
+ * and on the state of wl->scan_state == GELIC_WL_SCAN_GOT_LIST
+ */
+static void update_best(struct gelic_wl_scan_info **best,
+ struct gelic_wl_scan_info *candid,
+ int *best_weight,
+ int *weight)
+{
+ if (*best_weight < ++(*weight)) {
+ *best_weight = *weight;
+ *best = candid;
+ }
+}
+
+static
+struct gelic_wl_scan_info *gelic_wl_find_best_bss(struct gelic_wl_info *wl)
+{
+ struct gelic_wl_scan_info *scan_info;
+ struct gelic_wl_scan_info *best_bss;
+ int weight, best_weight;
+ u16 security;
+ DECLARE_MAC_BUF(mac);
+
+ pr_debug("%s: <-\n", __func__);
+
+ best_bss = NULL;
+ best_weight = 0;
+
+ list_for_each_entry(scan_info, &wl->network_list, list) {
+ pr_debug("%s: station %p\n", __func__, scan_info);
+
+ if (!scan_info->valid) {
+ pr_debug("%s: station invalid\n", __func__);
+ continue;
+ }
+
+ /* If bss specified, check it only */
+ if (test_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat)) {
+ if (!compare_ether_addr(&scan_info->hwinfo->bssid[2],
+ wl->bssid)) {
+ best_bss = scan_info;
+ pr_debug("%s: bssid matched\n", __func__);
+ break;
+ } else {
+ pr_debug("%s: bssid unmached\n", __func__);
+ continue;
+ }
+ }
+
+ weight = 0;
+
+ /* security */
+ security = be16_to_cpu(scan_info->hwinfo->security) &
+ GELIC_EURUS_SCAN_SEC_MASK;
+ if (wl->wpa_level == GELIC_WL_WPA_LEVEL_WPA2) {
+ if (security == GELIC_EURUS_SCAN_SEC_WPA2)
+ update_best(&best_bss, scan_info,
+ &best_weight, &weight);
+ else
+ continue;
+ } else if (wl->wpa_level == GELIC_WL_WPA_LEVEL_WPA) {
+ if (security == GELIC_EURUS_SCAN_SEC_WPA)
+ update_best(&best_bss, scan_info,
+ &best_weight, &weight);
+ else
+ continue;
+ } else if (wl->wpa_level == GELIC_WL_WPA_LEVEL_NONE &&
+ wl->group_cipher_method == GELIC_WL_CIPHER_WEP) {
+ if (security == GELIC_EURUS_SCAN_SEC_WEP)
+ update_best(&best_bss, scan_info,
+ &best_weight, &weight);
+ else
+ continue;
+ }
+
+ /* If ESSID is set, check it */
+ if (test_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat)) {
+ if ((scan_info->essid_len == wl->essid_len) &&
+ !strncmp(wl->essid,
+ scan_info->hwinfo->essid,
+ scan_info->essid_len))
+ update_best(&best_bss, scan_info,
+ &best_weight, &weight);
+ else
+ continue;
+ }
+ }
+
+#ifdef DEBUG
+ pr_debug("%s: -> bss=%p\n", __func__, best_bss);
+ if (best_bss) {
+ pr_debug("%s:addr=%s\n", __func__,
+ print_mac(mac, &best_bss->hwinfo->bssid[2]));
+ }
+#endif
+ return best_bss;
+}
+
+/*
+ * Setup WEP configuration to the chip
+ * The caller must hold wl->scan_lock,
+ * and on the state of wl->scan_state == GELIC_WL_SCAN_GOT_LIST
+ */
+static int gelic_wl_do_wep_setup(struct gelic_wl_info *wl)
+{
+ unsigned int i;
+ struct gelic_eurus_wep_cfg *wep;
+ struct gelic_eurus_cmd *cmd;
+ int wep104 = 0;
+ int have_key = 0;
+ int ret = 0;
+
+ pr_debug("%s: <-\n", __func__);
+ /* we can assume no one should uses the buffer */
+ wep = wl->buf;
+ memset(wep, 0, sizeof(*wep));
+
+ if (wl->group_cipher_method == GELIC_WL_CIPHER_WEP) {
+ pr_debug("%s: WEP mode\n", __func__);
+ for (i = 0; i < GELIC_WEP_KEYS; i++) {
+ if (!test_bit(i, &wl->key_enabled))
+ continue;
+
+ pr_debug("%s: key#%d enabled\n", __func__, i);
+ have_key = 1;
+ if (wl->key_len[i] == 13)
+ wep104 = 1;
+ else if (wl->key_len[i] != 5) {
+ pr_info("%s: wrong wep key[%d]=%d\n",
+ __func__, i, wl->key_len[i]);
+ ret = -EINVAL;
+ goto out;
+ }
+ memcpy(wep->key[i], wl->key[i], wl->key_len[i]);
+ }
+
+ if (!have_key) {
+ pr_info("%s: all wep key disabled\n", __func__);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (wep104) {
+ pr_debug("%s: 104bit key\n", __func__);
+ wep->security = cpu_to_be16(GELIC_EURUS_WEP_SEC_104BIT);
+ } else {
+ pr_debug("%s: 40bit key\n", __func__);
+ wep->security = cpu_to_be16(GELIC_EURUS_WEP_SEC_40BIT);
+ }
+ } else {
+ pr_debug("%s: NO encryption\n", __func__);
+ wep->security = cpu_to_be16(GELIC_EURUS_WEP_SEC_NONE);
+ }
+
+ /* issue wep setup */
+ cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_SET_WEP_CFG,
+ wep, sizeof(*wep));
+ if (!cmd)
+ ret = -ENOMEM;
+ else if (cmd->status || cmd->cmd_status)
+ ret = -ENXIO;
+
+ kfree(cmd);
+out:
+ pr_debug("%s: ->\n", __func__);
+ return ret;
+}
+
+#ifdef DEBUG
+static const char *wpasecstr(enum gelic_eurus_wpa_security sec)
+{
+ switch (sec) {
+ case GELIC_EURUS_WPA_SEC_NONE:
+ return "NONE";
+ break;
+ case GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP:
+ return "WPA_TKIP_TKIP";
+ break;
+ case GELIC_EURUS_WPA_SEC_WPA_TKIP_AES:
+ return "WPA_TKIP_AES";
+ break;
+ case GELIC_EURUS_WPA_SEC_WPA_AES_AES:
+ return "WPA_AES_AES";
+ break;
+ case GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP:
+ return "WPA2_TKIP_TKIP";
+ break;
+ case GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES:
+ return "WPA2_TKIP_AES";
+ break;
+ case GELIC_EURUS_WPA_SEC_WPA2_AES_AES:
+ return "WPA2_AES_AES";
+ break;
+ }
+ return "";
+};
+#endif
+
+static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl)
+{
+ struct gelic_eurus_wpa_cfg *wpa;
+ struct gelic_eurus_cmd *cmd;
+ u16 security;
+ int ret = 0;
+
+ pr_debug("%s: <-\n", __func__);
+ /* we can assume no one should uses the buffer */
+ wpa = wl->buf;
+ memset(wpa, 0, sizeof(*wpa));
+
+ if (!test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat))
+ pr_info("%s: PSK not configured yet\n", __func__);
+
+ /* copy key */
+ memcpy(wpa->psk, wl->psk, wl->psk_len);
+
+ /* set security level */
+ if (wl->wpa_level == GELIC_WL_WPA_LEVEL_WPA2) {
+ if (wl->group_cipher_method == GELIC_WL_CIPHER_AES) {
+ security = GELIC_EURUS_WPA_SEC_WPA2_AES_AES;
+ } else {
+ if (wl->pairwise_cipher_method == GELIC_WL_CIPHER_AES &&
+ precise_ie())
+ security = GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES;
+ else
+ security = GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP;
+ }
+ } else {
+ if (wl->group_cipher_method == GELIC_WL_CIPHER_AES) {
+ security = GELIC_EURUS_WPA_SEC_WPA_AES_AES;
+ } else {
+ if (wl->pairwise_cipher_method == GELIC_WL_CIPHER_AES &&
+ precise_ie())
+ security = GELIC_EURUS_WPA_SEC_WPA_TKIP_AES;
+ else
+ security = GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP;
+ }
+ }
+ wpa->security = cpu_to_be16(security);
+
+ /* PSK type */
+ wpa->psk_type = cpu_to_be16(wl->psk_type);
+#ifdef DEBUG
+ pr_debug("%s: sec=%s psktype=%s\nn", __func__,
+ wpasecstr(wpa->security),
+ (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ?
+ "BIN" : "passphrase");
+#if 0
+ /*
+ * don't enable here if you plan to submit
+ * the debug log because this dumps your precious
+ * passphrase/key.
+ */
+ pr_debug("%s: psk=%s\n",
+ (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ?
+ (char *)"N/A" : (char *)wpa->psk);
+#endif
+#endif
+ /* issue wpa setup */
+ cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_SET_WPA_CFG,
+ wpa, sizeof(*wpa));
+ if (!cmd)
+ ret = -ENOMEM;
+ else if (cmd->status || cmd->cmd_status)
+ ret = -ENXIO;
+ kfree(cmd);
+ pr_debug("%s: --> %d\n", __func__, ret);
+ return ret;
+}
+
+/*
+ * Start association. caller must hold assoc_stat_lock
+ */
+static int gelic_wl_associate_bss(struct gelic_wl_info *wl,
+ struct gelic_wl_scan_info *bss)
+{
+ struct gelic_eurus_cmd *cmd;
+ struct gelic_eurus_common_cfg *common;
+ int ret = 0;
+ unsigned long rc;
+
+ pr_debug("%s: <-\n", __func__);
+
+ /* do common config */
+ common = wl->buf;
+ memset(common, 0, sizeof(*common));
+ common->bss_type = cpu_to_be16(GELIC_EURUS_BSS_INFRA);
+ common->op_mode = cpu_to_be16(GELIC_EURUS_OPMODE_11BG);
+
+ common->scan_index = cpu_to_be16(bss->eurus_index);
+ switch (wl->auth_method) {
+ case GELIC_EURUS_AUTH_OPEN:
+ common->auth_method = cpu_to_be16(GELIC_EURUS_AUTH_OPEN);
+ break;
+ case GELIC_EURUS_AUTH_SHARED:
+ common->auth_method = cpu_to_be16(GELIC_EURUS_AUTH_SHARED);
+ break;
+ }
+
+#ifdef DEBUG
+ scan_list_dump(wl);
+#endif
+ pr_debug("%s: common cfg index=%d bsstype=%d auth=%d\n", __func__,
+ be16_to_cpu(common->scan_index),
+ be16_to_cpu(common->bss_type),
+ be16_to_cpu(common->auth_method));
+
+ cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_SET_COMMON_CFG,
+ common, sizeof(*common));
+ if (!cmd || cmd->status || cmd->cmd_status) {
+ ret = -ENOMEM;
+ kfree(cmd);
+ goto out;
+ }
+ kfree(cmd);
+
+ /* WEP/WPA */
+ switch (wl->wpa_level) {
+ case GELIC_WL_WPA_LEVEL_NONE:
+ /* If WEP or no security, setup WEP config */
+ ret = gelic_wl_do_wep_setup(wl);
+ break;
+ case GELIC_WL_WPA_LEVEL_WPA:
+ case GELIC_WL_WPA_LEVEL_WPA2:
+ ret = gelic_wl_do_wpa_setup(wl);
+ break;
+ };
+
+ if (ret) {
+ pr_debug("%s: WEP/WPA setup failed %d\n", __func__,
+ ret);
+ }
+
+ /* start association */
+ init_completion(&wl->assoc_done);
+ wl->assoc_stat = GELIC_WL_ASSOC_STAT_ASSOCIATING;
+ cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_ASSOC,
+ NULL, 0);
+ if (!cmd || cmd->status || cmd->cmd_status) {
+ pr_debug("%s: assoc request failed\n", __func__);
+ wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN;
+ kfree(cmd);
+ ret = -ENOMEM;
+ gelic_wl_send_iwap_event(wl, NULL);
+ goto out;
+ }
+ kfree(cmd);
+
+ /* wait for connected event */
+ rc = wait_for_completion_timeout(&wl->assoc_done, HZ * 4);/*FIXME*/
+
+ if (!rc) {
+ /* timeouted. Maybe key or cyrpt mode is wrong */
+ pr_info("%s: connect timeout \n", __func__);
+ cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_DISASSOC,
+ NULL, 0);
+ kfree(cmd);
+ wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN;
+ gelic_wl_send_iwap_event(wl, NULL);
+ ret = -ENXIO;
+ } else {
+ wl->assoc_stat = GELIC_WL_ASSOC_STAT_ASSOCIATED;
+ /* copy bssid */
+ memcpy(wl->active_bssid, &bss->hwinfo->bssid[2], ETH_ALEN);
+
+ /* send connect event */
+ gelic_wl_send_iwap_event(wl, wl->active_bssid);
+ pr_info("%s: connected\n", __func__);
+ }
+out:
+ pr_debug("%s: ->\n", __func__);
+ return ret;
+}
+
+/*
+ * connected event
+ */
+static void gelic_wl_connected_event(struct gelic_wl_info *wl,
+ u64 event)
+{
+ u64 desired_event = 0;
+
+ switch (wl->wpa_level) {
+ case GELIC_WL_WPA_LEVEL_NONE:
+ desired_event = GELIC_LV1_WL_EVENT_CONNECTED;
+ break;
+ case GELIC_WL_WPA_LEVEL_WPA:
+ case GELIC_WL_WPA_LEVEL_WPA2:
+ desired_event = GELIC_LV1_WL_EVENT_WPA_CONNECTED;
+ break;
+ }
+
+ if (desired_event == event) {
+ pr_debug("%s: completed \n", __func__);
+ complete(&wl->assoc_done);
+ netif_carrier_on(port_to_netdev(wl_port(wl)));
+ } else
+ pr_debug("%s: event %#lx under wpa\n",
+ __func__, event);
+}
+
+/*
+ * disconnect event
+ */
+static void gelic_wl_disconnect_event(struct gelic_wl_info *wl,
+ u64 event)
+{
+ struct gelic_eurus_cmd *cmd;
+ int lock;
+
+ /*
+ * If we fall here in the middle of association,
+ * associate_bss() should be waiting for complation of
+ * wl->assoc_done.
+ * As it waits with timeout, just leave assoc_done
+ * uncompleted, then it terminates with timeout
+ */
+ if (down_trylock(&wl->assoc_stat_lock)) {
+ pr_debug("%s: already locked\n", __func__);
+ lock = 0;
+ } else {
+ pr_debug("%s: obtain lock\n", __func__);
+ lock = 1;
+ }
+
+ cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_DISASSOC, NULL, 0);
+ kfree(cmd);
+
+ /* send disconnected event to the supplicant */
+ if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED)
+ gelic_wl_send_iwap_event(wl, NULL);
+
+ wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN;
+ netif_carrier_off(port_to_netdev(wl_port(wl)));
+
+ if (lock)
+ up(&wl->assoc_stat_lock);
+}
+/*
+ * event worker
+ */
+#ifdef DEBUG
+static const char *eventstr(enum gelic_lv1_wl_event event)
+{
+ static char buf[32];
+ char *ret;
+ if (event & GELIC_LV1_WL_EVENT_DEVICE_READY)
+ ret = "EURUS_READY";
+ else if (event & GELIC_LV1_WL_EVENT_SCAN_COMPLETED)
+ ret = "SCAN_COMPLETED";
+ else if (event & GELIC_LV1_WL_EVENT_DEAUTH)
+ ret = "DEAUTH";
+ else if (event & GELIC_LV1_WL_EVENT_BEACON_LOST)
+ ret = "BEACON_LOST";
+ else if (event & GELIC_LV1_WL_EVENT_CONNECTED)
+ ret = "CONNECTED";
+ else if (event & GELIC_LV1_WL_EVENT_WPA_CONNECTED)
+ ret = "WPA_CONNECTED";
+ else if (event & GELIC_LV1_WL_EVENT_WPA_ERROR)
+ ret = "WPA_ERROR";
+ else {
+ sprintf(buf, "Unknown(%#x)", event);
+ ret = buf;
+ }
+ return ret;
+}
+#else
+static const char *eventstr(enum gelic_lv1_wl_event event)
+{
+ return NULL;
+}
+#endif
+static void gelic_wl_event_worker(struct work_struct *work)
+{
+ struct gelic_wl_info *wl;
+ struct gelic_port *port;
+ u64 event, tmp;
+ int status;
+
+ pr_debug("%s:start\n", __func__);
+ wl = container_of(work, struct gelic_wl_info, event_work.work);
+ port = wl_port(wl);
+ while (1) {
+ status = lv1_net_control(bus_id(port->card), dev_id(port->card),
+ GELIC_LV1_GET_WLAN_EVENT, 0, 0, 0,
+ &event, &tmp);
+ if (status) {
+ if (status != LV1_NO_ENTRY)
+ pr_debug("%s:wlan event failed %d\n",
+ __func__, status);
+ /* got all events */
+ pr_debug("%s:end\n", __func__);
+ return;
+ }
+ pr_debug("%s: event=%s\n", __func__, eventstr(event));
+ switch (event) {
+ case GELIC_LV1_WL_EVENT_SCAN_COMPLETED:
+ gelic_wl_scan_complete_event(wl);
+ break;
+ case GELIC_LV1_WL_EVENT_BEACON_LOST:
+ case GELIC_LV1_WL_EVENT_DEAUTH:
+ gelic_wl_disconnect_event(wl, event);
+ break;
+ case GELIC_LV1_WL_EVENT_CONNECTED:
+ case GELIC_LV1_WL_EVENT_WPA_CONNECTED:
+ gelic_wl_connected_event(wl, event);
+ break;
+ default:
+ break;
+ }
+ } /* while */
+}
+/*
+ * association worker
+ */
+static void gelic_wl_assoc_worker(struct work_struct *work)
+{
+ struct gelic_wl_info *wl;
+
+ struct gelic_wl_scan_info *best_bss;
+ int ret;
+
+ wl = container_of(work, struct gelic_wl_info, assoc_work.work);
+
+ down(&wl->assoc_stat_lock);
+
+ if (wl->assoc_stat != GELIC_WL_ASSOC_STAT_DISCONN)
+ goto out;
+
+ ret = gelic_wl_start_scan(wl, 0);
+ if (ret == -ERESTARTSYS) {
+ pr_debug("%s: scan start failed association\n", __func__);
+ schedule_delayed_work(&wl->assoc_work, HZ/10); /*FIXME*/
+ goto out;
+ } else if (ret) {
+ pr_info("%s: scan prerequisite failed\n", __func__);
+ goto out;
+ }
+
+ /*
+ * Wait for bss scan completion
+ * If we have scan list already, gelic_wl_start_scan()
+ * returns OK and raises the complete. Thus,
+ * it's ok to wait unconditionally here
+ */
+ wait_for_completion(&wl->scan_done);
+
+ pr_debug("%s: scan done\n", __func__);
+ down(&wl->scan_lock);
+ if (wl->scan_stat != GELIC_WL_SCAN_STAT_GOT_LIST) {
+ gelic_wl_send_iwap_event(wl, NULL);
+ pr_info("%s: no scan list. association failed\n", __func__);
+ goto scan_lock_out;
+ }
+
+ /* find best matching bss */
+ best_bss = gelic_wl_find_best_bss(wl);
+ if (!best_bss) {
+ gelic_wl_send_iwap_event(wl, NULL);
+ pr_info("%s: no bss matched. association failed\n", __func__);
+ goto scan_lock_out;
+ }
+
+ /* ok, do association */
+ ret = gelic_wl_associate_bss(wl, best_bss);
+ if (ret)
+ pr_info("%s: association failed %d\n", __func__, ret);
+scan_lock_out:
+ up(&wl->scan_lock);
+out:
+ up(&wl->assoc_stat_lock);
+}
+/*
+ * Interrupt handler
+ * Called from the ethernet interrupt handler
+ * Processes wireless specific virtual interrupts only
+ */
+void gelic_wl_interrupt(struct net_device *netdev, u64 status)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+
+ if (status & GELIC_CARD_WLAN_COMMAND_COMPLETED) {
+ pr_debug("%s:cmd complete\n", __func__);
+ complete(&wl->cmd_done_intr);
+ }
+
+ if (status & GELIC_CARD_WLAN_EVENT_RECEIVED) {
+ pr_debug("%s:event received\n", __func__);
+ queue_delayed_work(wl->event_queue, &wl->event_work, 0);
+ }
+}
+
+/*
+ * driver helpers
+ */
+#define IW_IOCTL(n) [(n) - SIOCSIWCOMMIT]
+static const iw_handler gelic_wl_wext_handler[] =
+{
+ IW_IOCTL(SIOCGIWNAME) = gelic_wl_get_name,
+ IW_IOCTL(SIOCGIWRANGE) = gelic_wl_get_range,
+ IW_IOCTL(SIOCSIWSCAN) = gelic_wl_set_scan,
+ IW_IOCTL(SIOCGIWSCAN) = gelic_wl_get_scan,
+ IW_IOCTL(SIOCSIWAUTH) = gelic_wl_set_auth,
+ IW_IOCTL(SIOCGIWAUTH) = gelic_wl_get_auth,
+ IW_IOCTL(SIOCSIWESSID) = gelic_wl_set_essid,
+ IW_IOCTL(SIOCGIWESSID) = gelic_wl_get_essid,
+ IW_IOCTL(SIOCSIWENCODE) = gelic_wl_set_encode,
+ IW_IOCTL(SIOCGIWENCODE) = gelic_wl_get_encode,
+ IW_IOCTL(SIOCSIWAP) = gelic_wl_set_ap,
+ IW_IOCTL(SIOCGIWAP) = gelic_wl_get_ap,
+ IW_IOCTL(SIOCSIWENCODEEXT) = gelic_wl_set_encodeext,
+ IW_IOCTL(SIOCGIWENCODEEXT) = gelic_wl_get_encodeext,
+ IW_IOCTL(SIOCSIWMODE) = gelic_wl_set_mode,
+ IW_IOCTL(SIOCGIWMODE) = gelic_wl_get_mode,
+ IW_IOCTL(SIOCGIWNICKN) = gelic_wl_get_nick,
+};
+
+static struct iw_priv_args gelic_wl_private_args[] =
+{
+ {
+ .cmd = GELIC_WL_PRIV_SET_PSK,
+ .set_args = IW_PRIV_TYPE_CHAR |
+ (GELIC_WL_EURUS_PSK_MAX_LEN + 2),
+ .name = "set_psk"
+ },
+ {
+ .cmd = GELIC_WL_PRIV_GET_PSK,
+ .get_args = IW_PRIV_TYPE_CHAR |
+ (GELIC_WL_EURUS_PSK_MAX_LEN + 2),
+ .name = "get_psk"
+ }
+};
+
+static const iw_handler gelic_wl_private_handler[] =
+{
+ gelic_wl_priv_set_psk,
+ gelic_wl_priv_get_psk,
+};
+
+static const struct iw_handler_def gelic_wl_wext_handler_def = {
+ .num_standard = ARRAY_SIZE(gelic_wl_wext_handler),
+ .standard = gelic_wl_wext_handler,
+ .get_wireless_stats = gelic_wl_get_wireless_stats,
+ .num_private = ARRAY_SIZE(gelic_wl_private_handler),
+ .num_private_args = ARRAY_SIZE(gelic_wl_private_args),
+ .private = gelic_wl_private_handler,
+ .private_args = gelic_wl_private_args,
+};
+
+static struct net_device *gelic_wl_alloc(struct gelic_card *card)
+{
+ struct net_device *netdev;
+ struct gelic_port *port;
+ struct gelic_wl_info *wl;
+ unsigned int i;
+
+ pr_debug("%s:start\n", __func__);
+ netdev = alloc_etherdev(sizeof(struct gelic_port) +
+ sizeof(struct gelic_wl_info));
+ pr_debug("%s: netdev =%p card=%p \np", __func__, netdev, card);
+ if (!netdev)
+ return NULL;
+
+ port = netdev_priv(netdev);
+ port->netdev = netdev;
+ port->card = card;
+ port->type = GELIC_PORT_WIRELESS;
+
+ wl = port_wl(port);
+ pr_debug("%s: wl=%p port=%p\n", __func__, wl, port);
+
+ /* allocate scan list */
+ wl->networks = kzalloc(sizeof(struct gelic_wl_scan_info) *
+ GELIC_WL_BSS_MAX_ENT, GFP_KERNEL);
+
+ if (!wl->networks)
+ goto fail_bss;
+
+ wl->eurus_cmd_queue = create_singlethread_workqueue("gelic_cmd");
+ if (!wl->eurus_cmd_queue)
+ goto fail_cmd_workqueue;
+
+ wl->event_queue = create_singlethread_workqueue("gelic_event");
+ if (!wl->event_queue)
+ goto fail_event_workqueue;
+
+ INIT_LIST_HEAD(&wl->network_free_list);
+ INIT_LIST_HEAD(&wl->network_list);
+ for (i = 0; i < GELIC_WL_BSS_MAX_ENT; i++)
+ list_add_tail(&wl->networks[i].list,
+ &wl->network_free_list);
+ init_completion(&wl->cmd_done_intr);
+
+ INIT_DELAYED_WORK(&wl->event_work, gelic_wl_event_worker);
+ INIT_DELAYED_WORK(&wl->assoc_work, gelic_wl_assoc_worker);
+ init_MUTEX(&wl->scan_lock);
+ init_MUTEX(&wl->assoc_stat_lock);
+
+ init_completion(&wl->scan_done);
+ /* for the case that no scan request is issued and stop() is called */
+ complete(&wl->scan_done);
+
+ spin_lock_init(&wl->lock);
+
+ wl->scan_age = 5*HZ; /* FIXME */
+
+ /* buffer for receiving scanned list etc */
+ BUILD_BUG_ON(PAGE_SIZE <
+ sizeof(struct gelic_eurus_scan_info) *
+ GELIC_EURUS_MAX_SCAN);
+ wl->buf = (void *)get_zeroed_page(GFP_KERNEL);
+ if (!wl->buf) {
+ pr_info("%s:buffer allocation failed\n", __func__);
+ goto fail_getpage;
+ }
+ pr_debug("%s:end\n", __func__);
+ return netdev;
+
+fail_getpage:
+ destroy_workqueue(wl->event_queue);
+fail_event_workqueue:
+ destroy_workqueue(wl->eurus_cmd_queue);
+fail_cmd_workqueue:
+ kfree(wl->networks);
+fail_bss:
+ free_netdev(netdev);
+ pr_debug("%s:end error\n", __func__);
+ return NULL;
+
+}
+
+static void gelic_wl_free(struct gelic_wl_info *wl)
+{
+ struct gelic_wl_scan_info *scan_info;
+ unsigned int i;
+
+ pr_debug("%s: <-\n", __func__);
+
+ pr_debug("%s: destroy queues\n", __func__);
+ destroy_workqueue(wl->eurus_cmd_queue);
+ destroy_workqueue(wl->event_queue);
+
+ scan_info = wl->networks;
+ for (i = 0; i < GELIC_WL_BSS_MAX_ENT; i++, scan_info++)
+ kfree(scan_info->hwinfo);
+ kfree(wl->networks);
+
+ free_netdev(port_to_netdev(wl_port(wl)));
+
+ pr_debug("%s: ->\n", __func__);
+}
+
+static int gelic_wl_try_associate(struct net_device *netdev)
+{
+ struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+ int ret = -1;
+ unsigned int i;
+
+ pr_debug("%s: <-\n", __func__);
+
+ /* check constraits for start association */
+ /* for no access restriction AP */
+ if (wl->group_cipher_method == GELIC_WL_CIPHER_NONE) {
+ if (test_bit(GELIC_WL_STAT_CONFIGURED,
+ &wl->stat))
+ goto do_associate;
+ else {
+ pr_debug("%s: no wep, not configured\n", __func__);
+ return ret;
+ }
+ }
+
+ /* for WEP, one of four keys should be set */
+ if (wl->group_cipher_method == GELIC_WL_CIPHER_WEP) {
+ /* one of keys set */
+ for (i = 0; i < GELIC_WEP_KEYS; i++) {
+ if (test_bit(i, &wl->key_enabled))
+ goto do_associate;
+ }
+ pr_debug("%s: WEP, but no key specified\n", __func__);
+ return ret;
+ }
+
+ /* for WPA[2], psk should be set */
+ if ((wl->group_cipher_method == GELIC_WL_CIPHER_TKIP) ||
+ (wl->group_cipher_method == GELIC_WL_CIPHER_AES)) {
+ if (test_bit(GELIC_WL_STAT_WPA_PSK_SET,
+ &wl->stat))
+ goto do_associate;
+ else {
+ pr_debug("%s: AES/TKIP, but PSK not configured\n",
+ __func__);
+ return ret;
+ }
+ }
+
+do_associate:
+ ret = schedule_delayed_work(&wl->assoc_work, 0);
+ pr_debug("%s: start association work %d\n", __func__, ret);
+ return ret;
+}
+
+/*
+ * netdev handlers
+ */
+static int gelic_wl_open(struct net_device *netdev)
+{
+ struct gelic_card *card = netdev_card(netdev);
+
+ pr_debug("%s:->%p\n", __func__, netdev);
+
+ gelic_card_up(card);
+
+ /* try to associate */
+ gelic_wl_try_associate(netdev);
+
+ netif_start_queue(netdev);
+
+ pr_debug("%s:<-\n", __func__);
+ return 0;
+}
+
+/*
+ * reset state machine
+ */
+static int gelic_wl_reset_state(struct gelic_wl_info *wl)
+{
+ struct gelic_wl_scan_info *target;
+ struct gelic_wl_scan_info *tmp;
+
+ /* empty scan list */
+ list_for_each_entry_safe(target, tmp, &wl->network_list, list) {
+ list_move_tail(&target->list, &wl->network_free_list);
+ }
+ wl->scan_stat = GELIC_WL_SCAN_STAT_INIT;
+
+ /* clear configuration */
+ wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+ wl->group_cipher_method = GELIC_WL_CIPHER_NONE;
+ wl->pairwise_cipher_method = GELIC_WL_CIPHER_NONE;
+ wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE;
+
+ wl->key_enabled = 0;
+ wl->current_key = 0;
+
+ wl->psk_type = GELIC_EURUS_WPA_PSK_PASSPHRASE;
+ wl->psk_len = 0;
+
+ wl->essid_len = 0;
+ memset(wl->essid, 0, sizeof(wl->essid));
+ memset(wl->bssid, 0, sizeof(wl->bssid));
+ memset(wl->active_bssid, 0, sizeof(wl->active_bssid));
+
+ wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN;
+
+ memset(&wl->iwstat, 0, sizeof(wl->iwstat));
+ /* all status bit clear */
+ wl->stat = 0;
+ return 0;
+}
+
+/*
+ * Tell eurus to terminate association
+ */
+static void gelic_wl_disconnect(struct net_device *netdev)
+{
+ struct gelic_port *port = netdev_priv(netdev);
+ struct gelic_wl_info *wl = port_wl(port);
+ struct gelic_eurus_cmd *cmd;
+
+ /*
+ * If scann process is running on chip,
+ * further requests will be rejected
+ */
+ if (wl->scan_stat == GELIC_WL_SCAN_STAT_SCANNING)
+ wait_for_completion_timeout(&wl->scan_done, HZ);
+
+ cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_DISASSOC, NULL, 0);
+ kfree(cmd);
+ gelic_wl_send_iwap_event(wl, NULL);
+};
+
+static int gelic_wl_stop(struct net_device *netdev)
+{
+ struct gelic_port *port = netdev_priv(netdev);
+ struct gelic_wl_info *wl = port_wl(port);
+ struct gelic_card *card = netdev_card(netdev);
+
+ pr_debug("%s:<-\n", __func__);
+
+ /*
+ * Cancel pending association work.
+ * event work can run after netdev down
+ */
+ cancel_delayed_work(&wl->assoc_work);
+
+ if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED)
+ gelic_wl_disconnect(netdev);
+
+ /* reset our state machine */
+ gelic_wl_reset_state(wl);
+
+ netif_stop_queue(netdev);
+
+ gelic_card_down(card);
+
+ pr_debug("%s:->\n", __func__);
+ return 0;
+}
+
+/* -- */
+
+static struct ethtool_ops gelic_wl_ethtool_ops = {
+ .get_drvinfo = gelic_net_get_drvinfo,
+ .get_link = gelic_wl_get_link,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
+ .get_rx_csum = gelic_net_get_rx_csum,
+ .set_rx_csum = gelic_net_set_rx_csum,
+};
+
+static void gelic_wl_setup_netdev_ops(struct net_device *netdev)
+{
+ struct gelic_wl_info *wl;
+ wl = port_wl(netdev_priv(netdev));
+ BUG_ON(!wl);
+ netdev->open = &gelic_wl_open;
+ netdev->stop = &gelic_wl_stop;
+ netdev->hard_start_xmit = &gelic_net_xmit;
+ netdev->set_multicast_list = &gelic_net_set_multi;
+ netdev->change_mtu = &gelic_net_change_mtu;
+ netdev->wireless_data = &wl->wireless_data;
+ netdev->wireless_handlers = &gelic_wl_wext_handler_def;
+ /* tx watchdog */
+ netdev->tx_timeout = &gelic_net_tx_timeout;
+ netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
+
+ netdev->ethtool_ops = &gelic_wl_ethtool_ops;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ netdev->poll_controller = gelic_net_poll_controller;
+#endif
+}
+
+/*
+ * driver probe/remove
+ */
+int gelic_wl_driver_probe(struct gelic_card *card)
+{
+ int ret;
+ struct net_device *netdev;
+
+ pr_debug("%s:start\n", __func__);
+
+ if (ps3_compare_firmware_version(1, 6, 0) < 0)
+ return 0;
+ if (!card->vlan[GELIC_PORT_WIRELESS].tx)
+ return 0;
+
+ /* alloc netdevice for wireless */
+ netdev = gelic_wl_alloc(card);
+ if (!netdev)
+ return -ENOMEM;
+
+ /* setup net_device structure */
+ SET_NETDEV_DEV(netdev, &card->dev->core);
+ gelic_wl_setup_netdev_ops(netdev);
+
+ /* setup some of net_device and register it */
+ ret = gelic_net_setup_netdev(netdev, card);
+ if (ret)
+ goto fail_setup;
+ card->netdev[GELIC_PORT_WIRELESS] = netdev;
+
+ /* add enable wireless interrupt */
+ card->irq_mask |= GELIC_CARD_WLAN_EVENT_RECEIVED |
+ GELIC_CARD_WLAN_COMMAND_COMPLETED;
+ /* to allow wireless commands while both interfaces are down */
+ gelic_card_set_irq_mask(card, GELIC_CARD_WLAN_EVENT_RECEIVED |
+ GELIC_CARD_WLAN_COMMAND_COMPLETED);
+ pr_debug("%s:end\n", __func__);
+ return 0;
+
+fail_setup:
+ gelic_wl_free(port_wl(netdev_port(netdev)));
+
+ return ret;
+}
+
+int gelic_wl_driver_remove(struct gelic_card *card)
+{
+ struct gelic_wl_info *wl;
+ struct net_device *netdev;
+
+ pr_debug("%s:start\n", __func__);
+
+ if (ps3_compare_firmware_version(1, 6, 0) < 0)
+ return 0;
+ if (!card->vlan[GELIC_PORT_WIRELESS].tx)
+ return 0;
+
+ netdev = card->netdev[GELIC_PORT_WIRELESS];
+ wl = port_wl(netdev_priv(netdev));
+
+ /* if the interface was not up, but associated */
+ if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED)
+ gelic_wl_disconnect(netdev);
+
+ complete(&wl->cmd_done_intr);
+
+ /* cancel all work queue */
+ cancel_delayed_work(&wl->assoc_work);
+ cancel_delayed_work(&wl->event_work);
+ flush_workqueue(wl->eurus_cmd_queue);
+ flush_workqueue(wl->event_queue);
+
+ unregister_netdev(netdev);
+
+ /* disable wireless interrupt */
+ pr_debug("%s: disable intr\n", __func__);
+ card->irq_mask &= ~(GELIC_CARD_WLAN_EVENT_RECEIVED |
+ GELIC_CARD_WLAN_COMMAND_COMPLETED);
+ /* free bss list, netdev*/
+ gelic_wl_free(wl);
+ pr_debug("%s:end\n", __func__);
+ return 0;
+}
diff --git a/drivers/net/ps3_gelic_wireless.h b/drivers/net/ps3_gelic_wireless.h
new file mode 100644
index 00000000000..10369716672
--- /dev/null
+++ b/drivers/net/ps3_gelic_wireless.h
@@ -0,0 +1,329 @@
+/*
+ * PS3 gelic network driver.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corporation
+ *
+ * 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 version 2.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _GELIC_WIRELESS_H
+#define _GELIC_WIRELESS_H
+
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+
+
+/* return value from GELIC_LV1_GET_WLAN_EVENT netcontrol */
+enum gelic_lv1_wl_event {
+ GELIC_LV1_WL_EVENT_DEVICE_READY = 0x01, /* Eurus ready */
+ GELIC_LV1_WL_EVENT_SCAN_COMPLETED = 0x02, /* Scan has completed */
+ GELIC_LV1_WL_EVENT_DEAUTH = 0x04, /* Deauthed by the AP */
+ GELIC_LV1_WL_EVENT_BEACON_LOST = 0x08, /* Beacon lost detected */
+ GELIC_LV1_WL_EVENT_CONNECTED = 0x10, /* Connected to AP */
+ GELIC_LV1_WL_EVENT_WPA_CONNECTED = 0x20, /* WPA connection */
+ GELIC_LV1_WL_EVENT_WPA_ERROR = 0x40, /* MIC error */
+};
+
+/* arguments for GELIC_LV1_POST_WLAN_COMMAND netcontrol */
+enum gelic_eurus_command {
+ GELIC_EURUS_CMD_ASSOC = 1, /* association start */
+ GELIC_EURUS_CMD_DISASSOC = 2, /* disassociate */
+ GELIC_EURUS_CMD_START_SCAN = 3, /* scan start */
+ GELIC_EURUS_CMD_GET_SCAN = 4, /* get scan result */
+ GELIC_EURUS_CMD_SET_COMMON_CFG = 5, /* set common config */
+ GELIC_EURUS_CMD_GET_COMMON_CFG = 6, /* set common config */
+ GELIC_EURUS_CMD_SET_WEP_CFG = 7, /* set WEP config */
+ GELIC_EURUS_CMD_GET_WEP_CFG = 8, /* get WEP config */
+ GELIC_EURUS_CMD_SET_WPA_CFG = 9, /* set WPA config */
+ GELIC_EURUS_CMD_GET_WPA_CFG = 10, /* get WPA config */
+ GELIC_EURUS_CMD_GET_RSSI_CFG = 11, /* get RSSI info. */
+ GELIC_EURUS_CMD_MAX_INDEX
+};
+
+/* for GELIC_EURUS_CMD_COMMON_CFG */
+enum gelic_eurus_bss_type {
+ GELIC_EURUS_BSS_INFRA = 0,
+ GELIC_EURUS_BSS_ADHOC = 1, /* not supported */
+};
+
+enum gelic_eurus_auth_method {
+ GELIC_EURUS_AUTH_OPEN = 0, /* FIXME: WLAN_AUTH_OPEN */
+ GELIC_EURUS_AUTH_SHARED = 1, /* not supported */
+};
+
+enum gelic_eurus_opmode {
+ GELIC_EURUS_OPMODE_11BG = 0, /* 802.11b/g */
+ GELIC_EURUS_OPMODE_11B = 1, /* 802.11b only */
+ GELIC_EURUS_OPMODE_11G = 2, /* 802.11g only */
+};
+
+struct gelic_eurus_common_cfg {
+ /* all fields are big endian */
+ u16 scan_index;
+ u16 bss_type; /* infra or adhoc */
+ u16 auth_method; /* shared key or open */
+ u16 op_mode; /* B/G */
+} __attribute__((packed));
+
+
+/* for GELIC_EURUS_CMD_WEP_CFG */
+enum gelic_eurus_wep_security {
+ GELIC_EURUS_WEP_SEC_NONE = 0,
+ GELIC_EURUS_WEP_SEC_40BIT = 1,
+ GELIC_EURUS_WEP_SEC_104BIT = 2,
+};
+
+struct gelic_eurus_wep_cfg {
+ /* all fields are big endian */
+ u16 security;
+ u8 key[4][16];
+} __attribute__((packed));
+
+/* for GELIC_EURUS_CMD_WPA_CFG */
+enum gelic_eurus_wpa_security {
+ GELIC_EURUS_WPA_SEC_NONE = 0x0000,
+ /* group=TKIP, pairwise=TKIP */
+ GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP = 0x0001,
+ /* group=AES, pairwise=AES */
+ GELIC_EURUS_WPA_SEC_WPA_AES_AES = 0x0002,
+ /* group=TKIP, pairwise=TKIP */
+ GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP = 0x0004,
+ /* group=AES, pairwise=AES */
+ GELIC_EURUS_WPA_SEC_WPA2_AES_AES = 0x0008,
+ /* group=TKIP, pairwise=AES */
+ GELIC_EURUS_WPA_SEC_WPA_TKIP_AES = 0x0010,
+ /* group=TKIP, pairwise=AES */
+ GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES = 0x0020,
+};
+
+enum gelic_eurus_wpa_psk_type {
+ GELIC_EURUS_WPA_PSK_PASSPHRASE = 0, /* passphrase string */
+ GELIC_EURUS_WPA_PSK_BIN = 1, /* 32 bytes binary key */
+};
+
+#define GELIC_WL_EURUS_PSK_MAX_LEN 64
+#define WPA_PSK_LEN 32 /* WPA spec says 256bit */
+
+struct gelic_eurus_wpa_cfg {
+ /* all fields are big endian */
+ u16 security;
+ u16 psk_type; /* psk key encoding type */
+ u8 psk[GELIC_WL_EURUS_PSK_MAX_LEN]; /* psk key; hex or passphrase */
+} __attribute__((packed));
+
+/* for GELIC_EURUS_CMD_{START,GET}_SCAN */
+enum gelic_eurus_scan_capability {
+ GELIC_EURUS_SCAN_CAP_ADHOC = 0x0000,
+ GELIC_EURUS_SCAN_CAP_INFRA = 0x0001,
+ GELIC_EURUS_SCAN_CAP_MASK = 0x0001,
+};
+
+enum gelic_eurus_scan_sec_type {
+ GELIC_EURUS_SCAN_SEC_NONE = 0x0000,
+ GELIC_EURUS_SCAN_SEC_WEP = 0x0100,
+ GELIC_EURUS_SCAN_SEC_WPA = 0x0200,
+ GELIC_EURUS_SCAN_SEC_WPA2 = 0x0400,
+ GELIC_EURUS_SCAN_SEC_MASK = 0x0f00,
+};
+
+enum gelic_eurus_scan_sec_wep_type {
+ GELIC_EURUS_SCAN_SEC_WEP_UNKNOWN = 0x0000,
+ GELIC_EURUS_SCAN_SEC_WEP_40 = 0x0001,
+ GELIC_EURUS_SCAN_SEC_WEP_104 = 0x0002,
+ GELIC_EURUS_SCAN_SEC_WEP_MASK = 0x0003,
+};
+
+enum gelic_eurus_scan_sec_wpa_type {
+ GELIC_EURUS_SCAN_SEC_WPA_UNKNOWN = 0x0000,
+ GELIC_EURUS_SCAN_SEC_WPA_TKIP = 0x0001,
+ GELIC_EURUS_SCAN_SEC_WPA_AES = 0x0002,
+ GELIC_EURUS_SCAN_SEC_WPA_MASK = 0x0003,
+};
+
+/*
+ * hw BSS information structure returned from GELIC_EURUS_CMD_GET_SCAN
+ */
+struct gelic_eurus_scan_info {
+ /* all fields are big endian */
+ __be16 size;
+ __be16 rssi; /* percentage */
+ __be16 channel; /* channel number */
+ __be16 beacon_period; /* FIXME: in msec unit */
+ __be16 capability;
+ __be16 security;
+ u8 bssid[8]; /* last ETH_ALEN are valid. bssid[0],[1] are unused */
+ u8 essid[32]; /* IW_ESSID_MAX_SIZE */
+ u8 rate[16]; /* first MAX_RATES_LENGTH(12) are valid */
+ u8 ext_rate[16]; /* first MAX_RATES_EX_LENGTH(16) are valid */
+ __be32 reserved1;
+ __be32 reserved2;
+ __be32 reserved3;
+ __be32 reserved4;
+ u8 elements[0]; /* ie */
+} __attribute__ ((packed));
+
+/* the hypervisor returns bbs up to 16 */
+#define GELIC_EURUS_MAX_SCAN (16)
+struct gelic_wl_scan_info {
+ struct list_head list;
+ struct gelic_eurus_scan_info *hwinfo;
+
+ int valid; /* set 1 if this entry was in latest scanned list
+ * from Eurus */
+ unsigned int eurus_index; /* index in the Eurus list */
+ unsigned long last_scanned; /* acquired time */
+
+ unsigned int rate_len;
+ unsigned int rate_ext_len;
+ unsigned int essid_len;
+};
+
+/* for GELIC_EURUS_CMD_GET_RSSI */
+struct gelic_eurus_rssi_info {
+ /* big endian */
+ __be16 rssi;
+} __attribute__ ((packed));
+
+
+/* for 'stat' member of gelic_wl_info */
+enum gelic_wl_info_status_bit {
+ GELIC_WL_STAT_CONFIGURED,
+ GELIC_WL_STAT_CH_INFO, /* ch info aquired */
+ GELIC_WL_STAT_ESSID_SET, /* ESSID specified by userspace */
+ GELIC_WL_STAT_BSSID_SET, /* BSSID specified by userspace */
+ GELIC_WL_STAT_WPA_PSK_SET, /* PMK specified by userspace */
+ GELIC_WL_STAT_WPA_LEVEL_SET, /* WEP or WPA[2] selected */
+};
+
+/* for 'scan_stat' member of gelic_wl_info */
+enum gelic_wl_scan_state {
+ /* just initialized or get last scan result failed */
+ GELIC_WL_SCAN_STAT_INIT,
+ /* scan request issued, accepted or chip is scanning */
+ GELIC_WL_SCAN_STAT_SCANNING,
+ /* scan results retrieved */
+ GELIC_WL_SCAN_STAT_GOT_LIST,
+};
+
+/* for 'cipher_method' */
+enum gelic_wl_cipher_method {
+ GELIC_WL_CIPHER_NONE,
+ GELIC_WL_CIPHER_WEP,
+ GELIC_WL_CIPHER_TKIP,
+ GELIC_WL_CIPHER_AES,
+};
+
+/* for 'wpa_level' */
+enum gelic_wl_wpa_level {
+ GELIC_WL_WPA_LEVEL_NONE,
+ GELIC_WL_WPA_LEVEL_WPA,
+ GELIC_WL_WPA_LEVEL_WPA2,
+};
+
+/* for 'assoc_stat' */
+enum gelic_wl_assoc_state {
+ GELIC_WL_ASSOC_STAT_DISCONN,
+ GELIC_WL_ASSOC_STAT_ASSOCIATING,
+ GELIC_WL_ASSOC_STAT_ASSOCIATED,
+};
+/* part of private data alloc_etherdev() allocated */
+#define GELIC_WEP_KEYS 4
+struct gelic_wl_info {
+ /* bss list */
+ struct semaphore scan_lock;
+ struct list_head network_list;
+ struct list_head network_free_list;
+ struct gelic_wl_scan_info *networks;
+
+ unsigned long scan_age; /* last scanned time */
+ enum gelic_wl_scan_state scan_stat;
+ struct completion scan_done;
+
+ /* eurus command queue */
+ struct workqueue_struct *eurus_cmd_queue;
+ struct completion cmd_done_intr;
+
+ /* eurus event handling */
+ struct workqueue_struct *event_queue;
+ struct delayed_work event_work;
+
+ /* wl status bits */
+ unsigned long stat;
+ enum gelic_eurus_auth_method auth_method; /* open/shared */
+ enum gelic_wl_cipher_method group_cipher_method;
+ enum gelic_wl_cipher_method pairwise_cipher_method;
+ enum gelic_wl_wpa_level wpa_level; /* wpa/wpa2 */
+
+ /* association handling */
+ struct semaphore assoc_stat_lock;
+ struct delayed_work assoc_work;
+ enum gelic_wl_assoc_state assoc_stat;
+ struct completion assoc_done;
+
+ spinlock_t lock;
+ u16 ch_info; /* available channels. bit0 = ch1 */
+ /* WEP keys */
+ u8 key[GELIC_WEP_KEYS][IW_ENCODING_TOKEN_MAX];
+ unsigned long key_enabled;
+ unsigned int key_len[GELIC_WEP_KEYS];
+ unsigned int current_key;
+ /* WWPA PSK */
+ u8 psk[GELIC_WL_EURUS_PSK_MAX_LEN];
+ enum gelic_eurus_wpa_psk_type psk_type;
+ unsigned int psk_len;
+
+ u8 essid[IW_ESSID_MAX_SIZE];
+ u8 bssid[ETH_ALEN]; /* userland requested */
+ u8 active_bssid[ETH_ALEN]; /* associated bssid */
+ unsigned int essid_len;
+
+ /* buffer for hypervisor IO */
+ void *buf;
+
+ struct iw_public_data wireless_data;
+ struct iw_statistics iwstat;
+};
+
+#define GELIC_WL_BSS_MAX_ENT 32
+#define GELIC_WL_ASSOC_RETRY 50
+static inline struct gelic_port *wl_port(struct gelic_wl_info *wl)
+{
+ return container_of((void *)wl, struct gelic_port, priv);
+}
+static inline struct gelic_wl_info *port_wl(struct gelic_port *port)
+{
+ return port_priv(port);
+}
+
+struct gelic_eurus_cmd {
+ struct work_struct work;
+ struct gelic_wl_info *wl;
+ unsigned int cmd; /* command code */
+ u64 tag;
+ u64 size;
+ void *buffer;
+ unsigned int buf_size;
+ struct completion done;
+ int status;
+ u64 cmd_status;
+};
+
+/* private ioctls to pass PSK */
+#define GELIC_WL_PRIV_SET_PSK (SIOCIWFIRSTPRIV + 0)
+#define GELIC_WL_PRIV_GET_PSK (SIOCIWFIRSTPRIV + 1)
+
+extern int gelic_wl_driver_probe(struct gelic_card *card);
+extern int gelic_wl_driver_remove(struct gelic_card *card);
+extern void gelic_wl_interrupt(struct net_device *netdev, u64 status);
+#endif /* _GELIC_WIRELESS_H */
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 2334f4ebf90..19184e486ae 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -61,7 +61,6 @@
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (6000 * HZ / 1000)
-#define TIMER_WUT (jiffies + HZ * 1)/* timer wakeup time : 1 second */
/* RDC MAC I/O Size */
#define R6040_IO_SIZE 256
@@ -174,8 +173,6 @@ struct r6040_private {
struct net_device *dev;
struct mii_if_info mii_if;
struct napi_struct napi;
- struct net_device_stats stats;
- u16 napi_rx_running;
void __iomem *base;
};
@@ -235,17 +232,53 @@ static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
phy_write(ioaddr, lp->phy_addr, reg, val);
}
-static void r6040_tx_timeout(struct net_device *dev)
+static void r6040_free_txbufs(struct net_device *dev)
{
- struct r6040_private *priv = netdev_priv(dev);
+ struct r6040_private *lp = netdev_priv(dev);
+ int i;
- disable_irq(dev->irq);
- napi_disable(&priv->napi);
- spin_lock(&priv->lock);
- dev->stats.tx_errors++;
- spin_unlock(&priv->lock);
+ for (i = 0; i < TX_DCNT; i++) {
+ if (lp->tx_insert_ptr->skb_ptr) {
+ pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf,
+ MAX_BUF_SIZE, PCI_DMA_TODEVICE);
+ dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
+ lp->rx_insert_ptr->skb_ptr = NULL;
+ }
+ lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp;
+ }
+}
- netif_stop_queue(dev);
+static void r6040_free_rxbufs(struct net_device *dev)
+{
+ struct r6040_private *lp = netdev_priv(dev);
+ int i;
+
+ for (i = 0; i < RX_DCNT; i++) {
+ if (lp->rx_insert_ptr->skb_ptr) {
+ pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf,
+ MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
+ lp->rx_insert_ptr->skb_ptr = NULL;
+ }
+ lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp;
+ }
+}
+
+static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring,
+ dma_addr_t desc_dma, int size)
+{
+ struct r6040_descriptor *desc = desc_ring;
+ dma_addr_t mapping = desc_dma;
+
+ while (size-- > 0) {
+ mapping += sizeof(sizeof(*desc));
+ desc->ndesc = cpu_to_le32(mapping);
+ desc->vndescp = desc + 1;
+ desc++;
+ }
+ desc--;
+ desc->ndesc = cpu_to_le32(desc_dma);
+ desc->vndescp = desc_ring;
}
/* Allocate skb buffer for rx descriptor */
@@ -256,7 +289,7 @@ static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
descptr = lp->rx_insert_ptr;
while (lp->rx_free_desc < RX_DCNT) {
- descptr->skb_ptr = dev_alloc_skb(MAX_BUF_SIZE);
+ descptr->skb_ptr = netdev_alloc_skb(dev, MAX_BUF_SIZE);
if (!descptr->skb_ptr)
break;
@@ -272,6 +305,63 @@ static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
lp->rx_insert_ptr = descptr;
}
+static void r6040_alloc_txbufs(struct net_device *dev)
+{
+ struct r6040_private *lp = netdev_priv(dev);
+ void __iomem *ioaddr = lp->base;
+
+ lp->tx_free_desc = TX_DCNT;
+
+ lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring;
+ r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT);
+
+ iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0);
+ iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1);
+}
+
+static void r6040_alloc_rxbufs(struct net_device *dev)
+{
+ struct r6040_private *lp = netdev_priv(dev);
+ void __iomem *ioaddr = lp->base;
+
+ lp->rx_free_desc = 0;
+
+ lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring;
+ r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT);
+
+ rx_buf_alloc(lp, dev);
+
+ iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0);
+ iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1);
+}
+
+static void r6040_tx_timeout(struct net_device *dev)
+{
+ struct r6040_private *priv = netdev_priv(dev);
+ void __iomem *ioaddr = priv->base;
+
+ printk(KERN_WARNING "%s: transmit timed out, status %4.4x, PHY status "
+ "%4.4x\n",
+ dev->name, ioread16(ioaddr + MIER),
+ mdio_read(dev, priv->mii_if.phy_id, MII_BMSR));
+
+ disable_irq(dev->irq);
+ napi_disable(&priv->napi);
+ spin_lock(&priv->lock);
+ /* Clear all descriptors */
+ r6040_free_txbufs(dev);
+ r6040_free_rxbufs(dev);
+ r6040_alloc_txbufs(dev);
+ r6040_alloc_rxbufs(dev);
+
+ /* Reset MAC */
+ iowrite16(MAC_RST, ioaddr + MCR1);
+ spin_unlock(&priv->lock);
+ enable_irq(dev->irq);
+
+ dev->stats.tx_errors++;
+ netif_wake_queue(dev);
+}
static struct net_device_stats *r6040_get_stats(struct net_device *dev)
{
@@ -280,11 +370,11 @@ static struct net_device_stats *r6040_get_stats(struct net_device *dev)
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- priv->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1);
- priv->stats.multicast += ioread8(ioaddr + ME_CNT0);
+ dev->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1);
+ dev->stats.multicast += ioread8(ioaddr + ME_CNT0);
spin_unlock_irqrestore(&priv->lock, flags);
- return &priv->stats;
+ return &dev->stats;
}
/* Stop RDC MAC and Free the allocated resource */
@@ -293,7 +383,6 @@ static void r6040_down(struct net_device *dev)
struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
struct pci_dev *pdev = lp->pdev;
- int i;
int limit = 2048;
u16 *adrp;
u16 cmd;
@@ -313,27 +402,12 @@ static void r6040_down(struct net_device *dev)
iowrite16(adrp[1], ioaddr + MID_0M);
iowrite16(adrp[2], ioaddr + MID_0H);
free_irq(dev->irq, dev);
+
/* Free RX buffer */
- for (i = 0; i < RX_DCNT; i++) {
- if (lp->rx_insert_ptr->skb_ptr) {
- pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf,
- MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
- lp->rx_insert_ptr->skb_ptr = NULL;
- }
- lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp;
- }
+ r6040_free_rxbufs(dev);
/* Free TX buffer */
- for (i = 0; i < TX_DCNT; i++) {
- if (lp->tx_insert_ptr->skb_ptr) {
- pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf,
- MAX_BUF_SIZE, PCI_DMA_TODEVICE);
- dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
- lp->rx_insert_ptr->skb_ptr = NULL;
- }
- lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp;
- }
+ r6040_free_txbufs(dev);
/* Free Descriptor memory */
pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
@@ -432,19 +506,24 @@ static int r6040_rx(struct net_device *dev, int limit)
/* Check for errors */
err = ioread16(ioaddr + MLSR);
- if (err & 0x0400) priv->stats.rx_errors++;
+ if (err & 0x0400)
+ dev->stats.rx_errors++;
/* RX FIFO over-run */
- if (err & 0x8000) priv->stats.rx_fifo_errors++;
+ if (err & 0x8000)
+ dev->stats.rx_fifo_errors++;
/* RX descriptor unavailable */
- if (err & 0x0080) priv->stats.rx_frame_errors++;
+ if (err & 0x0080)
+ dev->stats.rx_frame_errors++;
/* Received packet with length over buffer lenght */
- if (err & 0x0020) priv->stats.rx_over_errors++;
+ if (err & 0x0020)
+ dev->stats.rx_over_errors++;
/* Received packet with too long or short */
- if (err & (0x0010|0x0008)) priv->stats.rx_length_errors++;
+ if (err & (0x0010 | 0x0008))
+ dev->stats.rx_length_errors++;
/* Received packet with CRC errors */
if (err & 0x0004) {
spin_lock(&priv->lock);
- priv->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
spin_unlock(&priv->lock);
}
@@ -469,8 +548,8 @@ static int r6040_rx(struct net_device *dev, int limit)
/* Send to upper layer */
netif_receive_skb(skb_ptr);
dev->last_rx = jiffies;
- priv->dev->stats.rx_packets++;
- priv->dev->stats.rx_bytes += descptr->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += descptr->len;
/* To next descriptor */
descptr = descptr->vndescp;
priv->rx_free_desc--;
@@ -498,11 +577,13 @@ static void r6040_tx(struct net_device *dev)
/* Check for errors */
err = ioread16(ioaddr + MLSR);
- if (err & 0x0200) priv->stats.rx_fifo_errors++;
- if (err & (0x2000 | 0x4000)) priv->stats.tx_carrier_errors++;
+ if (err & 0x0200)
+ dev->stats.rx_fifo_errors++;
+ if (err & (0x2000 | 0x4000))
+ dev->stats.tx_carrier_errors++;
if (descptr->status & 0x8000)
- break; /* Not complte */
+ break; /* Not complete */
skb_ptr = descptr->skb_ptr;
pci_unmap_single(priv->pdev, descptr->buf,
skb_ptr->len, PCI_DMA_TODEVICE);
@@ -545,7 +626,6 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
u16 status;
- int handled = 1;
/* Mask off RDC MAC interrupt */
iowrite16(MSK_INT, ioaddr + MIER);
@@ -565,7 +645,7 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
if (status & 0x10)
r6040_tx(dev);
- return IRQ_RETVAL(handled);
+ return IRQ_HANDLED;
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -577,53 +657,15 @@ static void r6040_poll_controller(struct net_device *dev)
}
#endif
-static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring,
- dma_addr_t desc_dma, int size)
-{
- struct r6040_descriptor *desc = desc_ring;
- dma_addr_t mapping = desc_dma;
-
- while (size-- > 0) {
- mapping += sizeof(sizeof(*desc));
- desc->ndesc = cpu_to_le32(mapping);
- desc->vndescp = desc + 1;
- desc++;
- }
- desc--;
- desc->ndesc = cpu_to_le32(desc_dma);
- desc->vndescp = desc_ring;
-}
-
/* Init RDC MAC */
static void r6040_up(struct net_device *dev)
{
struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
- /* Initialize */
- lp->tx_free_desc = TX_DCNT;
- lp->rx_free_desc = 0;
- /* Init descriptor */
- lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring;
- lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring;
- /* Init TX descriptor */
- r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT);
-
- /* Init RX descriptor */
- r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT);
-
- /* Allocate buffer for RX descriptor */
- rx_buf_alloc(lp, dev);
-
- /*
- * TX and RX descriptor start registers.
- * Lower 16-bits to MxD_SA0. Higher 16-bits to MxD_SA1.
- */
- iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0);
- iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1);
-
- iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0);
- iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1);
+ /* Initialise and alloc RX/TX buffers */
+ r6040_alloc_txbufs(dev);
+ r6040_alloc_rxbufs(dev);
/* Buffer Size Register */
iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR);
@@ -689,8 +731,7 @@ static void r6040_timer(unsigned long data)
}
/* Timer active again */
- lp->timer.expires = TIMER_WUT;
- add_timer(&lp->timer);
+ mod_timer(&lp->timer, jiffies + round_jiffies(HZ));
}
/* Read/set MAC address routines */
@@ -746,14 +787,10 @@ static int r6040_open(struct net_device *dev)
napi_enable(&lp->napi);
netif_start_queue(dev);
- if (lp->switch_sig != ICPLUS_PHY_ID) {
- /* set and active a timer process */
- init_timer(&lp->timer);
- lp->timer.expires = TIMER_WUT;
- lp->timer.data = (unsigned long)dev;
- lp->timer.function = &r6040_timer;
- add_timer(&lp->timer);
- }
+ /* set and active a timer process */
+ setup_timer(&lp->timer, r6040_timer, (unsigned long) dev);
+ if (lp->switch_sig != ICPLUS_PHY_ID)
+ mod_timer(&lp->timer, jiffies + HZ);
return 0;
}
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 2e9e88be7b3..20745fd4e97 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1630,15 +1630,21 @@ static inline void sis190_init_rxfilter(struct net_device *dev)
SIS_PCI_COMMIT();
}
-static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev)
+static int __devinit sis190_get_mac_addr(struct pci_dev *pdev,
+ struct net_device *dev)
{
- u8 from;
+ int rc;
+
+ rc = sis190_get_mac_addr_from_eeprom(pdev, dev);
+ if (rc < 0) {
+ u8 reg;
- pci_read_config_byte(pdev, 0x73, &from);
+ pci_read_config_byte(pdev, 0x73, &reg);
- return (from & 0x00000001) ?
- sis190_get_mac_addr_from_apc(pdev, dev) :
- sis190_get_mac_addr_from_eeprom(pdev, dev);
+ if (reg & 0x00000001)
+ rc = sis190_get_mac_addr_from_apc(pdev, dev);
+ }
+ return rc;
}
static void sis190_set_speed_auto(struct net_device *dev)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 9a6295909e4..54c662690f6 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -572,8 +572,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
default:
/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
+
/* turn off the Rx LED (LED_RX) */
- ledover &= ~PHY_M_LED_MO_RX;
+ ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
}
if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
@@ -602,7 +603,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
/* turn on 100 Mbps LED (LED_LINK100) */
- ledover |= PHY_M_LED_MO_100;
+ ledover |= PHY_M_LED_MO_100(MO_LED_ON);
}
if (ledover)
@@ -3322,82 +3323,80 @@ static void sky2_set_multicast(struct net_device *dev)
/* Can have one global because blinking is controlled by
* ethtool and that is always under RTNL mutex
*/
-static void sky2_led(struct sky2_hw *hw, unsigned port, int on)
+static void sky2_led(struct sky2_port *sky2, enum led_mode mode)
{
- u16 pg;
+ struct sky2_hw *hw = sky2->hw;
+ unsigned port = sky2->port;
- switch (hw->chip_id) {
- case CHIP_ID_YUKON_XL:
+ spin_lock_bh(&sky2->phy_lock);
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
+ hw->chip_id == CHIP_ID_YUKON_EX ||
+ hw->chip_id == CHIP_ID_YUKON_SUPR) {
+ u16 pg;
pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
- gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
- on ? (PHY_M_LEDC_LOS_CTRL(1) |
- PHY_M_LEDC_INIT_CTRL(7) |
- PHY_M_LEDC_STA1_CTRL(7) |
- PHY_M_LEDC_STA0_CTRL(7))
- : 0);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
- break;
+ switch (mode) {
+ case MO_LED_OFF:
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+ PHY_M_LEDC_LOS_CTRL(8) |
+ PHY_M_LEDC_INIT_CTRL(8) |
+ PHY_M_LEDC_STA1_CTRL(8) |
+ PHY_M_LEDC_STA0_CTRL(8));
+ break;
+ case MO_LED_ON:
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+ PHY_M_LEDC_LOS_CTRL(9) |
+ PHY_M_LEDC_INIT_CTRL(9) |
+ PHY_M_LEDC_STA1_CTRL(9) |
+ PHY_M_LEDC_STA0_CTRL(9));
+ break;
+ case MO_LED_BLINK:
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+ PHY_M_LEDC_LOS_CTRL(0xa) |
+ PHY_M_LEDC_INIT_CTRL(0xa) |
+ PHY_M_LEDC_STA1_CTRL(0xa) |
+ PHY_M_LEDC_STA0_CTRL(0xa));
+ break;
+ case MO_LED_NORM:
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+ PHY_M_LEDC_LOS_CTRL(1) |
+ PHY_M_LEDC_INIT_CTRL(8) |
+ PHY_M_LEDC_STA1_CTRL(7) |
+ PHY_M_LEDC_STA0_CTRL(7));
+ }
- default:
- gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+ } else
gm_phy_write(hw, port, PHY_MARV_LED_OVER,
- on ? PHY_M_LED_ALL : 0);
- }
+ PHY_M_LED_MO_DUP(mode) |
+ PHY_M_LED_MO_10(mode) |
+ PHY_M_LED_MO_100(mode) |
+ PHY_M_LED_MO_1000(mode) |
+ PHY_M_LED_MO_RX(mode) |
+ PHY_M_LED_MO_TX(mode));
+
+ spin_unlock_bh(&sky2->phy_lock);
}
/* blink LED's for finding board */
static int sky2_phys_id(struct net_device *dev, u32 data)
{
struct sky2_port *sky2 = netdev_priv(dev);
- struct sky2_hw *hw = sky2->hw;
- unsigned port = sky2->port;
- u16 ledctrl, ledover = 0;
- long ms;
- int interrupted;
- int onoff = 1;
+ unsigned int i;
- if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ))
- ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT);
- else
- ms = data * 1000;
-
- /* save initial values */
- spin_lock_bh(&sky2->phy_lock);
- if (hw->chip_id == CHIP_ID_YUKON_XL) {
- u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
- ledctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
- } else {
- ledctrl = gm_phy_read(hw, port, PHY_MARV_LED_CTRL);
- ledover = gm_phy_read(hw, port, PHY_MARV_LED_OVER);
- }
-
- interrupted = 0;
- while (!interrupted && ms > 0) {
- sky2_led(hw, port, onoff);
- onoff = !onoff;
-
- spin_unlock_bh(&sky2->phy_lock);
- interrupted = msleep_interruptible(250);
- spin_lock_bh(&sky2->phy_lock);
-
- ms -= 250;
- }
+ if (data == 0)
+ data = UINT_MAX;
- /* resume regularly scheduled programming */
- if (hw->chip_id == CHIP_ID_YUKON_XL) {
- u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
- gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ledctrl);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
- } else {
- gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
- gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+ for (i = 0; i < data; i++) {
+ sky2_led(sky2, MO_LED_ON);
+ if (msleep_interruptible(500))
+ break;
+ sky2_led(sky2, MO_LED_OFF);
+ if (msleep_interruptible(500))
+ break;
}
- spin_unlock_bh(&sky2->phy_lock);
+ sky2_led(sky2, MO_LED_NORM);
return 0;
}
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 5ab5c1c7c5a..7bb3ba9bcbd 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1318,18 +1318,21 @@ enum {
BLINK_670MS = 4,/* 670 ms */
};
-/**** PHY_MARV_LED_OVER 16 bit r/w LED control */
-enum {
- PHY_M_LED_MO_DUP = 3<<10,/* Bit 11..10: Duplex */
- PHY_M_LED_MO_10 = 3<<8, /* Bit 9.. 8: Link 10 */
- PHY_M_LED_MO_100 = 3<<6, /* Bit 7.. 6: Link 100 */
- PHY_M_LED_MO_1000 = 3<<4, /* Bit 5.. 4: Link 1000 */
- PHY_M_LED_MO_RX = 3<<2, /* Bit 3.. 2: Rx */
- PHY_M_LED_MO_TX = 3<<0, /* Bit 1.. 0: Tx */
-
- PHY_M_LED_ALL = PHY_M_LED_MO_DUP | PHY_M_LED_MO_10
- | PHY_M_LED_MO_100 | PHY_M_LED_MO_1000
- | PHY_M_LED_MO_RX,
+/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/
+#define PHY_M_LED_MO_SGMII(x) ((x)<<14) /* Bit 15..14: SGMII AN Timer */
+
+#define PHY_M_LED_MO_DUP(x) ((x)<<10) /* Bit 11..10: Duplex */
+#define PHY_M_LED_MO_10(x) ((x)<<8) /* Bit 9.. 8: Link 10 */
+#define PHY_M_LED_MO_100(x) ((x)<<6) /* Bit 7.. 6: Link 100 */
+#define PHY_M_LED_MO_1000(x) ((x)<<4) /* Bit 5.. 4: Link 1000 */
+#define PHY_M_LED_MO_RX(x) ((x)<<2) /* Bit 3.. 2: Rx */
+#define PHY_M_LED_MO_TX(x) ((x)<<0) /* Bit 1.. 0: Tx */
+
+enum led_mode {
+ MO_LED_NORM = 0,
+ MO_LED_BLINK = 1,
+ MO_LED_OFF = 2,
+ MO_LED_ON = 3,
};
/***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index db606b60388..26ffb67f1da 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -8781,7 +8781,7 @@ static int tg3_phys_id(struct net_device *dev, u32 data)
return -EAGAIN;
if (data == 0)
- data = 2;
+ data = UINT_MAX / 2;
for (i = 0; i < (data * 2); i++) {
if ((i % 2) == 0)
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 3af5b92b48c..0166407d706 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -1400,7 +1400,7 @@ static void TLan_SetMulticastList( struct net_device *dev )
*
**************************************************************/
-u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
{
/* printk( "TLAN: Invalid interrupt on %s.\n", dev->name ); */
return 0;
@@ -1432,7 +1432,7 @@ u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = netdev_priv(dev);
int eoc = 0;
@@ -1518,7 +1518,7 @@ u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
{
TLan_ReadAndClearStats( dev, TLAN_RECORD );
@@ -1554,7 +1554,7 @@ u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u32 ack = 0;
@@ -1689,7 +1689,7 @@ u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
{
printk( "TLAN: Test interrupt on %s.\n", dev->name );
return 1;
@@ -1719,7 +1719,7 @@ u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = netdev_priv(dev);
TLanList *head_list;
@@ -1767,7 +1767,7 @@ u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u32 ack;
@@ -1842,7 +1842,7 @@ u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = netdev_priv(dev);
dma_addr_t head_list_phys;
@@ -1902,7 +1902,7 @@ u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
*
**************************************************************/
-void TLan_Timer( unsigned long data )
+static void TLan_Timer( unsigned long data )
{
struct net_device *dev = (struct net_device *) data;
TLanPrivateInfo *priv = netdev_priv(dev);
@@ -1983,7 +1983,7 @@ void TLan_Timer( unsigned long data )
*
**************************************************************/
-void TLan_ResetLists( struct net_device *dev )
+static void TLan_ResetLists( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
int i;
@@ -2043,7 +2043,7 @@ void TLan_ResetLists( struct net_device *dev )
} /* TLan_ResetLists */
-void TLan_FreeLists( struct net_device *dev )
+static void TLan_FreeLists( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
int i;
@@ -2092,7 +2092,7 @@ void TLan_FreeLists( struct net_device *dev )
*
**************************************************************/
-void TLan_PrintDio( u16 io_base )
+static void TLan_PrintDio( u16 io_base )
{
u32 data0, data1;
int i;
@@ -2127,7 +2127,7 @@ void TLan_PrintDio( u16 io_base )
*
**************************************************************/
-void TLan_PrintList( TLanList *list, char *type, int num)
+static void TLan_PrintList( TLanList *list, char *type, int num)
{
int i;
@@ -2163,7 +2163,7 @@ void TLan_PrintList( TLanList *list, char *type, int num)
*
**************************************************************/
-void TLan_ReadAndClearStats( struct net_device *dev, int record )
+static void TLan_ReadAndClearStats( struct net_device *dev, int record )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u32 tx_good, tx_under;
@@ -2238,7 +2238,7 @@ void TLan_ReadAndClearStats( struct net_device *dev, int record )
*
**************************************************************/
-void
+static void
TLan_ResetAdapter( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
@@ -2324,7 +2324,7 @@ TLan_ResetAdapter( struct net_device *dev )
-void
+static void
TLan_FinishReset( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
@@ -2448,7 +2448,7 @@ TLan_FinishReset( struct net_device *dev )
*
**************************************************************/
-void TLan_SetMac( struct net_device *dev, int areg, char *mac )
+static void TLan_SetMac( struct net_device *dev, int areg, char *mac )
{
int i;
@@ -2490,7 +2490,7 @@ void TLan_SetMac( struct net_device *dev, int areg, char *mac )
*
********************************************************************/
-void TLan_PhyPrint( struct net_device *dev )
+static void TLan_PhyPrint( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 i, data0, data1, data2, data3, phy;
@@ -2539,7 +2539,7 @@ void TLan_PhyPrint( struct net_device *dev )
*
********************************************************************/
-void TLan_PhyDetect( struct net_device *dev )
+static void TLan_PhyDetect( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 control;
@@ -2586,7 +2586,7 @@ void TLan_PhyDetect( struct net_device *dev )
-void TLan_PhyPowerDown( struct net_device *dev )
+static void TLan_PhyPowerDown( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 value;
@@ -2611,7 +2611,7 @@ void TLan_PhyPowerDown( struct net_device *dev )
-void TLan_PhyPowerUp( struct net_device *dev )
+static void TLan_PhyPowerUp( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 value;
@@ -2632,7 +2632,7 @@ void TLan_PhyPowerUp( struct net_device *dev )
-void TLan_PhyReset( struct net_device *dev )
+static void TLan_PhyReset( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 phy;
@@ -2660,7 +2660,7 @@ void TLan_PhyReset( struct net_device *dev )
-void TLan_PhyStartLink( struct net_device *dev )
+static void TLan_PhyStartLink( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 ability;
@@ -2747,7 +2747,7 @@ void TLan_PhyStartLink( struct net_device *dev )
-void TLan_PhyFinishAutoNeg( struct net_device *dev )
+static void TLan_PhyFinishAutoNeg( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 an_adv;
@@ -2903,7 +2903,7 @@ void TLan_PhyMonitor( struct net_device *dev )
*
**************************************************************/
-int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
+static int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
{
u8 nack;
u16 sio, tmp;
@@ -2993,7 +2993,7 @@ int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
*
**************************************************************/
-void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
+static void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
{
u16 sio;
u32 i;
@@ -3035,7 +3035,7 @@ void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
*
**************************************************************/
-void TLan_MiiSync( u16 base_port )
+static void TLan_MiiSync( u16 base_port )
{
int i;
u16 sio;
@@ -3074,7 +3074,7 @@ void TLan_MiiSync( u16 base_port )
*
**************************************************************/
-void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
+static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
{
u16 sio;
int minten;
@@ -3144,7 +3144,7 @@ void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
*
**************************************************************/
-void TLan_EeSendStart( u16 io_base )
+static void TLan_EeSendStart( u16 io_base )
{
u16 sio;
@@ -3184,7 +3184,7 @@ void TLan_EeSendStart( u16 io_base )
*
**************************************************************/
-int TLan_EeSendByte( u16 io_base, u8 data, int stop )
+static int TLan_EeSendByte( u16 io_base, u8 data, int stop )
{
int err;
u8 place;
@@ -3245,7 +3245,7 @@ int TLan_EeSendByte( u16 io_base, u8 data, int stop )
*
**************************************************************/
-void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
+static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
{
u8 place;
u16 sio;
@@ -3303,7 +3303,7 @@ void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
*
**************************************************************/
-int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
+static int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
{
int err;
TLanPrivateInfo *priv = netdev_priv(dev);
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 35d15e85007..6f33f84d37b 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -36,6 +36,7 @@
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@@ -297,18 +298,11 @@ static void tsi108_check_phy(struct net_device *dev)
u32 speed;
unsigned long flags;
- /* Do a dummy read, as for some reason the first read
- * after a link becomes up returns link down, even if
- * it's been a while since the link came up.
- */
-
spin_lock_irqsave(&phy_lock, flags);
if (!data->phy_ok)
goto out;
- tsi108_read_mii(data, MII_BMSR);
-
duplex = mii_check_media(&data->mii_if, netif_msg_link(data), data->init_media);
data->init_media = 0;
@@ -345,22 +339,21 @@ static void tsi108_check_phy(struct net_device *dev)
TSI_WRITE(TSI108_MAC_CFG2, mac_cfg2_reg);
TSI_WRITE(TSI108_EC_PORTCTRL, portctrl_reg);
+ }
- if (data->link_up == 0) {
- /* The manual says it can take 3-4 usecs for the speed change
- * to take effect.
- */
- udelay(5);
+ if (data->link_up == 0) {
+ /* The manual says it can take 3-4 usecs for the speed change
+ * to take effect.
+ */
+ udelay(5);
- spin_lock(&data->txlock);
- if (is_valid_ether_addr(dev->dev_addr) && data->txfree)
- netif_wake_queue(dev);
+ spin_lock(&data->txlock);
+ if (is_valid_ether_addr(dev->dev_addr) && data->txfree)
+ netif_wake_queue(dev);
- data->link_up = 1;
- spin_unlock(&data->txlock);
- }
+ data->link_up = 1;
+ spin_unlock(&data->txlock);
}
-
} else {
if (data->link_up == 1) {
netif_stop_queue(dev);
@@ -1274,12 +1267,11 @@ static void tsi108_init_phy(struct net_device *dev)
* PHY_STAT register before the link up status bit is set.
*/
- data->link_up = 1;
+ data->link_up = 0;
while (!((phyval = tsi108_read_mii(data, MII_BMSR)) &
BMSR_LSTATUS)) {
if (i++ > (MII_READ_DELAY / 10)) {
- data->link_up = 0;
break;
}
spin_unlock_irqrestore(&phy_lock, flags);
@@ -1287,6 +1279,7 @@ static void tsi108_init_phy(struct net_device *dev)
spin_lock_irqsave(&phy_lock, flags);
}
+ data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if);
printk(KERN_DEBUG "PHY_STAT reg contains %08x\n", phyval);
data->phy_ok = 1;
data->init_media = 1;
@@ -1527,12 +1520,46 @@ static void tsi108_init_mac(struct net_device *dev)
TSI_WRITE(TSI108_EC_INTMASK, ~0);
}
+static int tsi108_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct tsi108_prv_data *data = netdev_priv(dev);
+ unsigned long flags;
+ int rc;
+
+ spin_lock_irqsave(&data->txlock, flags);
+ rc = mii_ethtool_gset(&data->mii_if, cmd);
+ spin_unlock_irqrestore(&data->txlock, flags);
+
+ return rc;
+}
+
+static int tsi108_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct tsi108_prv_data *data = netdev_priv(dev);
+ unsigned long flags;
+ int rc;
+
+ spin_lock_irqsave(&data->txlock, flags);
+ rc = mii_ethtool_sset(&data->mii_if, cmd);
+ spin_unlock_irqrestore(&data->txlock, flags);
+
+ return rc;
+}
+
static int tsi108_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct tsi108_prv_data *data = netdev_priv(dev);
+ if (!netif_running(dev))
+ return -EINVAL;
return generic_mii_ioctl(&data->mii_if, if_mii(rq), cmd, NULL);
}
+static const struct ethtool_ops tsi108_ethtool_ops = {
+ .get_link = ethtool_op_get_link,
+ .get_settings = tsi108_get_settings,
+ .set_settings = tsi108_set_settings,
+};
+
static int
tsi108_init_one(struct platform_device *pdev)
{
@@ -1584,7 +1611,6 @@ tsi108_init_one(struct platform_device *pdev)
data->mii_if.phy_id = einfo->phy;
data->mii_if.phy_id_mask = 0x1f;
data->mii_if.reg_num_mask = 0x1f;
- data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if);
data->phy = einfo->phy;
data->phy_type = einfo->phy_type;
@@ -1598,6 +1624,7 @@ tsi108_init_one(struct platform_device *pdev)
dev->get_stats = tsi108_get_stats;
netif_napi_add(dev, &data->napi, tsi108_poll, 64);
dev->do_ioctl = tsi108_do_ioctl;
+ dev->ethtool_ops = &tsi108_ethtool_ops;
/* Apparently, the Linux networking code won't use scatter-gather
* if the hardware doesn't do checksums. However, it's faster
@@ -1629,6 +1656,7 @@ tsi108_init_one(struct platform_device *pdev)
goto register_fail;
}
+ platform_set_drvdata(pdev, dev);
printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n",
dev->name, print_mac(mac, dev->dev_addr));
#ifdef DEBUG
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index a7afeea156b..a59c1f224aa 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -482,9 +482,11 @@ static void uli526x_init(struct net_device *dev)
struct uli526x_board_info *db = netdev_priv(dev);
unsigned long ioaddr = db->ioaddr;
u8 phy_tmp;
+ u8 timeout;
u16 phy_value;
u16 phy_reg_reset;
+
ULI526X_DBUG(0, "uli526x_init()", 0);
/* Reset M526x MAC controller */
@@ -509,11 +511,19 @@ static void uli526x_init(struct net_device *dev)
/* Parser SROM and media mode */
db->media_mode = uli526x_media_mode;
- /* Phyxcer capability setting */
+ /* phyxcer capability setting */
phy_reg_reset = phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id);
phy_reg_reset = (phy_reg_reset | 0x8000);
phy_write(db->ioaddr, db->phy_addr, 0, phy_reg_reset, db->chip_id);
+
+ /* See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management
+ * functions") or phy data sheet for details on phy reset
+ */
udelay(500);
+ timeout = 10;
+ while (timeout-- &&
+ phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id) & 0x8000)
+ udelay(100);
/* Process Phyxcer Media Mode */
uli526x_set_phyxcer(db);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 038c1ef94d2..7b816a03295 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -663,7 +663,11 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
case SIOCSIFHWADDR:
{
/* try to set the actual net device's hw address */
- int ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
+ int ret;
+
+ rtnl_lock();
+ ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
+ rtnl_unlock();
if (ret == 0) {
/** Set the character device's hardware address. This is used when
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 3f67a29593b..e2ad98bee6e 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -244,18 +244,6 @@ static int veth_open(struct net_device *dev)
return 0;
}
-static int veth_close(struct net_device *dev)
-{
- struct veth_priv *priv;
-
- if (netif_carrier_ok(dev)) {
- priv = netdev_priv(dev);
- netif_carrier_off(dev);
- netif_carrier_off(priv->peer);
- }
- return 0;
-}
-
static int veth_dev_init(struct net_device *dev)
{
struct veth_net_stats *stats;
@@ -286,13 +274,50 @@ static void veth_setup(struct net_device *dev)
dev->hard_start_xmit = veth_xmit;
dev->get_stats = veth_get_stats;
dev->open = veth_open;
- dev->stop = veth_close;
dev->ethtool_ops = &veth_ethtool_ops;
dev->features |= NETIF_F_LLTX;
dev->init = veth_dev_init;
dev->destructor = veth_dev_free;
}
+static void veth_change_state(struct net_device *dev)
+{
+ struct net_device *peer;
+ struct veth_priv *priv;
+
+ priv = netdev_priv(dev);
+ peer = priv->peer;
+
+ if (netif_carrier_ok(peer)) {
+ if (!netif_carrier_ok(dev))
+ netif_carrier_on(dev);
+ } else {
+ if (netif_carrier_ok(dev))
+ netif_carrier_off(dev);
+ }
+}
+
+static int veth_device_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = ptr;
+
+ if (dev->open != veth_open)
+ goto out;
+
+ switch (event) {
+ case NETDEV_CHANGE:
+ veth_change_state(dev);
+ break;
+ }
+out:
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block veth_notifier_block __read_mostly = {
+ .notifier_call = veth_device_event,
+};
+
/*
* netlink interface
*/
@@ -454,12 +479,14 @@ static struct rtnl_link_ops veth_link_ops = {
static __init int veth_init(void)
{
+ register_netdevice_notifier(&veth_notifier_block);
return rtnl_link_register(&veth_link_ops);
}
static __exit void veth_exit(void)
{
rtnl_link_unregister(&veth_link_ops);
+ unregister_netdevice_notifier(&veth_notifier_block);
}
module_init(veth_init);
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 7c851b1e6da..8c9d6ae2bb3 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -1893,7 +1893,7 @@ static void rhine_shutdown (struct pci_dev *pdev)
/* Make sure we use pattern 0, 1 and not 4, 5 */
if (rp->quirks & rq6patterns)
- iowrite8(0x04, ioaddr + 0xA7);
+ iowrite8(0x04, ioaddr + WOLcgClr);
if (rp->wolopts & WAKE_MAGIC) {
iowrite8(WOLmagic, ioaddr + WOLcrSet);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fdc23678117..19fd4cb0ddf 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -361,6 +361,7 @@ static int virtnet_probe(struct virtio_device *vdev)
netif_napi_add(dev, &vi->napi, virtnet_poll, napi_weight);
vi->dev = dev;
vi->vdev = vdev;
+ vdev->priv = vi;
/* We expect two virtqueues, receive then send. */
vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done);
@@ -395,7 +396,6 @@ static int virtnet_probe(struct virtio_device *vdev)
}
pr_debug("virtnet: registered device %s\n", dev->name);
- vdev->priv = vi;
return 0;
unregister:
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index c79066b38d3..69dea339261 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -1035,7 +1035,7 @@ struct ath5k_hw {
unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
unsigned int, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, unsigned int);
- bool (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *,
+ int (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *,
unsigned int, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int);
int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *);
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index ddc87149fe3..bef967ce34a 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -668,7 +668,10 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
* return false w/o doing anything. MAC's that do
* support it will return true w/o doing anything.
*/
- if (ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0))
+ ret = ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
+ if (ret < 0)
+ goto err;
+ if (ret > 0)
__set_bit(ATH_STAT_MRRETRY, sc->status);
/*
@@ -1256,7 +1259,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
if (ctl->flags & IEEE80211_TXCTL_NO_ACK)
flags |= AR5K_TXDESC_NOACK;
- pktlen = skb->len + FCS_LEN;
+ pktlen = skb->len;
if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) {
keyidx = ctl->key_idx;
@@ -1715,6 +1718,7 @@ ath5k_tasklet_rx(unsigned long data)
break;
else if (unlikely(ret)) {
ATH5K_ERR(sc, "error in processing rx descriptor\n");
+ spin_unlock(&sc->rxbuflock);
return;
}
@@ -1952,7 +1956,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
}
ds->ds_data = bf->skbaddr;
- ret = ah->ah_setup_tx_desc(ah, ds, skb->len + FCS_LEN,
+ ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
ieee80211_get_hdrlen_from_skb(skb),
AR5K_PKT_TYPE_BEACON, (ctl->power_level * 2), ctl->tx_rate, 1,
AR5K_TXKEYIX_INVALID, antenna, flags, 0, 0);
@@ -2126,8 +2130,9 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
"updated timers based on beacon TSF\n");
ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
- "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n",
- bc_tsf, hw_tsf, bc_tu, hw_tu, nexttbtt);
+ "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n",
+ (unsigned long long) bc_tsf,
+ (unsigned long long) hw_tsf, bc_tu, hw_tu, nexttbtt);
ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "intval %u %s %s\n",
intval & AR5K_BEACON_PERIOD,
intval & AR5K_BEACON_ENA ? "AR5K_BEACON_ENA" : "",
@@ -2385,10 +2390,11 @@ ath5k_intr(int irq, void *dev_id)
u64 tsf = ath5k_hw_get_tsf64(ah);
sc->nexttbtt += sc->bintval;
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
- "SWBA nexttbtt: %x hw_tu: %x "
- "TSF: %llx\n",
- sc->nexttbtt,
- TSF_TO_TU(tsf), tsf);
+ "SWBA nexttbtt: %x hw_tu: %x "
+ "TSF: %llx\n",
+ sc->nexttbtt,
+ TSF_TO_TU(tsf),
+ (unsigned long long) tsf);
} else {
ath5k_beacon_send(sc);
}
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 3a4bf4035a2..c2de2d958e8 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -45,7 +45,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int);
-static bool ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
+static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
unsigned int);
static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *);
@@ -3506,7 +3506,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
{
u32 frame_type;
struct ath5k_hw_2w_tx_desc *tx_desc;
- unsigned int buff_len;
+ unsigned int frame_len;
tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0;
@@ -3537,22 +3537,25 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
/* Setup control descriptor */
/* Verify and set frame length */
- if (pkt_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
+
+ /* remove padding we might have added before */
+ frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
+
+ if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
return -EINVAL;
- tx_desc->tx_control_0 = pkt_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
+ tx_desc->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
/* Verify and set buffer length */
- buff_len = pkt_len - FCS_LEN;
/* NB: beacon's BufLen must be a multiple of 4 bytes */
if(type == AR5K_PKT_TYPE_BEACON)
- buff_len = roundup(buff_len, 4);
+ pkt_len = roundup(pkt_len, 4);
- if (buff_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
+ if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
return -EINVAL;
- tx_desc->tx_control_1 = buff_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
+ tx_desc->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
/*
* Verify and set header length
@@ -3634,7 +3637,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
{
struct ath5k_hw_4w_tx_desc *tx_desc;
struct ath5k_hw_tx_status *tx_status;
- unsigned int buff_len;
+ unsigned int frame_len;
ATH5K_TRACE(ah->ah_sc);
tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
@@ -3669,22 +3672,25 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
/* Setup control descriptor */
/* Verify and set frame length */
- if (pkt_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
+
+ /* remove padding we might have added before */
+ frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
+
+ if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
return -EINVAL;
- tx_desc->tx_control_0 = pkt_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
+ tx_desc->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
/* Verify and set buffer length */
- buff_len = pkt_len - FCS_LEN;
/* NB: beacon's BufLen must be a multiple of 4 bytes */
if(type == AR5K_PKT_TYPE_BEACON)
- buff_len = roundup(buff_len, 4);
+ pkt_len = roundup(pkt_len, 4);
- if (buff_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
+ if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
return -EINVAL;
- tx_desc->tx_control_1 = buff_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
+ tx_desc->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
tx_desc->tx_control_0 |=
AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
@@ -3737,7 +3743,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
/*
* Initialize a 4-word multirate tx descriptor on 5212
*/
-static bool
+static int
ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
unsigned int tx_rate3, u_int tx_tries3)
@@ -3777,10 +3783,10 @@ ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
#undef _XTX_TRIES
- return true;
+ return 1;
}
- return false;
+ return 0;
}
/*
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 1a2141dabdc..8bc4bc4c330 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -32,6 +32,7 @@ config B43_PCI_AUTOSELECT
bool
depends on B43 && SSB_PCIHOST_POSSIBLE
select SSB_PCIHOST
+ select SSB_B43_PCI_BRIDGE
default y
# Auto-select SSB PCICORE driver, if possible
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 08a011f0834..f13346ba9dd 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -14,6 +14,12 @@
#include "lo.h"
#include "phy.h"
+
+/* The unique identifier of the firmware that's officially supported by
+ * this driver version. */
+#define B43_SUPPORTED_FIRMWARE_ID "FW13"
+
+
#ifdef CONFIG_B43_DEBUG
# define B43_DEBUG 1
#else
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index ef65c41af00..51dfce16178 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -58,6 +58,8 @@ MODULE_AUTHOR("Stefano Brivio");
MODULE_AUTHOR("Michael Buesch");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID);
+
static int modparam_bad_frames_preempt;
module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
@@ -1859,11 +1861,11 @@ static int b43_upload_microcode(struct b43_wldev *dev)
err = -EOPNOTSUPP;
goto error;
}
- b43dbg(dev->wl, "Loading firmware version %u.%u "
- "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
- fwrev, fwpatch,
- (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
- (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
+ b43info(dev->wl, "Loading firmware version %u.%u "
+ "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
+ fwrev, fwpatch,
+ (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
+ (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
dev->fw.rev = fwrev;
dev->fw.patch = fwpatch;
@@ -4200,6 +4202,33 @@ static struct ssb_driver b43_ssb_driver = {
.resume = b43_resume,
};
+static void b43_print_driverinfo(void)
+{
+ const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "",
+ *feat_leds = "", *feat_rfkill = "";
+
+#ifdef CONFIG_B43_PCI_AUTOSELECT
+ feat_pci = "P";
+#endif
+#ifdef CONFIG_B43_PCMCIA
+ feat_pcmcia = "M";
+#endif
+#ifdef CONFIG_B43_NPHY
+ feat_nphy = "N";
+#endif
+#ifdef CONFIG_B43_LEDS
+ feat_leds = "L";
+#endif
+#ifdef CONFIG_B43_RFKILL
+ feat_rfkill = "R";
+#endif
+ printk(KERN_INFO "Broadcom 43xx driver loaded "
+ "[ Features: %s%s%s%s%s, Firmware-ID: "
+ B43_SUPPORTED_FIRMWARE_ID " ]\n",
+ feat_pci, feat_pcmcia, feat_nphy,
+ feat_leds, feat_rfkill);
+}
+
static int __init b43_init(void)
{
int err;
@@ -4211,6 +4240,7 @@ static int __init b43_init(void)
err = ssb_driver_register(&b43_ssb_driver);
if (err)
goto err_pcmcia_exit;
+ b43_print_driverinfo();
return err;
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig
index 6745579ba96..13c65faf024 100644
--- a/drivers/net/wireless/b43legacy/Kconfig
+++ b/drivers/net/wireless/b43legacy/Kconfig
@@ -25,6 +25,7 @@ config B43LEGACY_PCI_AUTOSELECT
bool
depends on B43LEGACY && SSB_PCIHOST_POSSIBLE
select SSB_PCIHOST
+ select SSB_B43_PCI_BRIDGE
default y
# Auto-select SSB PCICORE driver, if possible
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index c80edd2b904..93d45b71799 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -23,6 +23,10 @@
#include "phy.h"
+/* The unique identifier of the firmware that's officially supported by this
+ * driver version. */
+#define B43legacy_SUPPORTED_FIRMWARE_ID "FW10"
+
#define B43legacy_IRQWAIT_MAX_RETRIES 20
#define B43legacy_RX_MAX_SSI 60 /* best guess at max ssi */
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 6e08405e802..e87b427d5e4 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -354,7 +354,8 @@ return 0;
}
-u16 b43legacy_dmacontroller_base(int dma64bit, int controller_idx)
+static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type,
+ int controller_idx)
{
static const u16 map64[] = {
B43legacy_MMIO_DMA64_BASE0,
@@ -373,7 +374,7 @@ u16 b43legacy_dmacontroller_base(int dma64bit, int controller_idx)
B43legacy_MMIO_DMA32_BASE5,
};
- if (dma64bit) {
+ if (type == B43legacy_DMA_64BIT) {
B43legacy_WARN_ON(!(controller_idx >= 0 &&
controller_idx < ARRAY_SIZE(map64)));
return map64[controller_idx];
@@ -480,8 +481,9 @@ static void free_ringmemory(struct b43legacy_dmaring *ring)
}
/* Reset the RX DMA channel */
-int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
- u16 mmio_base, int dma64)
+static int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
+ u16 mmio_base,
+ enum b43legacy_dmatype type)
{
int i;
u32 value;
@@ -489,13 +491,14 @@ int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
might_sleep();
- offset = dma64 ? B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL;
+ offset = (type == B43legacy_DMA_64BIT) ?
+ B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL;
b43legacy_write32(dev, mmio_base + offset, 0);
for (i = 0; i < 10; i++) {
- offset = dma64 ? B43legacy_DMA64_RXSTATUS :
- B43legacy_DMA32_RXSTATUS;
+ offset = (type == B43legacy_DMA_64BIT) ?
+ B43legacy_DMA64_RXSTATUS : B43legacy_DMA32_RXSTATUS;
value = b43legacy_read32(dev, mmio_base + offset);
- if (dma64) {
+ if (type == B43legacy_DMA_64BIT) {
value &= B43legacy_DMA64_RXSTAT;
if (value == B43legacy_DMA64_RXSTAT_DISABLED) {
i = -1;
@@ -519,8 +522,9 @@ int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
}
/* Reset the RX DMA channel */
-int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
- u16 mmio_base, int dma64)
+static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
+ u16 mmio_base,
+ enum b43legacy_dmatype type)
{
int i;
u32 value;
@@ -529,10 +533,10 @@ int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
might_sleep();
for (i = 0; i < 10; i++) {
- offset = dma64 ? B43legacy_DMA64_TXSTATUS :
- B43legacy_DMA32_TXSTATUS;
+ offset = (type == B43legacy_DMA_64BIT) ?
+ B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS;
value = b43legacy_read32(dev, mmio_base + offset);
- if (dma64) {
+ if (type == B43legacy_DMA_64BIT) {
value &= B43legacy_DMA64_TXSTAT;
if (value == B43legacy_DMA64_TXSTAT_DISABLED ||
value == B43legacy_DMA64_TXSTAT_IDLEWAIT ||
@@ -547,13 +551,14 @@ int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
}
msleep(1);
}
- offset = dma64 ? B43legacy_DMA64_TXCTL : B43legacy_DMA32_TXCTL;
+ offset = (type == B43legacy_DMA_64BIT) ? B43legacy_DMA64_TXCTL :
+ B43legacy_DMA32_TXCTL;
b43legacy_write32(dev, mmio_base + offset, 0);
for (i = 0; i < 10; i++) {
- offset = dma64 ? B43legacy_DMA64_TXSTATUS :
- B43legacy_DMA32_TXSTATUS;
+ offset = (type == B43legacy_DMA_64BIT) ?
+ B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS;
value = b43legacy_read32(dev, mmio_base + offset);
- if (dma64) {
+ if (type == B43legacy_DMA_64BIT) {
value &= B43legacy_DMA64_TXSTAT;
if (value == B43legacy_DMA64_TXSTAT_DISABLED) {
i = -1;
@@ -578,6 +583,32 @@ int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
return 0;
}
+/* Check if a DMA mapping address is invalid. */
+static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
+ dma_addr_t addr,
+ size_t buffersize)
+{
+ if (unlikely(dma_mapping_error(addr)))
+ return 1;
+
+ switch (ring->type) {
+ case B43legacy_DMA_30BIT:
+ if ((u64)addr + buffersize > (1ULL << 30))
+ return 1;
+ break;
+ case B43legacy_DMA_32BIT:
+ if ((u64)addr + buffersize > (1ULL << 32))
+ return 1;
+ break;
+ case B43legacy_DMA_64BIT:
+ /* Currently we can't have addresses beyond 64 bits in the kernel. */
+ break;
+ }
+
+ /* The address is OK. */
+ return 0;
+}
+
static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
struct b43legacy_dmadesc_generic *desc,
struct b43legacy_dmadesc_meta *meta,
@@ -595,7 +626,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
return -ENOMEM;
dmaaddr = map_descbuffer(ring, skb->data,
ring->rx_buffersize, 0);
- if (dma_mapping_error(dmaaddr)) {
+ if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) {
/* ugh. try to realloc in zone_dma */
gfp_flags |= GFP_DMA;
@@ -608,7 +639,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
ring->rx_buffersize, 0);
}
- if (dma_mapping_error(dmaaddr)) {
+ if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) {
dev_kfree_skb_any(skb);
return -EIO;
}
@@ -674,7 +705,7 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring)
u32 trans = ssb_dma_translation(ring->dev->dev);
if (ring->tx) {
- if (ring->dma64) {
+ if (ring->type == B43legacy_DMA_64BIT) {
u64 ringbase = (u64)(ring->dmabase);
addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK)
@@ -709,7 +740,7 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring)
err = alloc_initial_descbuffers(ring);
if (err)
goto out;
- if (ring->dma64) {
+ if (ring->type == B43legacy_DMA_64BIT) {
u64 ringbase = (u64)(ring->dmabase);
addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK)
@@ -760,16 +791,16 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring)
{
if (ring->tx) {
b43legacy_dmacontroller_tx_reset(ring->dev, ring->mmio_base,
- ring->dma64);
- if (ring->dma64) {
+ ring->type);
+ if (ring->type == B43legacy_DMA_64BIT) {
b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGLO, 0);
b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGHI, 0);
} else
b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, 0);
} else {
b43legacy_dmacontroller_rx_reset(ring->dev, ring->mmio_base,
- ring->dma64);
- if (ring->dma64) {
+ ring->type);
+ if (ring->type == B43legacy_DMA_64BIT) {
b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGLO, 0);
b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGHI, 0);
} else
@@ -824,11 +855,10 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
/* Main initialization function. */
static
-struct b43legacy_dmaring *b43legacy_setup_dmaring(
- struct b43legacy_wldev *dev,
- int controller_index,
- int for_tx,
- int dma64)
+struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
+ int controller_index,
+ int for_tx,
+ enum b43legacy_dmatype type)
{
struct b43legacy_dmaring *ring;
int err;
@@ -838,6 +868,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(
ring = kzalloc(sizeof(*ring), GFP_KERNEL);
if (!ring)
goto out;
+ ring->type = type;
nr_slots = B43legacy_RXRING_SLOTS;
if (for_tx)
@@ -855,12 +886,12 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(
goto err_kfree_meta;
/* test for ability to dma to txhdr_cache */
- dma_test = dma_map_single(dev->dev->dev,
- ring->txhdr_cache,
- sizeof(struct b43legacy_txhdr_fw3),
- DMA_TO_DEVICE);
+ dma_test = dma_map_single(dev->dev->dev, ring->txhdr_cache,
+ sizeof(struct b43legacy_txhdr_fw3),
+ DMA_TO_DEVICE);
- if (dma_mapping_error(dma_test)) {
+ if (b43legacy_dma_mapping_error(ring, dma_test,
+ sizeof(struct b43legacy_txhdr_fw3))) {
/* ugh realloc */
kfree(ring->txhdr_cache);
ring->txhdr_cache = kcalloc(nr_slots,
@@ -874,7 +905,8 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(
sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE);
- if (dma_mapping_error(dma_test))
+ if (b43legacy_dma_mapping_error(ring, dma_test,
+ sizeof(struct b43legacy_txhdr_fw3)))
goto err_kfree_txhdr_cache;
}
@@ -885,11 +917,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(
ring->dev = dev;
ring->nr_slots = nr_slots;
- ring->mmio_base = b43legacy_dmacontroller_base(dma64,
- controller_index);
+ ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index);
ring->index = controller_index;
- ring->dma64 = !!dma64;
- if (dma64)
+ if (type == B43legacy_DMA_64BIT)
ring->ops = &dma64_ops;
else
ring->ops = &dma32_ops;
@@ -939,10 +969,10 @@ static void b43legacy_destroy_dmaring(struct b43legacy_dmaring *ring)
if (!ring)
return;
- b43legacydbg(ring->dev->wl, "DMA-%s 0x%04X (%s) max used slots:"
- " %d/%d\n", (ring->dma64) ? "64" : "32", ring->mmio_base,
- (ring->tx) ? "TX" : "RX",
- ring->max_used_slots, ring->nr_slots);
+ b43legacydbg(ring->dev->wl, "DMA-%u 0x%04X (%s) max used slots:"
+ " %d/%d\n", (unsigned int)(ring->type), ring->mmio_base,
+ (ring->tx) ? "TX" : "RX", ring->max_used_slots,
+ ring->nr_slots);
/* Device IRQs are disabled prior entering this function,
* so no need to take care of concurrency with rx handler stuff.
*/
@@ -988,11 +1018,22 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev)
struct b43legacy_dmaring *ring;
int err;
u64 dmamask;
- int dma64 = 0;
+ enum b43legacy_dmatype type;
dmamask = supported_dma_mask(dev);
- if (dmamask == DMA_64BIT_MASK)
- dma64 = 1;
+ switch (dmamask) {
+ default:
+ B43legacy_WARN_ON(1);
+ case DMA_30BIT_MASK:
+ type = B43legacy_DMA_30BIT;
+ break;
+ case DMA_32BIT_MASK:
+ type = B43legacy_DMA_32BIT;
+ break;
+ case DMA_64BIT_MASK:
+ type = B43legacy_DMA_64BIT;
+ break;
+ }
err = ssb_dma_set_mask(dev->dev, dmamask);
if (err) {
@@ -1010,52 +1051,50 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev)
err = -ENOMEM;
/* setup TX DMA channels. */
- ring = b43legacy_setup_dmaring(dev, 0, 1, dma64);
+ ring = b43legacy_setup_dmaring(dev, 0, 1, type);
if (!ring)
goto out;
dma->tx_ring0 = ring;
- ring = b43legacy_setup_dmaring(dev, 1, 1, dma64);
+ ring = b43legacy_setup_dmaring(dev, 1, 1, type);
if (!ring)
goto err_destroy_tx0;
dma->tx_ring1 = ring;
- ring = b43legacy_setup_dmaring(dev, 2, 1, dma64);
+ ring = b43legacy_setup_dmaring(dev, 2, 1, type);
if (!ring)
goto err_destroy_tx1;
dma->tx_ring2 = ring;
- ring = b43legacy_setup_dmaring(dev, 3, 1, dma64);
+ ring = b43legacy_setup_dmaring(dev, 3, 1, type);
if (!ring)
goto err_destroy_tx2;
dma->tx_ring3 = ring;
- ring = b43legacy_setup_dmaring(dev, 4, 1, dma64);
+ ring = b43legacy_setup_dmaring(dev, 4, 1, type);
if (!ring)
goto err_destroy_tx3;
dma->tx_ring4 = ring;
- ring = b43legacy_setup_dmaring(dev, 5, 1, dma64);
+ ring = b43legacy_setup_dmaring(dev, 5, 1, type);
if (!ring)
goto err_destroy_tx4;
dma->tx_ring5 = ring;
/* setup RX DMA channels. */
- ring = b43legacy_setup_dmaring(dev, 0, 0, dma64);
+ ring = b43legacy_setup_dmaring(dev, 0, 0, type);
if (!ring)
goto err_destroy_tx5;
dma->rx_ring0 = ring;
if (dev->dev->id.revision < 5) {
- ring = b43legacy_setup_dmaring(dev, 3, 0, dma64);
+ ring = b43legacy_setup_dmaring(dev, 3, 0, type);
if (!ring)
goto err_destroy_rx0;
dma->rx_ring3 = ring;
}
- b43legacydbg(dev->wl, "%d-bit DMA initialized\n",
- (dmamask == DMA_64BIT_MASK) ? 64 :
- (dmamask == DMA_32BIT_MASK) ? 32 : 30);
+ b43legacydbg(dev->wl, "%u-bit DMA initialized\n", (unsigned int)type);
err = 0;
out:
return err;
@@ -1194,9 +1233,13 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
}
meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
- sizeof(struct b43legacy_txhdr_fw3), 1);
- if (dma_mapping_error(meta_hdr->dmaaddr))
+ sizeof(struct b43legacy_txhdr_fw3), 1);
+ if (b43legacy_dma_mapping_error(ring, meta_hdr->dmaaddr,
+ sizeof(struct b43legacy_txhdr_fw3))) {
+ ring->current_slot = old_top_slot;
+ ring->used_slots = old_used_slots;
return -EIO;
+ }
ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
sizeof(struct b43legacy_txhdr_fw3), 1, 0, 0);
@@ -1211,7 +1254,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
/* create a bounce buffer in zone_dma on mapping failure. */
- if (dma_mapping_error(meta->dmaaddr)) {
+ if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) {
bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb) {
ring->current_slot = old_top_slot;
@@ -1225,7 +1268,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
skb = bounce_skb;
meta->skb = skb;
meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
- if (dma_mapping_error(meta->dmaaddr)) {
+ if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) {
ring->current_slot = old_top_slot;
ring->used_slots = old_used_slots;
err = -EIO;
diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h
index 26f6ab08de7..2dd488c5be2 100644
--- a/drivers/net/wireless/b43legacy/dma.h
+++ b/drivers/net/wireless/b43legacy/dma.h
@@ -218,6 +218,12 @@ struct b43legacy_dma_ops {
void (*set_current_rxslot)(struct b43legacy_dmaring *ring, int slot);
};
+enum b43legacy_dmatype {
+ B43legacy_DMA_30BIT = 30,
+ B43legacy_DMA_32BIT = 32,
+ B43legacy_DMA_64BIT = 64,
+};
+
struct b43legacy_dmaring {
/* Lowlevel DMA ops. */
const struct b43legacy_dma_ops *ops;
@@ -250,8 +256,8 @@ struct b43legacy_dmaring {
int index;
/* Boolean. Is this a TX ring? */
bool tx;
- /* Boolean. 64bit DMA if true, 32bit DMA otherwise. */
- bool dma64;
+ /* The type of DMA engine used. */
+ enum b43legacy_dmatype type;
/* Boolean. Is this ring stopped at ieee80211 level? */
bool stopped;
/* Lock, only used for TX. */
@@ -284,15 +290,6 @@ void b43legacy_dma_write(struct b43legacy_dmaring *ring,
int b43legacy_dma_init(struct b43legacy_wldev *dev);
void b43legacy_dma_free(struct b43legacy_wldev *dev);
-int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
- u16 dmacontroller_mmio_base,
- int dma64);
-int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
- u16 dmacontroller_mmio_base,
- int dma64);
-
-u16 b43legacy_dmacontroller_base(int dma64bit, int dmacontroller_idx);
-
void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev);
void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev);
@@ -320,20 +317,6 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev)
{
}
static inline
-int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
- u16 dmacontroller_mmio_base,
- int dma64)
-{
- return 0;
-}
-static inline
-int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
- u16 dmacontroller_mmio_base,
- int dma64)
-{
- return 0;
-}
-static inline
void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
struct ieee80211_tx_queue_stats *stats)
{
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 53f7f2e9761..5f3f34e1dbf 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3,7 +3,7 @@
* Broadcom B43legacy wireless driver
*
* Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
- * Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
+ * Copyright (c) 2005-2008 Stefano Brivio <stefano.brivio@polimi.it>
* Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
* Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
* Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -60,6 +60,8 @@ MODULE_AUTHOR("Stefano Brivio");
MODULE_AUTHOR("Michael Buesch");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID);
+
#if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO)
static int modparam_pio;
module_param_named(pio, modparam_pio, int, 0444);
@@ -1640,10 +1642,11 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
err = -EOPNOTSUPP;
goto error;
}
- b43legacydbg(dev->wl, "Loading firmware version 0x%X, patch level %u "
- "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch,
- (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
- (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
+ b43legacyinfo(dev->wl, "Loading firmware version 0x%X, patch level %u "
+ "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch,
+ (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
+ (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F,
+ fwtime & 0x1F);
dev->fw.rev = fwrev;
dev->fw.patch = fwpatch;
@@ -3806,6 +3809,32 @@ static struct ssb_driver b43legacy_ssb_driver = {
.resume = b43legacy_resume,
};
+static void b43legacy_print_driverinfo(void)
+{
+ const char *feat_pci = "", *feat_leds = "", *feat_rfkill = "",
+ *feat_pio = "", *feat_dma = "";
+
+#ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT
+ feat_pci = "P";
+#endif
+#ifdef CONFIG_B43LEGACY_LEDS
+ feat_leds = "L";
+#endif
+#ifdef CONFIG_B43LEGACY_RFKILL
+ feat_rfkill = "R";
+#endif
+#ifdef CONFIG_B43LEGACY_PIO
+ feat_pio = "I";
+#endif
+#ifdef CONFIG_B43LEGACY_DMA
+ feat_dma = "D";
+#endif
+ printk(KERN_INFO "Broadcom 43xx-legacy driver loaded "
+ "[ Features: %s%s%s%s%s, Firmware-ID: "
+ B43legacy_SUPPORTED_FIRMWARE_ID " ]\n",
+ feat_pci, feat_leds, feat_rfkill, feat_pio, feat_dma);
+}
+
static int __init b43legacy_init(void)
{
int err;
@@ -3816,6 +3845,8 @@ static int __init b43legacy_init(void)
if (err)
goto err_dfs_exit;
+ b43legacy_print_driverinfo();
+
return err;
err_dfs_exit:
diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig
index 0159701e845..afb8f4305c2 100644
--- a/drivers/net/wireless/bcm43xx/Kconfig
+++ b/drivers/net/wireless/bcm43xx/Kconfig
@@ -1,6 +1,6 @@
config BCM43XX
tristate "Broadcom BCM43xx wireless support (DEPRECATED)"
- depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL
+ depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && (!SSB_B43_PCI_BRIDGE || SSB != y) && EXPERIMENTAL
select WIRELESS_EXT
select FW_LOADER
select HW_RANDOM
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 3e6ad7b92c8..a56d9fc6354 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -3365,7 +3365,6 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv,
/* Set us so that we have processed and used all buffers, but have
* not restocked the Rx queue with fresh buffers */
rxq->read = rxq->write = 0;
- rxq->processed = RX_QUEUE_SIZE - 1;
rxq->free_count = 0;
spin_unlock_irqrestore(&rxq->lock, flags);
}
@@ -3607,7 +3606,22 @@ static int ipw_load(struct ipw_priv *priv)
* Driver allocates buffers of this size for Rx
*/
-static inline int ipw_queue_space(const struct clx2_queue *q)
+/**
+ * ipw_rx_queue_space - Return number of free slots available in queue.
+ */
+static int ipw_rx_queue_space(const struct ipw_rx_queue *q)
+{
+ int s = q->read - q->write;
+ if (s <= 0)
+ s += RX_QUEUE_SIZE;
+ /* keep some buffer to not confuse full and empty queue */
+ s -= 2;
+ if (s < 0)
+ s = 0;
+ return s;
+}
+
+static inline int ipw_tx_queue_space(const struct clx2_queue *q)
{
int s = q->last_used - q->first_empty;
if (s <= 0)
@@ -4947,7 +4961,7 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
priv->tx_packets++;
}
done:
- if ((ipw_queue_space(q) > q->low_mark) &&
+ if ((ipw_tx_queue_space(q) > q->low_mark) &&
(qindex >= 0) &&
(priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
netif_wake_queue(priv->net_dev);
@@ -4965,7 +4979,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
struct clx2_queue *q = &txq->q;
struct tfd_frame *tfd;
- if (ipw_queue_space(q) < (sync ? 1 : 2)) {
+ if (ipw_tx_queue_space(q) < (sync ? 1 : 2)) {
IPW_ERROR("No space for Tx\n");
return -EBUSY;
}
@@ -5070,7 +5084,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
spin_lock_irqsave(&rxq->lock, flags);
write = rxq->write;
- while ((rxq->write != rxq->processed) && (rxq->free_count)) {
+ while ((ipw_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
element = rxq->rx_free.next;
rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
list_del(element);
@@ -5187,7 +5201,6 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
/* Set us so that we have processed and used all buffers, but have
* not restocked the Rx queue with fresh buffers */
rxq->read = rxq->write = 0;
- rxq->processed = RX_QUEUE_SIZE - 1;
rxq->free_count = 0;
return rxq;
@@ -8223,13 +8236,17 @@ static void ipw_rx(struct ipw_priv *priv)
struct ieee80211_hdr_4addr *header;
u32 r, w, i;
u8 network_packet;
+ u8 fill_rx = 0;
DECLARE_MAC_BUF(mac);
DECLARE_MAC_BUF(mac2);
DECLARE_MAC_BUF(mac3);
r = ipw_read32(priv, IPW_RX_READ_INDEX);
w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
- i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
+ i = priv->rxq->read;
+
+ if (ipw_rx_queue_space (priv->rxq) > (RX_QUEUE_SIZE / 2))
+ fill_rx = 1;
while (i != r) {
rxb = priv->rxq->queue[i];
@@ -8404,11 +8421,17 @@ static void ipw_rx(struct ipw_priv *priv)
list_add_tail(&rxb->list, &priv->rxq->rx_used);
i = (i + 1) % RX_QUEUE_SIZE;
+
+ /* If there are a lot of unsued frames, restock the Rx queue
+ * so the ucode won't assert */
+ if (fill_rx) {
+ priv->rxq->read = i;
+ ipw_rx_queue_replenish(priv);
+ }
}
/* Backtrack one entry */
- priv->rxq->processed = (i ? i : RX_QUEUE_SIZE) - 1;
-
+ priv->rxq->read = i;
ipw_rx_queue_restock(priv);
}
@@ -10336,7 +10359,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
ipw_write32(priv, q->reg_w, q->first_empty);
- if (ipw_queue_space(q) < q->high_mark)
+ if (ipw_tx_queue_space(q) < q->high_mark)
netif_stop_queue(priv->net_dev);
return NETDEV_TX_OK;
@@ -10357,7 +10380,7 @@ static int ipw_net_is_queue_full(struct net_device *dev, int pri)
struct clx2_tx_queue *txq = &priv->txq[0];
#endif /* CONFIG_IPW2200_QOS */
- if (ipw_queue_space(&txq->q) < txq->q.high_mark)
+ if (ipw_tx_queue_space(&txq->q) < txq->q.high_mark)
return 1;
return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 5ee1ad69898..40b71bc2c4a 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -687,6 +687,12 @@ static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_c
BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
!(cmd->meta.flags & CMD_SIZE_HUGE));
+
+ if (iwl3945_is_rfkill(priv)) {
+ IWL_DEBUG_INFO("Not sending command - RF KILL");
+ return -EIO;
+ }
+
if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
IWL_ERROR("No space for Tx\n");
return -ENOSPC;
@@ -1580,7 +1586,7 @@ static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
*/
int iwl3945_eeprom_init(struct iwl3945_priv *priv)
{
- __le16 *e = (__le16 *)&priv->eeprom;
+ u16 *e = (u16 *)&priv->eeprom;
u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
u32 r;
int sz = sizeof(priv->eeprom);
@@ -1623,7 +1629,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
IWL_ERROR("Time out reading EEPROM[%d]", addr);
return -ETIMEDOUT;
}
- e[addr / 2] = cpu_to_le16(r >> 16);
+ e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
}
return 0;
@@ -2806,7 +2812,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
#endif
/* drop all data frame if we are not associated */
- if ((!iwl3945_is_associated(priv) || !priv->assoc_id) &&
+ if ((!iwl3945_is_associated(priv) ||
+ ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) &&
((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
goto drop_unlock;
@@ -4281,7 +4288,7 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
int reclaim;
unsigned long flags;
u8 fill_rx = 0;
- u32 count = 0;
+ u32 count = 8;
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
@@ -6256,6 +6263,8 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
STATUS_RF_KILL_SW |
+ test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
+ STATUS_GEO_CONFIGURED |
test_bit(STATUS_IN_SUSPEND, &priv->status) <<
STATUS_IN_SUSPEND;
goto exit;
@@ -6267,6 +6276,8 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
STATUS_RF_KILL_SW |
+ test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
+ STATUS_GEO_CONFIGURED |
test_bit(STATUS_IN_SUSPEND, &priv->status) <<
STATUS_IN_SUSPEND |
test_bit(STATUS_FW_ERROR, &priv->status) <<
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index f423241b956..a23d4798653 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -692,6 +692,11 @@ static int iwl4965_enqueue_hcmd(struct iwl4965_priv *priv, struct iwl4965_host_c
BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
!(cmd->meta.flags & CMD_SIZE_HUGE));
+ if (iwl4965_is_rfkill(priv)) {
+ IWL_DEBUG_INFO("Not sending command - RF KILL");
+ return -EIO;
+ }
+
if (iwl4965_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
IWL_ERROR("No space for Tx\n");
return -ENOSPC;
@@ -1654,7 +1659,7 @@ static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
*/
int iwl4965_eeprom_init(struct iwl4965_priv *priv)
{
- __le16 *e = (__le16 *)&priv->eeprom;
+ u16 *e = (u16 *)&priv->eeprom;
u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP);
u32 r;
int sz = sizeof(priv->eeprom);
@@ -1698,7 +1703,7 @@ int iwl4965_eeprom_init(struct iwl4965_priv *priv)
rc = -ETIMEDOUT;
goto done;
}
- e[addr / 2] = cpu_to_le16(r >> 16);
+ e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
}
rc = 0;
@@ -2935,7 +2940,7 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
/* drop all data frame if we are not associated */
if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
(!iwl4965_is_associated(priv) ||
- !priv->assoc_id ||
+ ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) ||
!priv->assoc_station_added)) {
IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n");
goto drop_unlock;
@@ -4664,7 +4669,7 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)
int reclaim;
unsigned long flags;
u8 fill_rx = 0;
- u32 count = 0;
+ u32 count = 8;
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
@@ -6680,6 +6685,8 @@ static void __iwl4965_down(struct iwl4965_priv *priv)
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
STATUS_RF_KILL_SW |
+ test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
+ STATUS_GEO_CONFIGURED |
test_bit(STATUS_IN_SUSPEND, &priv->status) <<
STATUS_IN_SUSPEND;
goto exit;
@@ -6691,6 +6698,8 @@ static void __iwl4965_down(struct iwl4965_priv *priv)
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
STATUS_RF_KILL_SW |
+ test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
+ STATUS_GEO_CONFIGURED |
test_bit(STATUS_IN_SUSPEND, &priv->status) <<
STATUS_IN_SUSPEND |
test_bit(STATUS_FW_ERROR, &priv->status) <<
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index eab020338fd..b3c1acbcc65 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1040,7 +1040,6 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
lbs_deb_leave(LBS_DEB_CMD);
return ret;
}
-EXPORT_SYMBOL_GPL(lbs_mesh_access);
int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan)
{
@@ -1576,7 +1575,6 @@ done:
lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
return ret;
}
-EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command);
/**
* @brief This function allocates the command buffer and link
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 159216a9190..bdc6a1cc210 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -562,9 +562,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
}
resp = (void *)priv->upld_buf;
-
- curcmd = le16_to_cpu(resp->command);
-
+ curcmd = le16_to_cpu(priv->cur_cmd->cmdbuf->command);
respcmd = le16_to_cpu(resp->command);
result = le16_to_cpu(resp->result);
@@ -572,9 +570,9 @@ int lbs_process_rx_command(struct lbs_private *priv)
respcmd, le16_to_cpu(resp->seqnum), priv->upld_len, jiffies);
lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", (void *) resp, priv->upld_len);
- if (resp->seqnum != resp->seqnum) {
+ if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) {
lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n",
- le16_to_cpu(resp->seqnum), le16_to_cpu(resp->seqnum));
+ le16_to_cpu(resp->seqnum), le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
spin_unlock_irqrestore(&priv->driver_lock, flags);
ret = -1;
goto done;
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index aaacd9bd6bd..4e22341b4f3 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -69,7 +69,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev);
int lbs_remove_card(struct lbs_private *priv);
int lbs_start_card(struct lbs_private *priv);
int lbs_stop_card(struct lbs_private *priv);
-int lbs_reset_device(struct lbs_private *priv);
void lbs_host_to_card_done(struct lbs_private *priv);
int lbs_update_channel(struct lbs_private *priv);
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 84fb49ca0fa..4d4e2f3b66a 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1351,8 +1351,6 @@ done:
lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
return ret;
}
-EXPORT_SYMBOL_GPL(lbs_add_mesh);
-
static void lbs_remove_mesh(struct lbs_private *priv)
{
@@ -1372,7 +1370,6 @@ static void lbs_remove_mesh(struct lbs_private *priv)
free_netdev(mesh_dev);
lbs_deb_leave(LBS_DEB_MESH);
}
-EXPORT_SYMBOL_GPL(lbs_remove_mesh);
/**
* @brief This function finds the CFP in
@@ -1458,20 +1455,6 @@ void lbs_interrupt(struct lbs_private *priv)
}
EXPORT_SYMBOL_GPL(lbs_interrupt);
-int lbs_reset_device(struct lbs_private *priv)
-{
- int ret;
-
- lbs_deb_enter(LBS_DEB_MAIN);
- ret = lbs_prepare_and_send_command(priv, CMD_802_11_RESET,
- CMD_ACT_HALT, 0, 0, NULL);
- msleep_interruptible(10);
-
- lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
- return ret;
-}
-EXPORT_SYMBOL_GPL(lbs_reset_device);
-
static int __init lbs_init_module(void)
{
lbs_deb_enter(LBS_DEB_MAIN);
diff --git a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c
index 5cda49aff3a..d191e055a78 100644
--- a/drivers/net/wireless/p54common.c
+++ b/drivers/net/wireless/p54common.c
@@ -166,18 +166,23 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
struct p54_common *priv = dev->priv;
struct eeprom_pda_wrap *wrap = NULL;
struct pda_entry *entry;
- int i = 0;
unsigned int data_len, entry_len;
void *tmp;
int err;
+ u8 *end = (u8 *)eeprom + len;
wrap = (struct eeprom_pda_wrap *) eeprom;
- entry = (void *)wrap->data + wrap->len;
- i += 2;
- i += le16_to_cpu(entry->len)*2;
- while (i < len) {
+ entry = (void *)wrap->data + le16_to_cpu(wrap->len);
+
+ /* verify that at least the entry length/code fits */
+ while ((u8 *)entry <= end - sizeof(*entry)) {
entry_len = le16_to_cpu(entry->len);
data_len = ((entry_len - 1) << 1);
+
+ /* abort if entry exceeds whole structure */
+ if ((u8 *)entry + sizeof(*entry) + data_len > end)
+ break;
+
switch (le16_to_cpu(entry->code)) {
case PDR_MAC_ADDRESS:
SET_IEEE80211_PERM_ADDR(dev, entry->data);
@@ -249,13 +254,12 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
priv->version = *(u8 *)(entry->data + 1);
break;
case PDR_END:
- i = len;
+ /* make it overrun */
+ entry_len = len;
break;
}
entry = (void *)entry + (entry_len + 1)*2;
- i += 2;
- i += entry_len*2;
}
if (!priv->iq_autocal || !priv->output_limit || !priv->curve_data) {
diff --git a/drivers/net/wireless/p54common.h b/drivers/net/wireless/p54common.h
index a721334e20d..b67ff34e26f 100644
--- a/drivers/net/wireless/p54common.h
+++ b/drivers/net/wireless/p54common.h
@@ -53,10 +53,10 @@ struct pda_entry {
} __attribute__ ((packed));
struct eeprom_pda_wrap {
- u32 magic;
- u16 pad;
- u16 len;
- u32 arm_opcode;
+ __le32 magic;
+ __le16 pad;
+ __le16 len;
+ __le32 arm_opcode;
u8 data[0];
} __attribute__ ((packed));
diff --git a/drivers/net/wireless/p54usb.c b/drivers/net/wireless/p54usb.c
index 60d286eb0b8..e7d4aee8799 100644
--- a/drivers/net/wireless/p54usb.c
+++ b/drivers/net/wireless/p54usb.c
@@ -35,6 +35,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
{USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */
{USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */
+ {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */
{USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
{USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
{USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
@@ -62,6 +63,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
{USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
{USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
+ {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
{USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
{USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
{USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index d3ecf89abd9..10b776c1adc 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -228,9 +228,9 @@ struct NDIS_WLAN_BSSID_EX {
struct NDIS_802_11_SSID Ssid;
__le32 Privacy;
__le32 Rssi;
- enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+ __le32 NetworkTypeInUse;
struct NDIS_802_11_CONFIGURATION Configuration;
- enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+ __le32 InfrastructureMode;
u8 SupportedRates[NDIS_802_11_LENGTH_RATES_EX];
__le32 IELength;
u8 IEs[0];
@@ -260,7 +260,7 @@ struct NDIS_802_11_KEY {
__le32 KeyLength;
u8 Bssid[6];
u8 Padding[6];
- __le64 KeyRSC;
+ u8 KeyRSC[8];
u8 KeyMaterial[32];
} __attribute__((packed));
@@ -279,11 +279,11 @@ struct RNDIS_CONFIG_PARAMETER_INFOBUFFER {
} __attribute__((packed));
/* these have to match what is in wpa_supplicant */
-enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
-enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, CIPHER_WEP104 }
- wpa_cipher;
-enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, KEY_MGMT_802_1X_NO_WPA,
- KEY_MGMT_WPA_NONE } wpa_key_mgmt;
+enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP };
+enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
+ CIPHER_WEP104 };
+enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
+ KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE };
/*
* private data
@@ -1508,7 +1508,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
struct usbnet *usbdev = dev->priv;
struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
struct NDIS_802_11_KEY ndis_key;
- int i, keyidx, ret;
+ int keyidx, ret;
u8 *addr;
keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
@@ -1543,9 +1543,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
ndis_key.KeyIndex = cpu_to_le32(keyidx);
if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
- for (i = 0; i < 6; i++)
- ndis_key.KeyRSC |=
- cpu_to_le64(ext->rx_seq[i] << (i * 8));
+ memcpy(ndis_key.KeyRSC, ext->rx_seq, 6);
ndis_key.KeyIndex |= cpu_to_le32(1 << 29);
}
@@ -2300,7 +2298,7 @@ static void rndis_update_wireless_stats(struct work_struct *work)
struct usbnet *usbdev = priv->usbdev;
struct iw_statistics iwstats;
__le32 rssi, tmp;
- int len, ret, bitrate, j;
+ int len, ret, j;
unsigned long flags;
int update_jiffies = STATS_UPDATE_JIFFIES;
void *buf;
@@ -2352,14 +2350,10 @@ static void rndis_update_wireless_stats(struct work_struct *work)
if (ret == 0)
iwstats.discard.misc += le32_to_cpu(tmp);
- /* Workaround transfer stalls on poor quality links. */
- len = sizeof(tmp);
- ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len);
- if (ret == 0) {
- bitrate = le32_to_cpu(tmp) * 100;
- if (bitrate > 11000000)
- goto end;
-
+ /* Workaround transfer stalls on poor quality links.
+ * TODO: find right way to fix these stalls (as stalls do not happen
+ * with ndiswrapper/windows driver). */
+ if (iwstats.qual.qual <= 25) {
/* Decrease stats worker interval to catch stalls.
* faster. Faster than 400-500ms causes packet loss,
* Slower doesn't catch stalls fast enough.
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index d6cba138c7a..c69f85ed766 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -960,8 +960,12 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2400pci_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt2400pci_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index e874fdcae20..91e87b53374 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1112,8 +1112,12 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2500pci_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt2500pci_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 86ded4066f5..638c3d24310 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1001,8 +1001,12 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2500usb_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt2500usb_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
@@ -1839,11 +1843,11 @@ static struct usb_device_id rt2500usb_device_table[] = {
/* Hercules */
{ USB_DEVICE(0x06f8, 0xe000), USB_DEVICE_DATA(&rt2500usb_ops) },
/* Melco */
+ { USB_DEVICE(0x0411, 0x005e), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) },
-
/* MSI */
{ USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) },
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 72cfe00c1ed..07adc576db4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -97,12 +97,16 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
libconf.ant.rx = rx;
libconf.ant.tx = tx;
+ if (rx == rt2x00dev->link.ant.active.rx &&
+ tx == rt2x00dev->link.ant.active.tx)
+ return;
+
/*
* Antenna setup changes require the RX to be disabled,
* else the changes will be ignored by the device.
*/
if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+ rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK);
/*
* Write new antenna setup to device and reset the link tuner.
@@ -116,7 +120,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
rt2x00dev->link.ant.active.tx = libconf.ant.tx;
if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
}
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index c4be2ac4d7a..0d51f478bcd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -61,11 +61,33 @@ EXPORT_SYMBOL_GPL(rt2x00lib_get_ring);
/*
* Link tuning handlers
*/
-static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
+void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
{
+ if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
+ /*
+ * Reset link information.
+ * Both the currently active vgc level as well as
+ * the link tuner counter should be reset. Resetting
+ * the counter is important for devices where the
+ * device should only perform link tuning during the
+ * first minute after being enabled.
+ */
rt2x00dev->link.count = 0;
rt2x00dev->link.vgc_level = 0;
+ /*
+ * Reset the link tuner.
+ */
+ rt2x00dev->ops->lib->reset_tuner(rt2x00dev);
+}
+
+static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
+{
+ /*
+ * Clear all (possibly) pre-existing quality statistics.
+ */
memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual));
/*
@@ -79,10 +101,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
rt2x00dev->link.qual.rx_percentage = 50;
rt2x00dev->link.qual.tx_percentage = 50;
- /*
- * Reset the link tuner.
- */
- rt2x00dev->ops->lib->reset_tuner(rt2x00dev);
+ rt2x00lib_reset_link_tuner(rt2x00dev);
queue_delayed_work(rt2x00dev->hw->workqueue,
&rt2x00dev->link.work, LINK_TUNE_INTERVAL);
@@ -93,15 +112,6 @@ static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev)
cancel_delayed_work_sync(&rt2x00dev->link.work);
}
-void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
- if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
- return;
-
- rt2x00lib_stop_link_tuner(rt2x00dev);
- rt2x00lib_start_link_tuner(rt2x00dev);
-}
-
/*
* Ring initialization
*/
@@ -260,19 +270,11 @@ static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
if (sample_a == sample_b)
return;
- if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) {
- if (sample_a > sample_b && rx == ANTENNA_B)
- rx = ANTENNA_A;
- else if (rx == ANTENNA_A)
- rx = ANTENNA_B;
- }
+ if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
+ rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
- if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) {
- if (sample_a > sample_b && tx == ANTENNA_B)
- tx = ANTENNA_A;
- else if (tx == ANTENNA_A)
- tx = ANTENNA_B;
- }
+ if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
+ tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
rt2x00lib_config_antenna(rt2x00dev, rx, tx);
}
@@ -293,7 +295,7 @@ static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
* sample the rssi from the other antenna to make a valid
* comparison between the 2 antennas.
*/
- if ((rssi_curr - rssi_old) > -5 || (rssi_curr - rssi_old) < 5)
+ if (abs(rssi_curr - rssi_old) < 5)
return;
rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
@@ -319,15 +321,15 @@ static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY;
if (rt2x00dev->hw->conf.antenna_sel_rx == 0 &&
- rt2x00dev->default_ant.rx != ANTENNA_SW_DIVERSITY)
+ rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY;
if (rt2x00dev->hw->conf.antenna_sel_tx == 0 &&
- rt2x00dev->default_ant.tx != ANTENNA_SW_DIVERSITY)
+ rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY;
if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) &&
!(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) {
- rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE;
+ rt2x00dev->link.ant.flags = 0;
return;
}
@@ -441,17 +443,18 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
rt2x00dev->ops->lib->link_tuner(rt2x00dev);
/*
- * Evaluate antenna setup.
- */
- rt2x00lib_evaluate_antenna(rt2x00dev);
-
- /*
* Precalculate a portion of the link signal which is
* in based on the tx/rx success/failure counters.
*/
rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual);
/*
+ * Evaluate antenna setup, make this the last step since this could
+ * possibly reset some statistics.
+ */
+ rt2x00lib_evaluate_antenna(rt2x00dev);
+
+ /*
* Increase tuner counter, and reschedule the next link tuner run.
*/
rt2x00dev->link.count++;
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 838421216da..b1915dc7dda 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -85,6 +85,8 @@ enum dev_state {
STATE_RADIO_OFF,
STATE_RADIO_RX_ON,
STATE_RADIO_RX_OFF,
+ STATE_RADIO_RX_ON_LINK,
+ STATE_RADIO_RX_OFF_LINK,
STATE_RADIO_IRQ_ON,
STATE_RADIO_IRQ_OFF,
};
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index b31f0c26c32..e808db98f2f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1482,8 +1482,12 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt61pci_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt61pci_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 4d576ab3e7f..4fac2d414d8 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1208,8 +1208,12 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
rt73usb_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt73usb_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 27ebd689aa2..5e9a8ace0d8 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -135,13 +135,15 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
while (skb_queue_len(&ring->queue)) {
struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
struct sk_buff *skb;
- struct ieee80211_tx_status status = { {0} };
+ struct ieee80211_tx_status status;
struct ieee80211_tx_control *control;
u32 flags = le32_to_cpu(entry->flags);
if (flags & RTL8180_TX_DESC_FLAG_OWN)
return;
+ memset(&status, 0, sizeof(status));
+
ring->idx = (ring->idx + 1) % ring->entries;
skb = __skb_dequeue(&ring->queue);
pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 0d71716d750..f44505994a0 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -113,10 +113,12 @@ void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
static void rtl8187_tx_cb(struct urb *urb)
{
- struct ieee80211_tx_status status = { {0} };
+ struct ieee80211_tx_status status;
struct sk_buff *skb = (struct sk_buff *)urb->context;
struct rtl8187_tx_info *info = (struct rtl8187_tx_info *)skb->cb;
+ memset(&status, 0, sizeof(status));
+
usb_free_urb(info->urb);
if (info->control)
memcpy(&status.control, info->control, sizeof(status.control));
diff --git a/drivers/net/wireless/wavelan.h b/drivers/net/wireless/wavelan.h
index 27172cde5a3..9ab360558ff 100644
--- a/drivers/net/wireless/wavelan.h
+++ b/drivers/net/wireless/wavelan.h
@@ -85,7 +85,7 @@ union hacs_u
#define HASR_MMC_INTR 0x0002 /* Interrupt request from MMC */
#define HASR_MMC_BUSY 0x0004 /* MMC busy indication */
#define HASR_PSA_BUSY 0x0008 /* LAN parameter storage area busy */
-};
+} __attribute__ ((packed));
typedef struct ha_t ha_t;
struct ha_t
@@ -292,7 +292,7 @@ struct mmw_t
#define MMW_EXT_ANT_INTERNAL 0x00 /* Internal antenna */
#define MMW_EXT_ANT_EXTERNAL 0x03 /* External antenna */
#define MMW_EXT_ANT_IQ_TEST 0x1C /* IQ test pattern (set to 0) */
-};
+} __attribute__ ((packed));
#define MMW_SIZE 37
@@ -347,7 +347,7 @@ struct mmr_t
unsigned char mmr_unused4[1]; /* unused */
unsigned char mmr_fee_data_l; /* Read data from EEPROM (low) */
unsigned char mmr_fee_data_h; /* Read data from EEPROM (high) */
-};
+} __attribute__ ((packed));
#define MMR_SIZE 36
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 49127e4b42c..76ef2d83919 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -360,11 +360,14 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw)
{
struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue;
struct sk_buff *skb;
- struct ieee80211_tx_status status = {{0}};
+ struct ieee80211_tx_status status;
skb = skb_dequeue(q);
if (skb == NULL)
return;
+
+ memset(&status, 0, sizeof(status));
+
tx_status(hw, skb, &status, 0);
}
@@ -389,7 +392,8 @@ void zd_mac_tx_to_dev(struct sk_buff *skb, int error)
if (unlikely(error ||
(cb->control->flags & IEEE80211_TXCTL_NO_ACK)))
{
- struct ieee80211_tx_status status = {{0}};
+ struct ieee80211_tx_status status;
+ memset(&status, 0, sizeof(status));
tx_status(hw, skb, &status, !error);
} else {
struct sk_buff_head *q =
@@ -603,7 +607,9 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
tx_hdr = (struct ieee80211_hdr *)skb->data;
if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1)))
{
- struct ieee80211_tx_status status = {{0}};
+ struct ieee80211_tx_status status;
+
+ memset(&status, 0, sizeof(status));
status.flags = IEEE80211_TX_STATUS_ACK;
status.ack_signal = stats->ssi;
__skb_unlink(skb, q);
diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig
index 1d3b84b4af3..553a9905299 100644
--- a/drivers/parisc/Kconfig
+++ b/drivers/parisc/Kconfig
@@ -103,6 +103,11 @@ config IOMMU_SBA
depends on PCI_LBA
default PCI_LBA
+config IOMMU_HELPER
+ bool
+ depends on IOMMU_SBA || IOMMU_CCIO
+ default y
+
#config PCI_EPIC
# bool "EPIC/SAGA PCI support"
# depends on PCI
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index d08b284de19..62db3c3fe4d 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -43,6 +43,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/scatterlist.h>
+#include <linux/iommu-helper.h>
#include <asm/byteorder.h>
#include <asm/cache.h> /* for L1_CACHE_BYTES */
@@ -302,13 +303,17 @@ static int ioc_count;
*/
#define CCIO_SEARCH_LOOP(ioc, res_idx, mask, size) \
for(; res_ptr < res_end; ++res_ptr) { \
- if(0 == (*res_ptr & mask)) { \
- *res_ptr |= mask; \
- res_idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \
- ioc->res_hint = res_idx + (size >> 3); \
- goto resource_found; \
- } \
- }
+ int ret;\
+ unsigned int idx;\
+ idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \
+ ret = iommu_is_span_boundary(idx << 3, pages_needed, 0, boundary_size);\
+ if ((0 == (*res_ptr & mask)) && !ret) { \
+ *res_ptr |= mask; \
+ res_idx = idx;\
+ ioc->res_hint = res_idx + (size >> 3); \
+ goto resource_found; \
+ } \
+ }
#define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \
u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \
@@ -341,10 +346,11 @@ static int ioc_count;
* of available pages for the requested size.
*/
static int
-ccio_alloc_range(struct ioc *ioc, size_t size)
+ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
{
unsigned int pages_needed = size >> IOVP_SHIFT;
unsigned int res_idx;
+ unsigned long boundary_size;
#ifdef CCIO_SEARCH_TIME
unsigned long cr_start = mfctl(16);
#endif
@@ -360,6 +366,9 @@ ccio_alloc_range(struct ioc *ioc, size_t size)
** ggg sacrifices another 710 to the computer gods.
*/
+ boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
+ 1ULL << IOVP_SHIFT) >> IOVP_SHIFT;
+
if (pages_needed <= 8) {
/*
* LAN traffic will not thrash the TLB IFF the same NIC
@@ -760,7 +769,7 @@ ccio_map_single(struct device *dev, void *addr, size_t size,
ioc->msingle_pages += size >> IOVP_SHIFT;
#endif
- idx = ccio_alloc_range(ioc, size);
+ idx = ccio_alloc_range(ioc, dev, size);
iovp = (dma_addr_t)MKIOVP(idx);
pdir_start = &(ioc->pdir_base[idx]);
diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h
index 97ba8286c59..a9c46cc2db3 100644
--- a/drivers/parisc/iommu-helpers.h
+++ b/drivers/parisc/iommu-helpers.h
@@ -96,8 +96,8 @@ iommu_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents,
static inline unsigned int
iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
- struct scatterlist *startsg, int nents,
- int (*iommu_alloc_range)(struct ioc *, size_t))
+ struct scatterlist *startsg, int nents,
+ int (*iommu_alloc_range)(struct ioc *, struct device *, size_t))
{
struct scatterlist *contig_sg; /* contig chunk head */
unsigned long dma_offset, dma_len; /* start/len of DMA stream */
@@ -166,7 +166,7 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE);
sg_dma_address(contig_sg) =
PIDE_FLAG
- | (iommu_alloc_range(ioc, dma_len) << IOVP_SHIFT)
+ | (iommu_alloc_range(ioc, dev, dma_len) << IOVP_SHIFT)
| dma_offset;
n_mappings++;
}
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index d06627c3f35..bdbe780e21c 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -29,6 +29,7 @@
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/scatterlist.h>
+#include <linux/iommu-helper.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -313,6 +314,12 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
#define RESMAP_MASK(n) (~0UL << (BITS_PER_LONG - (n)))
#define RESMAP_IDX_MASK (sizeof(unsigned long) - 1)
+unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr,
+ unsigned int bitshiftcnt)
+{
+ return (((unsigned long)res_ptr - (unsigned long)ioc->res_map) << 3)
+ + bitshiftcnt;
+}
/**
* sba_search_bitmap - find free space in IO PDIR resource bitmap
@@ -324,19 +331,36 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
* Cool perf optimization: search for log2(size) bits at a time.
*/
static SBA_INLINE unsigned long
-sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
+sba_search_bitmap(struct ioc *ioc, struct device *dev,
+ unsigned long bits_wanted)
{
unsigned long *res_ptr = ioc->res_hint;
unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
- unsigned long pide = ~0UL;
+ unsigned long pide = ~0UL, tpide;
+ unsigned long boundary_size;
+ unsigned long shift;
+ int ret;
+
+ boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
+ 1ULL << IOVP_SHIFT) >> IOVP_SHIFT;
+
+#if defined(ZX1_SUPPORT)
+ BUG_ON(ioc->ibase & ~IOVP_MASK);
+ shift = ioc->ibase >> IOVP_SHIFT;
+#else
+ shift = 0;
+#endif
if (bits_wanted > (BITS_PER_LONG/2)) {
/* Search word at a time - no mask needed */
for(; res_ptr < res_end; ++res_ptr) {
- if (*res_ptr == 0) {
+ tpide = ptr_to_pide(ioc, res_ptr, 0);
+ ret = iommu_is_span_boundary(tpide, bits_wanted,
+ shift,
+ boundary_size);
+ if ((*res_ptr == 0) && !ret) {
*res_ptr = RESMAP_MASK(bits_wanted);
- pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
- pide <<= 3; /* convert to bit address */
+ pide = tpide;
break;
}
}
@@ -365,11 +389,13 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
{
DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr);
WARN_ON(mask == 0);
- if(((*res_ptr) & mask) == 0) {
+ tpide = ptr_to_pide(ioc, res_ptr, bitshiftcnt);
+ ret = iommu_is_span_boundary(tpide, bits_wanted,
+ shift,
+ boundary_size);
+ if ((((*res_ptr) & mask) == 0) && !ret) {
*res_ptr |= mask; /* mark resources busy! */
- pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
- pide <<= 3; /* convert to bit address */
- pide += bitshiftcnt;
+ pide = tpide;
break;
}
mask >>= o;
@@ -404,7 +430,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
* resource bit map.
*/
static int
-sba_alloc_range(struct ioc *ioc, size_t size)
+sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
{
unsigned int pages_needed = size >> IOVP_SHIFT;
#ifdef SBA_COLLECT_STATS
@@ -412,9 +438,9 @@ sba_alloc_range(struct ioc *ioc, size_t size)
#endif
unsigned long pide;
- pide = sba_search_bitmap(ioc, pages_needed);
+ pide = sba_search_bitmap(ioc, dev, pages_needed);
if (pide >= (ioc->res_size << 3)) {
- pide = sba_search_bitmap(ioc, pages_needed);
+ pide = sba_search_bitmap(ioc, dev, pages_needed);
if (pide >= (ioc->res_size << 3))
panic("%s: I/O MMU @ %p is out of mapping resources\n",
__FILE__, ioc->ioc_hpa);
@@ -710,7 +736,7 @@ sba_map_single(struct device *dev, void *addr, size_t size,
ioc->msingle_calls++;
ioc->msingle_pages += size >> IOVP_SHIFT;
#endif
- pide = sba_alloc_range(ioc, size);
+ pide = sba_alloc_range(ioc, dev, size);
iovp = (dma_addr_t) pide << IOVP_SHIFT;
DBG_RUN("%s() 0x%p -> 0x%lx\n",
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index ef5a6a245f5..6a9403d79e0 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -145,13 +145,15 @@ void pci_bus_add_devices(struct pci_bus *bus)
child_bus = dev->subordinate;
child_bus->dev.parent = child_bus->bridge;
retval = device_register(&child_bus->dev);
- if (!retval)
+ if (retval)
+ dev_err(&dev->dev, "Error registering pci_bus,"
+ " continuing...\n");
+ else
retval = device_create_file(&child_bus->dev,
&dev_attr_cpuaffinity);
if (retval)
- dev_err(&dev->dev, "Error registering pci_bus"
- " device bridge symlink,"
- " continuing...\n");
+ dev_err(&dev->dev, "Error creating cpuaffinity"
+ " file, continuing...\n");
}
}
}
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 8ed26480371..f941f609dbf 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -14,11 +14,12 @@
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
- * Copyright (C) Ashok Raj <ashok.raj@intel.com>
- * Copyright (C) Shaohua Li <shaohua.li@intel.com>
- * Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ * Copyright (C) 2006-2008 Intel Corporation
+ * Author: Ashok Raj <ashok.raj@intel.com>
+ * Author: Shaohua Li <shaohua.li@intel.com>
+ * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
*
- * This file implements early detection/parsing of DMA Remapping Devices
+ * This file implements early detection/parsing of DMA Remapping Devices
* reported to OS through BIOS via DMA remapping reporting (DMAR) ACPI
* tables.
*/
diff --git a/drivers/pci/hotplug-pci.c b/drivers/pci/hotplug-pci.c
index a590ef68215..4d4a6447840 100644
--- a/drivers/pci/hotplug-pci.c
+++ b/drivers/pci/hotplug-pci.c
@@ -4,7 +4,7 @@
#include "pci.h"
-unsigned int pci_do_scan_bus(struct pci_bus *bus)
+unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
{
unsigned int max;
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index c8c263875c2..9279d5ba62e 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -392,6 +392,9 @@ static int __init acpiphp_init(void)
{
info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+ if (acpi_pci_disabled)
+ return 0;
+
acpiphp_debug = debug;
/* read all the ACPI info from the system */
@@ -401,6 +404,9 @@ static int __init acpiphp_init(void)
static void __exit acpiphp_exit(void)
{
+ if (acpi_pci_disabled)
+ return;
+
/* deallocate internal data structures etc. */
acpiphp_glue_exit();
}
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index cf22f9e01e0..5e50008d118 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1085,7 +1085,7 @@ static int acpiphp_bus_trim(acpi_handle handle)
* This function should be called per *physical slot*,
* not per each slot object in ACPI namespace.
*/
-static int enable_device(struct acpiphp_slot *slot)
+static int __ref enable_device(struct acpiphp_slot *slot)
{
struct pci_dev *dev;
struct pci_bus *bus = slot->bridge->pci_bus;
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index 750ebd7a4c1..b0a22b92717 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -395,33 +395,34 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle,
{
acpi_handle *phandle = (acpi_handle *)context;
acpi_status status;
- struct acpi_device_info info;
- struct acpi_buffer info_buffer = {
- .length = sizeof(struct acpi_device_info),
- .pointer = &info,
- };
+ struct acpi_device_info *info;
+ struct acpi_buffer info_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ int retval = 0;
status = acpi_get_object_info(handle, &info_buffer);
if (ACPI_FAILURE(status)) {
- err("%s: Failed to get device information\n", __FUNCTION__);
- return 0;
+ err("%s: Failed to get device information status=0x%x\n",
+ __FUNCTION__, status);
+ return retval;
}
- info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0';
-
- if (info.current_status && (info.valid & ACPI_VALID_HID) &&
- (!strcmp(info.hardware_id.value, IBM_HARDWARE_ID1) ||
- !strcmp(info.hardware_id.value, IBM_HARDWARE_ID2))) {
- dbg("found hardware: %s, handle: %p\n", info.hardware_id.value,
- handle);
+ info = info_buffer.pointer;
+ info->hardware_id.value[sizeof(info->hardware_id.value) - 1] = '\0';
+
+ if (info->current_status && (info->valid & ACPI_VALID_HID) &&
+ (!strcmp(info->hardware_id.value, IBM_HARDWARE_ID1) ||
+ !strcmp(info->hardware_id.value, IBM_HARDWARE_ID2))) {
+ dbg("found hardware: %s, handle: %p\n",
+ info->hardware_id.value, handle);
*phandle = handle;
/* returning non-zero causes the search to stop
* and returns this value to the caller of
* acpi_walk_namespace, but it also causes some warnings
* in the acpi debug code to print...
*/
- return FOUND_APCI;
+ retval = FOUND_APCI;
}
- return 0;
+ kfree(info);
+ return retval;
}
static int __init ibm_acpiphp_init(void)
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index 5e9be44817c..b3515fc4cd3 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -250,7 +250,7 @@ int cpci_led_off(struct slot* slot)
* Device configuration functions
*/
-int cpci_configure_slot(struct slot* slot)
+int __ref cpci_configure_slot(struct slot *slot)
{
struct pci_bus *parent;
int fn;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 6eba9b2cfb9..698975a6a21 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -711,7 +711,8 @@ static int hpc_power_off_slot(struct slot * slot)
retval = pcie_write_cmd(slot, slot_cmd, cmd_mask);
if (retval) {
err("%s: Write command failed!\n", __FUNCTION__);
- return -1;
+ retval = -1;
+ goto out;
}
dbg("%s: SLOTCTRL %x write cmd %x\n",
__FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
@@ -722,7 +723,7 @@ static int hpc_power_off_slot(struct slot * slot)
* removed from the slot/adapter.
*/
msleep(1000);
-
+ out:
if (changed)
pcie_unmask_bad_dllp(ctrl);
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index dd50713966d..9372a840b63 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -167,7 +167,7 @@ static void program_fw_provided_values(struct pci_dev *dev)
}
}
-static int pciehp_add_bridge(struct pci_dev *dev)
+static int __ref pciehp_add_bridge(struct pci_dev *dev)
{
struct pci_bus *parent = dev->bus;
int pass, busnr, start = parent->secondary;
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 0a6b25ef194..a69a2152089 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -96,7 +96,7 @@ static void program_fw_provided_values(struct pci_dev *dev)
}
}
-int shpchp_configure_device(struct slot *p_slot)
+int __ref shpchp_configure_device(struct slot *p_slot)
{
struct pci_dev *dev;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index a4c3089f892..977d29b3229 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -14,9 +14,10 @@
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
- * Copyright (C) Ashok Raj <ashok.raj@intel.com>
- * Copyright (C) Shaohua Li <shaohua.li@intel.com>
- * Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ * Copyright (C) 2006-2008 Intel Corporation
+ * Author: Ashok Raj <ashok.raj@intel.com>
+ * Author: Shaohua Li <shaohua.li@intel.com>
+ * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
*/
#include <linux/init.h>
diff --git a/drivers/pci/intel-iommu.h b/drivers/pci/intel-iommu.h
index 07f5f6353bd..afc0ad96122 100644
--- a/drivers/pci/intel-iommu.h
+++ b/drivers/pci/intel-iommu.h
@@ -14,8 +14,9 @@
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
- * Copyright (C) Ashok Raj <ashok.raj@intel.com>
- * Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ * Copyright (C) 2006-2008 Intel Corporation
+ * Author: Ashok Raj <ashok.raj@intel.com>
+ * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
*/
#ifndef _INTEL_IOMMU_H_
diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c
index 8de7ab6c6d0..dbcdd6bfa63 100644
--- a/drivers/pci/iova.c
+++ b/drivers/pci/iova.c
@@ -3,7 +3,8 @@
*
* This file is released under the GPLv2.
*
- * Copyright (C) 2006 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ * Copyright (C) 2006-2008 Intel Corporation
+ * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
*/
#include "iova.h"
diff --git a/drivers/pci/iova.h b/drivers/pci/iova.h
index d521b5b7319..228f6c94b69 100644
--- a/drivers/pci/iova.h
+++ b/drivers/pci/iova.h
@@ -3,7 +3,8 @@
*
* This file is released under the GPLv2.
*
- * Copyright (C) 2006 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ * Copyright (C) 2006-2008 Intel Corporation
+ * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
*
*/
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index e569645d59e..4a23654184f 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -158,6 +158,7 @@ run_osc_out:
/**
* __pci_osc_support_set - register OS support to Firmware
* @flags: OS support bits
+ * @hid: hardware ID
*
* Update OS support fields and doing a _OSC Query to obtain an update
* from Firmware on supported control bits.
@@ -241,8 +242,6 @@ EXPORT_SYMBOL(pci_osc_control_set);
* choose from highest power _SxD to lowest power _SxW
* else // no _PRW at S-state x
* choose highest power _SxD or any lower power
- *
- * currently we simply return _SxD, if present.
*/
static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index ae3df46eaab..183fddaa38b 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -554,6 +554,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
case PM_EVENT_PRETHAW:
/* REVISIT both freeze and pre-thaw "should" use D0 */
case PM_EVENT_SUSPEND:
+ case PM_EVENT_HIBERNATE:
return PCI_D3hot;
default:
printk("Unrecognized suspend event %d\n", state.event);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 4d23b9fb551..2db2e4bb0d1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -286,7 +286,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
}
}
-void pci_read_bridge_bases(struct pci_bus *child)
+void __devinit pci_read_bridge_bases(struct pci_bus *child)
{
struct pci_dev *dev = child->self;
u8 io_base_lo, io_limit_lo;
@@ -472,7 +472,7 @@ static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
* them, we proceed to assigning numbers to the remaining buses in
* order to avoid overlaps between old and new bus numbers.
*/
-int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass)
+int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
{
struct pci_bus *child;
int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
@@ -1008,7 +1008,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn)
return nr;
}
-unsigned int pci_scan_child_bus(struct pci_bus *bus)
+unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
{
unsigned int devfn, pass, max = bus->secondary;
struct pci_dev *dev;
@@ -1116,7 +1116,7 @@ err_out:
return NULL;
}
-struct pci_bus *pci_scan_bus_parented(struct device *parent,
+struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
int bus, struct pci_ops *ops, void *sysdata)
{
struct pci_bus *b;
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 68aeeb7206d..ef18fcd641e 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -422,7 +422,7 @@ int pci_proc_detach_device(struct pci_dev *dev)
struct proc_dir_entry *e;
if ((e = dev->procent)) {
- if (atomic_read(&e->count))
+ if (atomic_read(&e->count) > 1)
return -EBUSY;
remove_proc_entry(e->name, dev->bus->procdir);
dev->procent = NULL;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 0a953d43b9a..e9a333d9855 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -867,13 +867,13 @@ static void quirk_disable_pxb(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
-
-static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
+static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
{
- /* set sb600 sata to ahci mode */
- if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
- u8 tmp;
+ /* set sb600/sb700/sb800 sata to ahci mode */
+ u8 tmp;
+ pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &tmp);
+ if (tmp == 0x01) {
pci_read_config_byte(pdev, 0x40, &tmp);
pci_write_config_byte(pdev, 0x40, tmp|1);
pci_write_config_byte(pdev, 0x9, 1);
@@ -881,10 +881,13 @@ static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x40, tmp);
pdev->class = PCI_CLASS_STORAGE_SATA_AHCI;
+ dev_info(&pdev->dev, "set SATA to AHCI mode\n");
}
}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
/*
* Serverworks CSB5 IDE does not fully support native mode
@@ -1649,9 +1652,8 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
pci_write_config_byte(dev, 0x75, 0x1);
pci_write_config_byte(dev, 0x77, 0x0);
- printk(KERN_INFO
- "PCI: VIA CX700 PCI parking/caching fixup on %s\n",
- pci_name(dev));
+ dev_info(&dev->dev,
+ "Disabling VIA CX700 PCI parking/caching\n");
}
}
}
@@ -1723,10 +1725,34 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2
quirk_msi_ht_cap);
-/*
- * Force enable MSI mapping capability on HT bridges
+/* The nVidia CK804 chipset may have 2 HT MSI mappings.
+ * MSI are supported if the MSI capability set in any of these mappings.
*/
-static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev)
+static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
+{
+ struct pci_dev *pdev;
+
+ if (!dev->subordinate)
+ return;
+
+ /* check HT MSI cap on this chipset and the root one.
+ * a single one having MSI is enough to be sure that MSI are supported.
+ */
+ pdev = pci_get_slot(dev->bus, 0);
+ if (!pdev)
+ return;
+ if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
+ dev_warn(&dev->dev, "MSI quirk detected; "
+ "subordinate MSI disabled\n");
+ dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+ }
+ pci_dev_put(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
+ quirk_nvidia_ck804_msi_ht_cap);
+
+/* Force enable MSI mapping capability on HT bridges */
+static void __devinit ht_enable_msi_mapping(struct pci_dev *dev)
{
int pos, ttl = 48;
@@ -1734,9 +1760,9 @@ static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev)
while (pos && ttl--) {
u8 flags;
- if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, &flags) == 0) {
- printk(KERN_INFO "PCI: Enabling HT MSI Mapping on %s\n",
- pci_name(dev));
+ 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);
@@ -1747,33 +1773,47 @@ static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB,
- quirk_msi_ht_cap_enable);
+ ht_enable_msi_mapping);
-/* The nVidia CK804 chipset may have 2 HT MSI mappings.
- * MSI are supported if the MSI capability set in any of these mappings.
- */
-static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
+static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
{
- struct pci_dev *pdev;
+ struct pci_dev *host_bridge;
+ int pos, ttl = 48;
- if (!dev->subordinate)
+ /*
+ * HT MSI mapping should be disabled on devices that are below
+ * a non-Hypertransport host bridge. Locate the host bridge...
+ */
+ host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+ if (host_bridge == NULL) {
+ dev_warn(&dev->dev,
+ "nv_msi_ht_cap_quirk didn't locate host bridge\n");
return;
+ }
- /* check HT MSI cap on this chipset and the root one.
- * a single one having MSI is enough to be sure that MSI are supported.
- */
- pdev = pci_get_slot(dev->bus, 0);
- if (!pdev)
+ pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE);
+ if (pos != 0) {
+ /* Host bridge is to HT */
+ ht_enable_msi_mapping(dev);
return;
- if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
- dev_warn(&dev->dev, "MSI quirk detected; "
- "subordinate MSI disabled\n");
- dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
}
- pci_dev_put(pdev);
+
+ /* Host bridge is not to HT, disable HT MSI mapping on this device */
+ 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_DEVICE_ID_NVIDIA_CK804_PCIE,
- quirk_nvidia_ck804_msi_ht_cap);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
{
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index a98b2470b9e..bd5c0e03139 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -242,8 +242,7 @@ void pci_remove_rom(struct pci_dev *pdev)
#endif /* 0 */
/**
- * pci_cleanup_rom - internal routine for freeing the ROM copy created
- * by pci_map_rom_copy called from remove.c
+ * pci_cleanup_rom - free the ROM copy created by pci_map_rom_copy
* @pdev: pointer to pci device struct
*
* Free the copied ROM if we allocated one.
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 262b0439abe..125e7b7f34f 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -206,10 +206,8 @@ pci_setup_bridge(struct pci_bus *bus)
if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
-#ifdef CONFIG_RESOURCES_64BIT
- bu = region.start >> 32;
- lu = region.end >> 32;
-#endif
+ bu = upper_32_bits(region.start);
+ lu = upper_32_bits(region.end);
DBG(KERN_INFO " PREFETCH window: 0x%016llx-0x%016llx\n",
(unsigned long long)region.start,
(unsigned long long)region.end);
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index 749515534cc..e54ecc580d9 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -647,7 +647,12 @@ static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_
if ( (mem->card_start > 0x3ffffff) || (region.start > region.end) ||
(mem->speed > 1000) ) {
leave("i82092aa_set_mem_map: invalid address / speed");
- printk("invalid mem map for socket %i : %lx to %lx with a start of %x \n",sock,region.start, region.end, mem->card_start);
+ printk("invalid mem map for socket %i: %llx to %llx with a "
+ "start of %x\n",
+ sock,
+ (unsigned long long)region.start,
+ (unsigned long long)region.end,
+ mem->card_start);
return -EINVAL;
}
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 5480119ff9d..3ce9f3defc1 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -78,8 +78,7 @@ void rio_dev_put(struct rio_dev *rdev)
}
/**
- * rio_device_probe - Tell if a RIO device structure has a matching RIO
- * device id structure
+ * rio_device_probe - Tell if a RIO device structure has a matching RIO device id structure
* @id: the RIO device id structure to match against
* @dev: the RIO device structure to match against
*
@@ -137,7 +136,7 @@ static int rio_device_remove(struct device *dev)
* rio_register_driver - register a new RIO driver
* @rdrv: the RIO driver structure to register
*
- * Adds a &struct rio_driver to the list of registered drivers
+ * Adds a &struct rio_driver to the list of registered drivers.
* Returns a negative value on error, otherwise 0. If no error
* occurred, the driver remains registered even if no device
* was claimed during registration.
@@ -167,8 +166,7 @@ void rio_unregister_driver(struct rio_driver *rdrv)
}
/**
- * rio_match_bus - Tell if a RIO device structure has a matching RIO
- * driver device id structure
+ * rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure
* @dev: the standard device structure to match against
* @drv: the standard driver structure containing the ids to match against
*
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 6402d699072..82f5ad9c3af 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -250,6 +250,15 @@ config RTC_DRV_TWL92330
platforms. The support is integrated with the rest of
the Menelaus driver; it's not separate module.
+config RTC_DRV_S35390A
+ tristate "Seiko Instruments S-35390A"
+ help
+ If you say yes here you will get support for the Seiko
+ Instruments S-35390A.
+
+ This driver can also be built as a module. If so the module
+ will be called rtc-s35390a.
+
endif # I2C
comment "SPI RTC drivers"
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index ec703f34ab8..872f1218ff9 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
+obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o
obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o
obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index e059f94c79e..f3ee2ad566b 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -388,6 +388,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
return seq_printf(seq,
"periodic_IRQ\t: %s\n"
"update_IRQ\t: %s\n"
+ "HPET_emulated\t: %s\n"
// "square_wave\t: %s\n"
// "BCD\t\t: %s\n"
"DST_enable\t: %s\n"
@@ -395,6 +396,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
"batt_status\t: %s\n",
(rtc_control & RTC_PIE) ? "yes" : "no",
(rtc_control & RTC_UIE) ? "yes" : "no",
+ is_hpet_enabled() ? "yes" : "no",
// (rtc_control & RTC_SQWE) ? "yes" : "no",
// (rtc_control & RTC_DM_BINARY) ? "no" : "yes",
(rtc_control & RTC_DST_EN) ? "yes" : "no",
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
new file mode 100644
index 00000000000..e8abc90c32c
--- /dev/null
+++ b/drivers/rtc/rtc-s35390a.c
@@ -0,0 +1,316 @@
+/*
+ * Seiko Instruments S-35390A RTC Driver
+ *
+ * Copyright (c) 2007 Byron Bradley
+ *
+ * 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 <linux/module.h>
+#include <linux/rtc.h>
+#include <linux/i2c.h>
+#include <linux/bitrev.h>
+#include <linux/bcd.h>
+#include <linux/slab.h>
+
+#define S35390A_CMD_STATUS1 0
+#define S35390A_CMD_STATUS2 1
+#define S35390A_CMD_TIME1 2
+
+#define S35390A_BYTE_YEAR 0
+#define S35390A_BYTE_MONTH 1
+#define S35390A_BYTE_DAY 2
+#define S35390A_BYTE_WDAY 3
+#define S35390A_BYTE_HOURS 4
+#define S35390A_BYTE_MINS 5
+#define S35390A_BYTE_SECS 6
+
+#define S35390A_FLAG_POC 0x01
+#define S35390A_FLAG_BLD 0x02
+#define S35390A_FLAG_24H 0x40
+#define S35390A_FLAG_RESET 0x80
+#define S35390A_FLAG_TEST 0x01
+
+struct s35390a {
+ struct i2c_client *client[8];
+ struct rtc_device *rtc;
+ int twentyfourhour;
+};
+
+static int s35390a_set_reg(struct s35390a *s35390a, int reg, char *buf, int len)
+{
+ struct i2c_client *client = s35390a->client[reg];
+ struct i2c_msg msg[] = {
+ { client->addr, 0, len, buf },
+ };
+
+ if ((i2c_transfer(client->adapter, msg, 1)) != 1)
+ return -EIO;
+
+ return 0;
+}
+
+static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len)
+{
+ struct i2c_client *client = s35390a->client[reg];
+ struct i2c_msg msg[] = {
+ { client->addr, I2C_M_RD, len, buf },
+ };
+
+ if ((i2c_transfer(client->adapter, msg, 1)) != 1)
+ return -EIO;
+
+ return 0;
+}
+
+static int s35390a_reset(struct s35390a *s35390a)
+{
+ char buf[1];
+
+ if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)) < 0)
+ return -EIO;
+
+ if (!(buf[0] & (S35390A_FLAG_POC | S35390A_FLAG_BLD)))
+ return 0;
+
+ buf[0] |= (S35390A_FLAG_RESET | S35390A_FLAG_24H);
+ buf[0] &= 0xf0;
+ return s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf));
+}
+
+static int s35390a_disable_test_mode(struct s35390a *s35390a)
+{
+ char buf[1];
+
+ if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf)) < 0)
+ return -EIO;
+
+ if (!(buf[0] & S35390A_FLAG_TEST))
+ return 0;
+
+ buf[0] &= ~S35390A_FLAG_TEST;
+ return s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf));
+}
+
+static char s35390a_hr2reg(struct s35390a *s35390a, int hour)
+{
+ if (s35390a->twentyfourhour)
+ return BIN2BCD(hour);
+
+ if (hour < 12)
+ return BIN2BCD(hour);
+
+ return 0x40 | BIN2BCD(hour - 12);
+}
+
+static int s35390a_reg2hr(struct s35390a *s35390a, char reg)
+{
+ unsigned hour;
+
+ if (s35390a->twentyfourhour)
+ return BCD2BIN(reg & 0x3f);
+
+ hour = BCD2BIN(reg & 0x3f);
+ if (reg & 0x40)
+ hour += 12;
+
+ return hour;
+}
+
+static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm)
+{
+ struct s35390a *s35390a = i2c_get_clientdata(client);
+ int i, err;
+ char buf[7];
+
+ dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d mday=%d, "
+ "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec,
+ tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year,
+ tm->tm_wday);
+
+ buf[S35390A_BYTE_YEAR] = BIN2BCD(tm->tm_year - 100);
+ buf[S35390A_BYTE_MONTH] = BIN2BCD(tm->tm_mon + 1);
+ buf[S35390A_BYTE_DAY] = BIN2BCD(tm->tm_mday);
+ buf[S35390A_BYTE_WDAY] = BIN2BCD(tm->tm_wday);
+ buf[S35390A_BYTE_HOURS] = s35390a_hr2reg(s35390a, tm->tm_hour);
+ buf[S35390A_BYTE_MINS] = BIN2BCD(tm->tm_min);
+ buf[S35390A_BYTE_SECS] = BIN2BCD(tm->tm_sec);
+
+ /* This chip expects the bits of each byte to be in reverse order */
+ for (i = 0; i < 7; ++i)
+ buf[i] = bitrev8(buf[i]);
+
+ err = s35390a_set_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf));
+
+ return err;
+}
+
+static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
+{
+ struct s35390a *s35390a = i2c_get_clientdata(client);
+ char buf[7];
+ int i, err;
+
+ err = s35390a_get_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf));
+ if (err < 0)
+ return err;
+
+ /* This chip returns the bits of each byte in reverse order */
+ for (i = 0; i < 7; ++i)
+ buf[i] = bitrev8(buf[i]);
+
+ tm->tm_sec = BCD2BIN(buf[S35390A_BYTE_SECS]);
+ tm->tm_min = BCD2BIN(buf[S35390A_BYTE_MINS]);
+ tm->tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_BYTE_HOURS]);
+ tm->tm_wday = BCD2BIN(buf[S35390A_BYTE_WDAY]);
+ tm->tm_mday = BCD2BIN(buf[S35390A_BYTE_DAY]);
+ tm->tm_mon = BCD2BIN(buf[S35390A_BYTE_MONTH]) - 1;
+ tm->tm_year = BCD2BIN(buf[S35390A_BYTE_YEAR]) + 100;
+
+ dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, "
+ "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec,
+ tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year,
+ tm->tm_wday);
+
+ return rtc_valid_tm(tm);
+}
+
+static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ return s35390a_get_datetime(to_i2c_client(dev), tm);
+}
+
+static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ return s35390a_set_datetime(to_i2c_client(dev), tm);
+}
+
+static const struct rtc_class_ops s35390a_rtc_ops = {
+ .read_time = s35390a_rtc_read_time,
+ .set_time = s35390a_rtc_set_time,
+};
+
+static struct i2c_driver s35390a_driver;
+
+static int s35390a_probe(struct i2c_client *client)
+{
+ int err;
+ unsigned int i;
+ struct s35390a *s35390a;
+ struct rtc_time tm;
+ char buf[1];
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ err = -ENODEV;
+ goto exit;
+ }
+
+ s35390a = kzalloc(sizeof(struct s35390a), GFP_KERNEL);
+ if (!s35390a) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ s35390a->client[0] = client;
+ i2c_set_clientdata(client, s35390a);
+
+ /* This chip uses multiple addresses, use dummy devices for them */
+ for (i = 1; i < 8; ++i) {
+ s35390a->client[i] = i2c_new_dummy(client->adapter,
+ client->addr + i, "rtc-s35390a");
+ if (!s35390a->client[i]) {
+ dev_err(&client->dev, "Address %02x unavailable\n",
+ client->addr + i);
+ err = -EBUSY;
+ goto exit_dummy;
+ }
+ }
+
+ err = s35390a_reset(s35390a);
+ if (err < 0) {
+ dev_err(&client->dev, "error resetting chip\n");
+ goto exit_dummy;
+ }
+
+ err = s35390a_disable_test_mode(s35390a);
+ if (err < 0) {
+ dev_err(&client->dev, "error disabling test mode\n");
+ goto exit_dummy;
+ }
+
+ err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf));
+ if (err < 0) {
+ dev_err(&client->dev, "error checking 12/24 hour mode\n");
+ goto exit_dummy;
+ }
+ if (buf[0] & S35390A_FLAG_24H)
+ s35390a->twentyfourhour = 1;
+ else
+ s35390a->twentyfourhour = 0;
+
+ if (s35390a_get_datetime(client, &tm) < 0)
+ dev_warn(&client->dev, "clock needs to be set\n");
+
+ s35390a->rtc = rtc_device_register(s35390a_driver.driver.name,
+ &client->dev, &s35390a_rtc_ops, THIS_MODULE);
+
+ if (IS_ERR(s35390a->rtc)) {
+ err = PTR_ERR(s35390a->rtc);
+ goto exit_dummy;
+ }
+ return 0;
+
+exit_dummy:
+ for (i = 1; i < 8; ++i)
+ if (s35390a->client[i])
+ i2c_unregister_device(s35390a->client[i]);
+ kfree(s35390a);
+ i2c_set_clientdata(client, NULL);
+
+exit:
+ return err;
+}
+
+static int s35390a_remove(struct i2c_client *client)
+{
+ unsigned int i;
+
+ struct s35390a *s35390a = i2c_get_clientdata(client);
+ for (i = 1; i < 8; ++i)
+ if (s35390a->client[i])
+ i2c_unregister_device(s35390a->client[i]);
+
+ rtc_device_unregister(s35390a->rtc);
+ kfree(s35390a);
+ i2c_set_clientdata(client, NULL);
+
+ return 0;
+}
+
+static struct i2c_driver s35390a_driver = {
+ .driver = {
+ .name = "rtc-s35390a",
+ },
+ .probe = s35390a_probe,
+ .remove = s35390a_remove,
+};
+
+static int __init s35390a_rtc_init(void)
+{
+ return i2c_add_driver(&s35390a_driver);
+}
+
+static void __exit s35390a_rtc_exit(void)
+{
+ i2c_del_driver(&s35390a_driver);
+}
+
+MODULE_AUTHOR("Byron Bradley <byron.bbradley@gmail.com>");
+MODULE_DESCRIPTION("S35390A RTC driver");
+MODULE_LICENSE("GPL");
+
+module_init(s35390a_rtc_init);
+module_exit(s35390a_rtc_exit);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index d984e0fae63..ccf46c96adb 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1149,12 +1149,14 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
{
struct list_head *l, *n;
struct dasd_ccw_req *cqr;
+ struct dasd_block *block;
list_for_each_safe(l, n, final_queue) {
cqr = list_entry(l, struct dasd_ccw_req, devlist);
list_del_init(&cqr->devlist);
- if (cqr->block)
- spin_lock_bh(&cqr->block->queue_lock);
+ block = cqr->block;
+ if (block)
+ spin_lock_bh(&block->queue_lock);
switch (cqr->status) {
case DASD_CQR_SUCCESS:
cqr->status = DASD_CQR_DONE;
@@ -1172,15 +1174,13 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
cqr, cqr->status);
BUG();
}
- if (cqr->block)
- spin_unlock_bh(&cqr->block->queue_lock);
if (cqr->callback != NULL)
(cqr->callback)(cqr, cqr->callback_data);
+ if (block)
+ spin_unlock_bh(&block->queue_lock);
}
}
-
-
/*
* Take a look at the first request on the ccw queue and check
* if it reached its expire time. If so, terminate the IO.
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index f69714a0e9e..b19db20a0be 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -2310,10 +2310,8 @@ static int
dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
{
- /* check failed CCW */
- if (cqr1->irb.scsw.cpa != cqr2->irb.scsw.cpa) {
- // return 0; /* CCW doesn't match */
- }
+ if (cqr1->startdev != cqr2->startdev)
+ return 0;
if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons)
return 0;
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 28a86f07004..556063e8f7a 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -62,8 +62,10 @@ dasd_devices_show(struct seq_file *m, void *v)
return 0;
if (device->block)
block = device->block;
- else
+ else {
+ dasd_put_device(device);
return 0;
+ }
/* Print device number. */
seq_printf(m, "%s", device->cdev->dev.bus_id);
/* Print discipline string. */
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 3faf0538b32..e6c94dbfdea 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -666,7 +666,7 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
page_addr = (unsigned long)
page_address(bvec->bv_page) + bvec->bv_offset;
source_addr = dev_info->start + (index<<12) + bytes_done;
- if (unlikely(page_addr & 4095) != 0 || (bvec->bv_len & 4095) != 0)
+ if (unlikely((page_addr & 4095) != 0) || (bvec->bv_len & 4095) != 0)
// More paranoia.
goto fail;
if (bio_data_dir(bio) == READ) {
diff --git a/drivers/s390/char/defkeymap.c b/drivers/s390/char/defkeymap.c
index 389346cda6c..07c7f31081b 100644
--- a/drivers/s390/char/defkeymap.c
+++ b/drivers/s390/char/defkeymap.c
@@ -151,8 +151,8 @@ char *func_table[MAX_NR_FUNC] = {
};
struct kbdiacruc accent_table[MAX_DIACR] = {
- {'^', 'c', '\003'}, {'^', 'd', '\004'},
- {'^', 'z', '\032'}, {'^', '\012', '\000'},
+ {'^', 'c', 0003}, {'^', 'd', 0004},
+ {'^', 'z', 0032}, {'^', 0012, 0000},
};
unsigned int accent_table_size = 4;
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 25629b92dec..2c7a1ee6b04 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -29,10 +29,10 @@ static ext_int_info_t ext_int_info_hwc;
/* Lock to protect internal data consistency. */
static DEFINE_SPINLOCK(sclp_lock);
-/* Mask of events that we can receive from the sclp interface. */
+/* Mask of events that we can send to the sclp interface. */
static sccb_mask_t sclp_receive_mask;
-/* Mask of events that we can send to the sclp interface. */
+/* Mask of events that we can receive from the sclp interface. */
static sccb_mask_t sclp_send_mask;
/* List of registered event listeners and senders. */
@@ -380,7 +380,7 @@ sclp_interrupt_handler(__u16 code)
}
sclp_running_state = sclp_running_state_idle;
}
- if (evbuf_pending && sclp_receive_mask != 0 &&
+ if (evbuf_pending &&
sclp_activation_state == sclp_activation_state_active)
__sclp_queue_read_req();
spin_unlock(&sclp_lock);
@@ -459,8 +459,8 @@ sclp_dispatch_state_change(void)
reg = NULL;
list_for_each(l, &sclp_reg_list) {
reg = list_entry(l, struct sclp_register, list);
- receive_mask = reg->receive_mask & sclp_receive_mask;
- send_mask = reg->send_mask & sclp_send_mask;
+ receive_mask = reg->send_mask & sclp_receive_mask;
+ send_mask = reg->receive_mask & sclp_send_mask;
if (reg->sclp_receive_mask != receive_mask ||
reg->sclp_send_mask != send_mask) {
reg->sclp_receive_mask = receive_mask;
@@ -615,8 +615,8 @@ struct init_sccb {
u16 mask_length;
sccb_mask_t receive_mask;
sccb_mask_t send_mask;
- sccb_mask_t sclp_send_mask;
sccb_mask_t sclp_receive_mask;
+ sccb_mask_t sclp_send_mask;
} __attribute__((packed));
/* Prepare init mask request. Called while sclp_lock is locked. */
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index aa8186d18ae..bac80e856f9 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -122,11 +122,13 @@ struct sclp_req {
/* of some routines it wants to be called from the low level driver */
struct sclp_register {
struct list_head list;
- /* event masks this user is registered for */
+ /* User wants to receive: */
sccb_mask_t receive_mask;
+ /* User wants to send: */
sccb_mask_t send_mask;
- /* actually present events */
+ /* H/W can receive: */
sccb_mask_t sclp_receive_mask;
+ /* H/W can send: */
sccb_mask_t sclp_send_mask;
/* called if event type availability changes */
void (*state_change_fn)(struct sclp_register *);
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c
index 9dc77f14fa5..b8f35bc52b7 100644
--- a/drivers/s390/char/sclp_config.c
+++ b/drivers/s390/char/sclp_config.c
@@ -64,7 +64,7 @@ static int __init sclp_conf_init(void)
return rc;
}
- if (!(sclp_conf_register.sclp_receive_mask & EVTYP_CONFMGMDATA_MASK)) {
+ if (!(sclp_conf_register.sclp_send_mask & EVTYP_CONFMGMDATA_MASK)) {
printk(KERN_WARNING TAG "no configuration management.\n");
sclp_unregister(&sclp_conf_register);
rc = -ENOSYS;
diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c
index 41617032afd..9f37456222e 100644
--- a/drivers/s390/char/sclp_cpi_sys.c
+++ b/drivers/s390/char/sclp_cpi_sys.c
@@ -129,7 +129,7 @@ static int cpi_req(void)
"to hardware console.\n");
goto out;
}
- if (!(sclp_cpi_event.sclp_send_mask & EVTYP_CTLPROGIDENT_MASK)) {
+ if (!(sclp_cpi_event.sclp_receive_mask & EVTYP_CTLPROGIDENT_MASK)) {
printk(KERN_WARNING "cpi: no control program "
"identification support\n");
rc = -EOPNOTSUPP;
diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c
index ad7195d3de0..da09781b32f 100644
--- a/drivers/s390/char/sclp_rw.c
+++ b/drivers/s390/char/sclp_rw.c
@@ -452,10 +452,10 @@ sclp_emit_buffer(struct sclp_buffer *buffer,
return -EIO;
sccb = buffer->sccb;
- if (sclp_rw_event.sclp_send_mask & EVTYP_MSG_MASK)
+ if (sclp_rw_event.sclp_receive_mask & EVTYP_MSG_MASK)
/* Use normal write message */
sccb->msg_buf.header.type = EVTYP_MSG;
- else if (sclp_rw_event.sclp_send_mask & EVTYP_PMSGCMD_MASK)
+ else if (sclp_rw_event.sclp_receive_mask & EVTYP_PMSGCMD_MASK)
/* Use write priority message */
sccb->msg_buf.header.type = EVTYP_PMSGCMD;
else
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index f47f4a768be..f7b258dfd52 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -202,7 +202,7 @@ sclp_vt220_callback(struct sclp_req *request, void *data)
static int
__sclp_vt220_emit(struct sclp_vt220_request *request)
{
- if (!(sclp_vt220_register.sclp_send_mask & EVTYP_VT220MSG_MASK)) {
+ if (!(sclp_vt220_register.sclp_receive_mask & EVTYP_VT220MSG_MASK)) {
request->sclp_req.status = SCLP_REQ_FAILED;
return -EIO;
}
@@ -367,7 +367,7 @@ sclp_vt220_timeout(unsigned long data)
sclp_vt220_emit_current();
}
-#define BUFFER_MAX_DELAY HZ/2
+#define BUFFER_MAX_DELAY HZ/20
/*
* Internal implementation of the write function. Write COUNT bytes of data
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index d35dc3f25d0..fec004f62bc 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -32,7 +32,7 @@
#include "io_sch.h"
static struct timer_list recovery_timer;
-static spinlock_t recovery_lock;
+static DEFINE_SPINLOCK(recovery_lock);
static int recovery_phase;
static const unsigned long recovery_delay[] = { 3, 30, 300 };
@@ -1535,7 +1535,7 @@ static int recovery_check(struct device *dev, void *data)
return 0;
}
-static void recovery_func(unsigned long data)
+static void recovery_work_func(struct work_struct *unused)
{
int redo = 0;
@@ -1553,6 +1553,17 @@ static void recovery_func(unsigned long data)
CIO_MSG_EVENT(2, "recovery: end\n");
}
+static DECLARE_WORK(recovery_work, recovery_work_func);
+
+static void recovery_func(unsigned long data)
+{
+ /*
+ * We can't do our recovery in softirq context and it's not
+ * performance critical, so we schedule it.
+ */
+ schedule_work(&recovery_work);
+}
+
void ccw_device_schedule_recovery(void)
{
unsigned long flags;
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 097fc0967e9..2b5bfb7c69e 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -32,7 +32,7 @@
#include <linux/module.h>
#include <linux/init.h>
-
+#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
@@ -1215,9 +1215,6 @@ tiqdio_is_inbound_q_done(struct qdio_q *q)
if (!no_used)
return 1;
- if (!q->siga_sync && !irq->is_qebsm)
- /* we'll check for more primed buffers in qeth_stop_polling */
- return 0;
if (irq->is_qebsm) {
count = 1;
start_buf = q->first_to_check;
@@ -3332,13 +3329,7 @@ qdio_activate(struct ccw_device *cdev, int flags)
}
}
- wait_event_interruptible_timeout(cdev->private->wait_q,
- ((irq_ptr->state ==
- QDIO_IRQ_STATE_STOPPED) ||
- (irq_ptr->state ==
- QDIO_IRQ_STATE_ERR)),
- QDIO_ACTIVATE_TIMEOUT);
-
+ msleep(QDIO_ACTIVATE_TIMEOUT);
switch (irq_ptr->state) {
case QDIO_IRQ_STATE_STOPPED:
case QDIO_IRQ_STATE_ERR:
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 37870e4e938..da8a272fd75 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -57,10 +57,10 @@
of the queue to 0 */
#define QDIO_ESTABLISH_TIMEOUT (1*HZ)
-#define QDIO_ACTIVATE_TIMEOUT (5*HZ)
#define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ)
#define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ)
#define QDIO_FORCE_CHECK_TIMEOUT (10*HZ)
+#define QDIO_ACTIVATE_TIMEOUT (5) /* 5 ms */
enum qdio_irq_states {
QDIO_IRQ_STATE_INACTIVE,
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index d0c6fd3b1c1..7b0b8190129 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -490,10 +490,12 @@ static int ap_device_probe(struct device *dev)
int rc;
ap_dev->drv = ap_drv;
- spin_lock_bh(&ap_device_lock);
- list_add(&ap_dev->list, &ap_device_list);
- spin_unlock_bh(&ap_device_lock);
rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
+ if (!rc) {
+ spin_lock_bh(&ap_device_lock);
+ list_add(&ap_dev->list, &ap_device_list);
+ spin_unlock_bh(&ap_device_lock);
+ }
return rc;
}
@@ -532,11 +534,11 @@ static int ap_device_remove(struct device *dev)
ap_flush_queue(ap_dev);
del_timer_sync(&ap_dev->timeout);
- if (ap_drv->remove)
- ap_drv->remove(ap_dev);
spin_lock_bh(&ap_device_lock);
list_del_init(&ap_dev->list);
spin_unlock_bh(&ap_device_lock);
+ if (ap_drv->remove)
+ ap_drv->remove(ap_dev);
spin_lock_bh(&ap_dev->lock);
atomic_sub(ap_dev->queue_count, &ap_poll_requests);
spin_unlock_bh(&ap_dev->lock);
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index c3076217871..d8a5c229c5a 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -1851,8 +1851,7 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
}
}
/* See how many write buffers are required to hold this data */
- numBuffers= ( skb->len + privptr->p_env->write_size - 1) /
- ( privptr->p_env->write_size);
+ numBuffers = DIV_ROUND_UP(skb->len, privptr->p_env->write_size);
/* If that number of buffers isn't available, give up for now */
if (privptr->write_free_count < numBuffers ||
@@ -2114,8 +2113,7 @@ init_ccw_bk(struct net_device *dev)
*/
ccw_blocks_perpage= PAGE_SIZE / CCWBK_SIZE;
ccw_pages_required=
- (ccw_blocks_required+ccw_blocks_perpage -1) /
- ccw_blocks_perpage;
+ DIV_ROUND_UP(ccw_blocks_required, ccw_blocks_perpage);
#ifdef DEBUGMSG
printk(KERN_INFO "%s: %s() > ccw_blocks_perpage=%d\n",
@@ -2131,30 +2129,29 @@ init_ccw_bk(struct net_device *dev)
* provide good performance. With packing buffers support 32k
* buffers are used.
*/
- if (privptr->p_env->read_size < PAGE_SIZE) {
- claw_reads_perpage= PAGE_SIZE / privptr->p_env->read_size;
- claw_read_pages= (privptr->p_env->read_buffers +
- claw_reads_perpage -1) / claw_reads_perpage;
+ if (privptr->p_env->read_size < PAGE_SIZE) {
+ claw_reads_perpage = PAGE_SIZE / privptr->p_env->read_size;
+ claw_read_pages = DIV_ROUND_UP(privptr->p_env->read_buffers,
+ claw_reads_perpage);
}
else { /* > or equal */
- privptr->p_buff_pages_perread=
- (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE;
- claw_read_pages=
- privptr->p_env->read_buffers * privptr->p_buff_pages_perread;
+ privptr->p_buff_pages_perread =
+ DIV_ROUND_UP(privptr->p_env->read_size, PAGE_SIZE);
+ claw_read_pages = privptr->p_env->read_buffers *
+ privptr->p_buff_pages_perread;
}
if (privptr->p_env->write_size < PAGE_SIZE) {
- claw_writes_perpage=
- PAGE_SIZE / privptr->p_env->write_size;
- claw_write_pages=
- (privptr->p_env->write_buffers + claw_writes_perpage -1) /
- claw_writes_perpage;
+ claw_writes_perpage =
+ PAGE_SIZE / privptr->p_env->write_size;
+ claw_write_pages = DIV_ROUND_UP(privptr->p_env->write_buffers,
+ claw_writes_perpage);
}
else { /* > or equal */
- privptr->p_buff_pages_perwrite=
- (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE;
- claw_write_pages=
- privptr->p_env->write_buffers * privptr->p_buff_pages_perwrite;
+ privptr->p_buff_pages_perwrite =
+ DIV_ROUND_UP(privptr->p_env->read_size, PAGE_SIZE);
+ claw_write_pages = privptr->p_env->write_buffers *
+ privptr->p_buff_pages_perwrite;
}
#ifdef DEBUGMSG
if (privptr->p_env->read_size < PAGE_SIZE) {
diff --git a/drivers/s390/net/claw.h b/drivers/s390/net/claw.h
index 1ee9a6f0654..1a89d989f34 100644
--- a/drivers/s390/net/claw.h
+++ b/drivers/s390/net/claw.h
@@ -114,11 +114,20 @@ do { \
debug_event(claw_dbf_##name,level,(void*)(addr),len); \
} while (0)
+/* Allow to sort out low debug levels early to avoid wasted sprints */
+static inline int claw_dbf_passes(debug_info_t *dbf_grp, int level)
+{
+ return (level <= dbf_grp->level);
+}
+
#define CLAW_DBF_TEXT_(level,name,text...) \
-do { \
- sprintf(debug_buffer, text); \
- debug_text_event(claw_dbf_##name,level, debug_buffer);\
-} while (0)
+ do { \
+ if (claw_dbf_passes(claw_dbf_##name, level)) { \
+ sprintf(debug_buffer, text); \
+ debug_text_event(claw_dbf_##name, level, \
+ debug_buffer); \
+ } \
+ } while (0)
/*******************************************************
* Define Control Blocks *
@@ -278,8 +287,6 @@ struct claw_env {
__u16 write_size; /* write buffer size */
__u16 dev_id; /* device ident */
__u8 packing; /* are we packing? */
- volatile __u8 queme_switch; /* gate for imed packing */
- volatile unsigned long pk_delay; /* Delay for adaptive packing */
__u8 in_use; /* device active flag */
struct net_device *ndev; /* backward ptr to the net dev*/
};
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 7bfe8d707a3..f51ed997258 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -94,7 +94,7 @@ static int
lcs_register_debug_facility(void)
{
lcs_dbf_setup = debug_register("lcs_setup", 2, 1, 8);
- lcs_dbf_trace = debug_register("lcs_trace", 2, 2, 8);
+ lcs_dbf_trace = debug_register("lcs_trace", 4, 1, 8);
if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) {
PRINT_ERR("Not enough memory for debug facility.\n");
lcs_unregister_debug_facility();
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index 8976fb0b070..d58fea52557 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -16,11 +16,19 @@ do { \
debug_event(lcs_dbf_##name,level,(void*)(addr),len); \
} while (0)
+/* Allow to sort out low debug levels early to avoid wasted sprints */
+static inline int lcs_dbf_passes(debug_info_t *dbf_grp, int level)
+{
+ return (level <= dbf_grp->level);
+}
+
#define LCS_DBF_TEXT_(level,name,text...) \
-do { \
- sprintf(debug_buffer, text); \
- debug_text_event(lcs_dbf_##name,level, debug_buffer);\
-} while (0)
+ do { \
+ if (lcs_dbf_passes(lcs_dbf_##name, level)) { \
+ sprintf(debug_buffer, text); \
+ debug_text_event(lcs_dbf_##name, level, debug_buffer); \
+ } \
+ } while (0)
/**
* sysfs related stuff
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index f3d893cfe61..874a1999448 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -97,12 +97,22 @@ MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf);
-#define IUCV_DBF_TEXT_(name,level,text...) \
- do { \
- char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf); \
- sprintf(iucv_dbf_txt_buf, text); \
- debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \
- put_cpu_var(iucv_dbf_txt_buf); \
+/* Allow to sort out low debug levels early to avoid wasted sprints */
+static inline int iucv_dbf_passes(debug_info_t *dbf_grp, int level)
+{
+ return (level <= dbf_grp->level);
+}
+
+#define IUCV_DBF_TEXT_(name, level, text...) \
+ do { \
+ if (iucv_dbf_passes(iucv_dbf_##name, level)) { \
+ char* iucv_dbf_txt_buf = \
+ get_cpu_var(iucv_dbf_txt_buf); \
+ sprintf(iucv_dbf_txt_buf, text); \
+ debug_text_event(iucv_dbf_##name, level, \
+ iucv_dbf_txt_buf); \
+ put_cpu_var(iucv_dbf_txt_buf); \
+ } \
} while (0)
#define IUCV_DBF_SPRINTF(name,level,text...) \
@@ -137,6 +147,7 @@ PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
#define PRINTK_HEADER " iucv: " /* for debugging */
static struct device_driver netiucv_driver = {
+ .owner = THIS_MODULE,
.name = "netiucv",
.bus = &iucv_bus,
};
@@ -572,9 +583,9 @@ static void netiucv_callback_connres(struct iucv_path *path, u8 ipuser[16])
}
/**
- * Dummy NOP action for all statemachines
+ * NOP action for statemachines
*/
-static void fsm_action_nop(fsm_instance *fi, int event, void *arg)
+static void netiucv_action_nop(fsm_instance *fi, int event, void *arg)
{
}
@@ -1110,7 +1121,7 @@ static const fsm_node dev_fsm[] = {
{ DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop },
{ DEV_STATE_RUNNING, DEV_EVENT_CONDOWN, dev_action_conndown },
- { DEV_STATE_RUNNING, DEV_EVENT_CONUP, fsm_action_nop },
+ { DEV_STATE_RUNNING, DEV_EVENT_CONUP, netiucv_action_nop },
};
static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index a7a0813b24c..c46666a2480 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -992,6 +992,16 @@ config SCSI_IZIP_SLOW_CTR
Generally, saying N is fine.
+config SCSI_MVSAS
+ tristate "Marvell 88SE6440 SAS/SATA support"
+ depends on PCI && SCSI
+ select SCSI_SAS_LIBSAS
+ help
+ This driver supports Marvell SAS/SATA PCI devices.
+
+ To compiler this driver as a module, choose M here: the module
+ will be called mvsas.
+
config SCSI_NCR53C406A
tristate "NCR53c406a SCSI support"
depends on ISA && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 925c26b4fff..23e6ecbd477 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -119,6 +119,7 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/
obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/
obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o
obj-$(CONFIG_SCSI_STEX) += stex.o
+obj-$(CONFIG_SCSI_MVSAS) += mvsas.o
obj-$(CONFIG_PS3_ROM) += ps3rom.o
obj-$(CONFIG_ARM) += arm/
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index 4150c8a8fdc..dfaaae5e73a 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -89,7 +89,7 @@ ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg)
pci_save_state(pdev);
pci_disable_device(pdev);
- if (mesg.event == PM_EVENT_SUSPEND)
+ if (mesg.event & PM_EVENT_SLEEP)
pci_set_power_state(pdev, PCI_D3hot);
return rc;
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index 6d2ae641273..64e62ce59c1 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -695,15 +695,16 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
scb_index = ahc_inb(ahc, SCB_TAG);
scb = ahc_lookup_scb(ahc, scb_index);
if (devinfo.role == ROLE_INITIATOR) {
- if (scb == NULL)
- panic("HOST_MSG_LOOP with "
- "invalid SCB %x\n", scb_index);
+ if (bus_phase == P_MESGOUT) {
+ if (scb == NULL)
+ panic("HOST_MSG_LOOP with "
+ "invalid SCB %x\n",
+ scb_index);
- if (bus_phase == P_MESGOUT)
ahc_setup_initiator_msgout(ahc,
&devinfo,
scb);
- else {
+ } else {
ahc->msg_type =
MSG_TYPE_INITIATOR_MSGIN;
ahc->msgin_index = 0;
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
index dd6e21d6f1d..3d3eaef65fb 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -134,7 +134,7 @@ ahc_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg)
pci_save_state(pdev);
pci_disable_device(pdev);
- if (mesg.event == PM_EVENT_SUSPEND)
+ if (mesg.event & PM_EVENT_SLEEP)
pci_set_power_state(pdev, PCI_D3hot);
return rc;
diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h
index 32f513b1b78..eb8efdcefe4 100644
--- a/drivers/scsi/aic94xx/aic94xx.h
+++ b/drivers/scsi/aic94xx/aic94xx.h
@@ -102,6 +102,7 @@ int asd_abort_task_set(struct domain_device *, u8 *lun);
int asd_clear_aca(struct domain_device *, u8 *lun);
int asd_clear_task_set(struct domain_device *, u8 *lun);
int asd_lu_reset(struct domain_device *, u8 *lun);
+int asd_I_T_nexus_reset(struct domain_device *dev);
int asd_query_task(struct sas_task *);
/* ---------- Adapter and Port management ---------- */
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h
index 150f6706d23..abc757559c1 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.h
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.h
@@ -140,7 +140,7 @@ struct asd_ascb {
/* internally generated command */
struct timer_list timer;
- struct completion completion;
+ struct completion *completion;
u8 tag_valid:1;
__be16 tag; /* error recovery only */
@@ -294,7 +294,6 @@ static inline void asd_init_ascb(struct asd_ha_struct *asd_ha,
ascb->timer.function = NULL;
init_timer(&ascb->timer);
ascb->tc_index = -1;
- init_completion(&ascb->completion);
}
/* Must be called with the tc_index_lock held!
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 5d761eb6744..88d1e731b65 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -1003,7 +1003,7 @@ static struct sas_domain_function_template aic94xx_transport_functions = {
.lldd_abort_task_set = asd_abort_task_set,
.lldd_clear_aca = asd_clear_aca,
.lldd_clear_task_set = asd_clear_task_set,
- .lldd_I_T_nexus_reset = NULL,
+ .lldd_I_T_nexus_reset = asd_I_T_nexus_reset,
.lldd_lu_reset = asd_lu_reset,
.lldd_query_task = asd_query_task,
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c
index 0febad4dd75..ab350504ca5 100644
--- a/drivers/scsi/aic94xx/aic94xx_scb.c
+++ b/drivers/scsi/aic94xx/aic94xx_scb.c
@@ -458,13 +458,19 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
tc_abort = le16_to_cpu(tc_abort);
list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
- struct sas_task *task = ascb->uldd_task;
+ struct sas_task *task = a->uldd_task;
+
+ if (a->tc_index != tc_abort)
+ continue;
- if (task && a->tc_index == tc_abort) {
+ if (task) {
failed_dev = task->dev;
sas_task_abort(task);
- break;
+ } else {
+ ASD_DPRINTK("R_T_A for non TASK scb 0x%x\n",
+ a->scb->header.opcode);
}
+ break;
}
if (!failed_dev) {
@@ -478,7 +484,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
* that the EH will wake up and do something.
*/
list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
- struct sas_task *task = ascb->uldd_task;
+ struct sas_task *task = a->uldd_task;
if (task &&
task->dev == failed_dev &&
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
index 965d4bb999d..008df9ab92a 100644
--- a/drivers/scsi/aic94xx/aic94xx_task.c
+++ b/drivers/scsi/aic94xx/aic94xx_task.c
@@ -343,11 +343,13 @@ Again:
task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
task->task_state_flags |= SAS_TASK_STATE_DONE;
if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) {
+ struct completion *completion = ascb->completion;
spin_unlock_irqrestore(&task->task_state_lock, flags);
ASD_DPRINTK("task 0x%p done with opcode 0x%x resp 0x%x "
"stat 0x%x but aborted by upper layer!\n",
task, opcode, ts->resp, ts->stat);
- complete(&ascb->completion);
+ if (completion)
+ complete(completion);
} else {
spin_unlock_irqrestore(&task->task_state_lock, flags);
task->lldd_task = NULL;
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c
index b52124f3d3a..b9ac8f703a1 100644
--- a/drivers/scsi/aic94xx/aic94xx_tmf.c
+++ b/drivers/scsi/aic94xx/aic94xx_tmf.c
@@ -53,50 +53,64 @@ static int asd_enqueue_internal(struct asd_ascb *ascb,
return res;
}
-static inline void asd_timedout_common(unsigned long data)
-{
- struct asd_ascb *ascb = (void *) data;
- struct asd_seq_data *seq = &ascb->ha->seq;
- unsigned long flags;
+/* ---------- CLEAR NEXUS ---------- */
- spin_lock_irqsave(&seq->pend_q_lock, flags);
- seq->pending--;
- list_del_init(&ascb->list);
- spin_unlock_irqrestore(&seq->pend_q_lock, flags);
-}
+struct tasklet_completion_status {
+ int dl_opcode;
+ int tmf_state;
+ u8 tag_valid:1;
+ __be16 tag;
+};
+
+#define DECLARE_TCS(tcs) \
+ struct tasklet_completion_status tcs = { \
+ .dl_opcode = 0, \
+ .tmf_state = 0, \
+ .tag_valid = 0, \
+ .tag = 0, \
+ }
-/* ---------- CLEAR NEXUS ---------- */
static void asd_clear_nexus_tasklet_complete(struct asd_ascb *ascb,
struct done_list_struct *dl)
{
+ struct tasklet_completion_status *tcs = ascb->uldd_task;
ASD_DPRINTK("%s: here\n", __FUNCTION__);
if (!del_timer(&ascb->timer)) {
ASD_DPRINTK("%s: couldn't delete timer\n", __FUNCTION__);
return;
}
ASD_DPRINTK("%s: opcode: 0x%x\n", __FUNCTION__, dl->opcode);
- ascb->uldd_task = (void *) (unsigned long) dl->opcode;
- complete(&ascb->completion);
+ tcs->dl_opcode = dl->opcode;
+ complete(ascb->completion);
+ asd_ascb_free(ascb);
}
static void asd_clear_nexus_timedout(unsigned long data)
{
- struct asd_ascb *ascb = (void *) data;
+ struct asd_ascb *ascb = (void *)data;
+ struct tasklet_completion_status *tcs = ascb->uldd_task;
ASD_DPRINTK("%s: here\n", __FUNCTION__);
- asd_timedout_common(data);
- ascb->uldd_task = (void *) TMF_RESP_FUNC_FAILED;
- complete(&ascb->completion);
+ tcs->dl_opcode = TMF_RESP_FUNC_FAILED;
+ complete(ascb->completion);
}
#define CLEAR_NEXUS_PRE \
+ struct asd_ascb *ascb; \
+ struct scb *scb; \
+ int res; \
+ DECLARE_COMPLETION_ONSTACK(completion); \
+ DECLARE_TCS(tcs); \
+ \
ASD_DPRINTK("%s: PRE\n", __FUNCTION__); \
res = 1; \
ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL); \
if (!ascb) \
return -ENOMEM; \
\
+ ascb->completion = &completion; \
+ ascb->uldd_task = &tcs; \
scb = ascb->scb; \
scb->header.opcode = CLEAR_NEXUS
@@ -107,10 +121,11 @@ static void asd_clear_nexus_timedout(unsigned long data)
if (res) \
goto out_err; \
ASD_DPRINTK("%s: clear nexus posted, waiting...\n", __FUNCTION__); \
- wait_for_completion(&ascb->completion); \
- res = (int) (unsigned long) ascb->uldd_task; \
+ wait_for_completion(&completion); \
+ res = tcs.dl_opcode; \
if (res == TC_NO_ERROR) \
res = TMF_RESP_FUNC_COMPLETE; \
+ return res; \
out_err: \
asd_ascb_free(ascb); \
return res
@@ -118,9 +133,6 @@ out_err: \
int asd_clear_nexus_ha(struct sas_ha_struct *sas_ha)
{
struct asd_ha_struct *asd_ha = sas_ha->lldd_ha;
- struct asd_ascb *ascb;
- struct scb *scb;
- int res;
CLEAR_NEXUS_PRE;
scb->clear_nexus.nexus = NEXUS_ADAPTER;
@@ -130,9 +142,6 @@ int asd_clear_nexus_ha(struct sas_ha_struct *sas_ha)
int asd_clear_nexus_port(struct asd_sas_port *port)
{
struct asd_ha_struct *asd_ha = port->ha->lldd_ha;
- struct asd_ascb *ascb;
- struct scb *scb;
- int res;
CLEAR_NEXUS_PRE;
scb->clear_nexus.nexus = NEXUS_PORT;
@@ -140,37 +149,77 @@ int asd_clear_nexus_port(struct asd_sas_port *port)
CLEAR_NEXUS_POST;
}
-#if 0
-static int asd_clear_nexus_I_T(struct domain_device *dev)
+enum clear_nexus_phase {
+ NEXUS_PHASE_PRE,
+ NEXUS_PHASE_POST,
+ NEXUS_PHASE_RESUME,
+};
+
+static int asd_clear_nexus_I_T(struct domain_device *dev,
+ enum clear_nexus_phase phase)
{
struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
- struct asd_ascb *ascb;
- struct scb *scb;
- int res;
CLEAR_NEXUS_PRE;
scb->clear_nexus.nexus = NEXUS_I_T;
- scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ;
- if (dev->tproto)
- scb->clear_nexus.flags |= SUSPEND_TX;
+ switch (phase) {
+ case NEXUS_PHASE_PRE:
+ scb->clear_nexus.flags = EXEC_Q | SUSPEND_TX;
+ break;
+ case NEXUS_PHASE_POST:
+ scb->clear_nexus.flags = SEND_Q | NOTINQ;
+ break;
+ case NEXUS_PHASE_RESUME:
+ scb->clear_nexus.flags = RESUME_TX;
+ }
scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
dev->lldd_dev);
CLEAR_NEXUS_POST;
}
-#endif
+
+int asd_I_T_nexus_reset(struct domain_device *dev)
+{
+ int res, tmp_res, i;
+ struct sas_phy *phy = sas_find_local_phy(dev);
+ /* Standard mandates link reset for ATA (type 0) and
+ * hard reset for SSP (type 1) */
+ int reset_type = (dev->dev_type == SATA_DEV ||
+ (dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1;
+
+ asd_clear_nexus_I_T(dev, NEXUS_PHASE_PRE);
+ /* send a hard reset */
+ ASD_DPRINTK("sending %s reset to %s\n",
+ reset_type ? "hard" : "soft", phy->dev.bus_id);
+ res = sas_phy_reset(phy, reset_type);
+ if (res == TMF_RESP_FUNC_COMPLETE) {
+ /* wait for the maximum settle time */
+ msleep(500);
+ /* clear all outstanding commands (keep nexus suspended) */
+ asd_clear_nexus_I_T(dev, NEXUS_PHASE_POST);
+ }
+ for (i = 0 ; i < 3; i++) {
+ tmp_res = asd_clear_nexus_I_T(dev, NEXUS_PHASE_RESUME);
+ if (tmp_res == TC_RESUME)
+ return res;
+ msleep(500);
+ }
+
+ /* This is a bit of a problem: the sequencer is still suspended
+ * and is refusing to resume. Hope it will resume on a bigger hammer
+ * or the disk is lost */
+ dev_printk(KERN_ERR, &phy->dev,
+ "Failed to resume nexus after reset 0x%x\n", tmp_res);
+
+ return TMF_RESP_FUNC_FAILED;
+}
static int asd_clear_nexus_I_T_L(struct domain_device *dev, u8 *lun)
{
struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
- struct asd_ascb *ascb;
- struct scb *scb;
- int res;
CLEAR_NEXUS_PRE;
scb->clear_nexus.nexus = NEXUS_I_T_L;
scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ;
- if (dev->tproto)
- scb->clear_nexus.flags |= SUSPEND_TX;
memcpy(scb->clear_nexus.ssp_task.lun, lun, 8);
scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
dev->lldd_dev);
@@ -181,9 +230,6 @@ static int asd_clear_nexus_tag(struct sas_task *task)
{
struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
struct asd_ascb *tascb = task->lldd_task;
- struct asd_ascb *ascb;
- struct scb *scb;
- int res;
CLEAR_NEXUS_PRE;
scb->clear_nexus.nexus = NEXUS_TAG;
@@ -199,9 +245,6 @@ static int asd_clear_nexus_index(struct sas_task *task)
{
struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
struct asd_ascb *tascb = task->lldd_task;
- struct asd_ascb *ascb;
- struct scb *scb;
- int res;
CLEAR_NEXUS_PRE;
scb->clear_nexus.nexus = NEXUS_TRANS_CX;
@@ -217,11 +260,11 @@ static int asd_clear_nexus_index(struct sas_task *task)
static void asd_tmf_timedout(unsigned long data)
{
struct asd_ascb *ascb = (void *) data;
+ struct tasklet_completion_status *tcs = ascb->uldd_task;
ASD_DPRINTK("tmf timed out\n");
- asd_timedout_common(data);
- ascb->uldd_task = (void *) TMF_RESP_FUNC_FAILED;
- complete(&ascb->completion);
+ tcs->tmf_state = TMF_RESP_FUNC_FAILED;
+ complete(ascb->completion);
}
static int asd_get_tmf_resp_tasklet(struct asd_ascb *ascb,
@@ -273,18 +316,24 @@ static int asd_get_tmf_resp_tasklet(struct asd_ascb *ascb,
static void asd_tmf_tasklet_complete(struct asd_ascb *ascb,
struct done_list_struct *dl)
{
+ struct tasklet_completion_status *tcs;
+
if (!del_timer(&ascb->timer))
return;
+ tcs = ascb->uldd_task;
ASD_DPRINTK("tmf tasklet complete\n");
- if (dl->opcode == TC_SSP_RESP)
- ascb->uldd_task = (void *) (unsigned long)
- asd_get_tmf_resp_tasklet(ascb, dl);
- else
- ascb->uldd_task = (void *) 0xFF00 + (unsigned long) dl->opcode;
+ tcs->dl_opcode = dl->opcode;
+
+ if (dl->opcode == TC_SSP_RESP) {
+ tcs->tmf_state = asd_get_tmf_resp_tasklet(ascb, dl);
+ tcs->tag_valid = ascb->tag_valid;
+ tcs->tag = ascb->tag;
+ }
- complete(&ascb->completion);
+ complete(ascb->completion);
+ asd_ascb_free(ascb);
}
static inline int asd_clear_nexus(struct sas_task *task)
@@ -292,15 +341,19 @@ static inline int asd_clear_nexus(struct sas_task *task)
int res = TMF_RESP_FUNC_FAILED;
int leftover;
struct asd_ascb *tascb = task->lldd_task;
+ DECLARE_COMPLETION_ONSTACK(completion);
unsigned long flags;
+ tascb->completion = &completion;
+
ASD_DPRINTK("task not done, clearing nexus\n");
if (tascb->tag_valid)
res = asd_clear_nexus_tag(task);
else
res = asd_clear_nexus_index(task);
- leftover = wait_for_completion_timeout(&tascb->completion,
+ leftover = wait_for_completion_timeout(&completion,
AIC94XX_SCB_TIMEOUT);
+ tascb->completion = NULL;
ASD_DPRINTK("came back from clear nexus\n");
spin_lock_irqsave(&task->task_state_lock, flags);
if (leftover < 1)
@@ -354,6 +407,11 @@ int asd_abort_task(struct sas_task *task)
struct asd_ascb *ascb = NULL;
struct scb *scb;
int leftover;
+ DECLARE_TCS(tcs);
+ DECLARE_COMPLETION_ONSTACK(completion);
+ DECLARE_COMPLETION_ONSTACK(tascb_completion);
+
+ tascb->completion = &tascb_completion;
spin_lock_irqsave(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
@@ -367,8 +425,10 @@ int asd_abort_task(struct sas_task *task)
ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
if (!ascb)
return -ENOMEM;
- scb = ascb->scb;
+ ascb->uldd_task = &tcs;
+ ascb->completion = &completion;
+ scb = ascb->scb;
scb->header.opcode = SCB_ABORT_TASK;
switch (task->task_proto) {
@@ -410,13 +470,12 @@ int asd_abort_task(struct sas_task *task)
res = asd_enqueue_internal(ascb, asd_tmf_tasklet_complete,
asd_tmf_timedout);
if (res)
- goto out;
- wait_for_completion(&ascb->completion);
+ goto out_free;
+ wait_for_completion(&completion);
ASD_DPRINTK("tmf came back\n");
- res = (int) (unsigned long) ascb->uldd_task;
- tascb->tag = ascb->tag;
- tascb->tag_valid = ascb->tag_valid;
+ tascb->tag = tcs.tag;
+ tascb->tag_valid = tcs.tag_valid;
spin_lock_irqsave(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
@@ -427,63 +486,68 @@ int asd_abort_task(struct sas_task *task)
}
spin_unlock_irqrestore(&task->task_state_lock, flags);
- switch (res) {
- /* The task to be aborted has been sent to the device.
- * We got a Response IU for the ABORT TASK TMF. */
- case TC_NO_ERROR + 0xFF00:
- case TMF_RESP_FUNC_COMPLETE:
- case TMF_RESP_FUNC_FAILED:
- res = asd_clear_nexus(task);
- break;
- case TMF_RESP_INVALID_FRAME:
- case TMF_RESP_OVERLAPPED_TAG:
- case TMF_RESP_FUNC_ESUPP:
- case TMF_RESP_NO_LUN:
- goto out_done; break;
- }
- /* In the following we assume that the managing layer
- * will _never_ make a mistake, when issuing ABORT TASK.
- */
- switch (res) {
- default:
- res = asd_clear_nexus(task);
- /* fallthrough */
- case TC_NO_ERROR + 0xFF00:
- case TMF_RESP_FUNC_COMPLETE:
- break;
- /* The task hasn't been sent to the device xor we never got
- * a (sane) Response IU for the ABORT TASK TMF.
- */
- case TF_NAK_RECV + 0xFF00:
- res = TMF_RESP_INVALID_FRAME;
- break;
- case TF_TMF_TASK_DONE + 0xFF00: /* done but not reported yet */
+ if (tcs.dl_opcode == TC_SSP_RESP) {
+ /* The task to be aborted has been sent to the device.
+ * We got a Response IU for the ABORT TASK TMF. */
+ if (tcs.tmf_state == TMF_RESP_FUNC_COMPLETE)
+ res = asd_clear_nexus(task);
+ else
+ res = tcs.tmf_state;
+ } else if (tcs.dl_opcode == TC_NO_ERROR &&
+ tcs.tmf_state == TMF_RESP_FUNC_FAILED) {
+ /* timeout */
res = TMF_RESP_FUNC_FAILED;
- leftover = wait_for_completion_timeout(&tascb->completion,
- AIC94XX_SCB_TIMEOUT);
- spin_lock_irqsave(&task->task_state_lock, flags);
- if (leftover < 1)
+ } else {
+ /* In the following we assume that the managing layer
+ * will _never_ make a mistake, when issuing ABORT
+ * TASK.
+ */
+ switch (tcs.dl_opcode) {
+ default:
+ res = asd_clear_nexus(task);
+ /* fallthrough */
+ case TC_NO_ERROR:
+ break;
+ /* The task hasn't been sent to the device xor
+ * we never got a (sane) Response IU for the
+ * ABORT TASK TMF.
+ */
+ case TF_NAK_RECV:
+ res = TMF_RESP_INVALID_FRAME;
+ break;
+ case TF_TMF_TASK_DONE: /* done but not reported yet */
res = TMF_RESP_FUNC_FAILED;
- if (task->task_state_flags & SAS_TASK_STATE_DONE)
+ leftover =
+ wait_for_completion_timeout(&tascb_completion,
+ AIC94XX_SCB_TIMEOUT);
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ if (leftover < 1)
+ res = TMF_RESP_FUNC_FAILED;
+ if (task->task_state_flags & SAS_TASK_STATE_DONE)
+ res = TMF_RESP_FUNC_COMPLETE;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+ break;
+ case TF_TMF_NO_TAG:
+ case TF_TMF_TAG_FREE: /* the tag is in the free list */
+ case TF_TMF_NO_CONN_HANDLE: /* no such device */
res = TMF_RESP_FUNC_COMPLETE;
- spin_unlock_irqrestore(&task->task_state_lock, flags);
- goto out_done;
- case TF_TMF_NO_TAG + 0xFF00:
- case TF_TMF_TAG_FREE + 0xFF00: /* the tag is in the free list */
- case TF_TMF_NO_CONN_HANDLE + 0xFF00: /* no such device */
- res = TMF_RESP_FUNC_COMPLETE;
- goto out_done;
- case TF_TMF_NO_CTX + 0xFF00: /* not in seq, or proto != SSP */
- res = TMF_RESP_FUNC_ESUPP;
- goto out;
+ break;
+ case TF_TMF_NO_CTX: /* not in seq, or proto != SSP */
+ res = TMF_RESP_FUNC_ESUPP;
+ break;
+ }
}
-out_done:
+ out_done:
+ tascb->completion = NULL;
if (res == TMF_RESP_FUNC_COMPLETE) {
task->lldd_task = NULL;
mb();
asd_ascb_free(tascb);
}
-out:
+ ASD_DPRINTK("task 0x%p aborted, res: 0x%x\n", task, res);
+ return res;
+
+ out_free:
asd_ascb_free(ascb);
ASD_DPRINTK("task 0x%p aborted, res: 0x%x\n", task, res);
return res;
@@ -511,6 +575,8 @@ static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun,
struct asd_ascb *ascb;
int res = 1;
struct scb *scb;
+ DECLARE_COMPLETION_ONSTACK(completion);
+ DECLARE_TCS(tcs);
if (!(dev->tproto & SAS_PROTOCOL_SSP))
return TMF_RESP_FUNC_ESUPP;
@@ -518,6 +584,9 @@ static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun,
ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
if (!ascb)
return -ENOMEM;
+
+ ascb->completion = &completion;
+ ascb->uldd_task = &tcs;
scb = ascb->scb;
if (tmf == TMF_QUERY_TASK)
@@ -550,31 +619,32 @@ static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun,
asd_tmf_timedout);
if (res)
goto out_err;
- wait_for_completion(&ascb->completion);
- res = (int) (unsigned long) ascb->uldd_task;
+ wait_for_completion(&completion);
- switch (res) {
- case TC_NO_ERROR + 0xFF00:
+ switch (tcs.dl_opcode) {
+ case TC_NO_ERROR:
res = TMF_RESP_FUNC_COMPLETE;
break;
- case TF_NAK_RECV + 0xFF00:
+ case TF_NAK_RECV:
res = TMF_RESP_INVALID_FRAME;
break;
- case TF_TMF_TASK_DONE + 0xFF00:
+ case TF_TMF_TASK_DONE:
res = TMF_RESP_FUNC_FAILED;
break;
- case TF_TMF_NO_TAG + 0xFF00:
- case TF_TMF_TAG_FREE + 0xFF00: /* the tag is in the free list */
- case TF_TMF_NO_CONN_HANDLE + 0xFF00: /* no such device */
+ case TF_TMF_NO_TAG:
+ case TF_TMF_TAG_FREE: /* the tag is in the free list */
+ case TF_TMF_NO_CONN_HANDLE: /* no such device */
res = TMF_RESP_FUNC_COMPLETE;
break;
- case TF_TMF_NO_CTX + 0xFF00: /* not in seq, or proto != SSP */
+ case TF_TMF_NO_CTX: /* not in seq, or proto != SSP */
res = TMF_RESP_FUNC_ESUPP;
break;
default:
/* Allow TMF response codes to propagate upwards */
+ res = tcs.dl_opcode;
break;
}
+ return res;
out_err:
asd_ascb_free(ascb);
return res;
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index 57786502e3e..0393707bdfc 100644
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -48,7 +48,7 @@ struct class_device_attribute;
/*The limit of outstanding scsi command that firmware can handle*/
#define ARCMSR_MAX_OUTSTANDING_CMD 256
#define ARCMSR_MAX_FREECCB_NUM 320
-#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2007/12/24"
+#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2008/02/27"
#define ARCMSR_SCSI_INITIATOR_ID 255
#define ARCMSR_MAX_XFER_SECTORS 512
#define ARCMSR_MAX_XFER_SECTORS_B 4096
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 4f9ff32cfed..f91f79c8007 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1387,18 +1387,16 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
switch(controlcode) {
case ARCMSR_MESSAGE_READ_RQBUFFER: {
- unsigned long *ver_addr;
+ unsigned char *ver_addr;
uint8_t *pQbuffer, *ptmpQbuffer;
int32_t allxfer_len = 0;
- void *tmp;
- tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA);
- ver_addr = (unsigned long *)tmp;
- if (!tmp) {
+ ver_addr = kmalloc(1032, GFP_ATOMIC);
+ if (!ver_addr) {
retvalue = ARCMSR_MESSAGE_FAIL;
goto message_out;
}
- ptmpQbuffer = (uint8_t *) ver_addr;
+ ptmpQbuffer = ver_addr;
while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
&& (allxfer_len < 1031)) {
pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
@@ -1427,26 +1425,24 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
}
arcmsr_iop_message_read(acb);
}
- memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len);
+ memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len);
pcmdmessagefld->cmdmessage.Length = allxfer_len;
pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
- kfree(tmp);
+ kfree(ver_addr);
}
break;
case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
- unsigned long *ver_addr;
+ unsigned char *ver_addr;
int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
uint8_t *pQbuffer, *ptmpuserbuffer;
- void *tmp;
- tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA);
- ver_addr = (unsigned long *)tmp;
- if (!tmp) {
+ ver_addr = kmalloc(1032, GFP_ATOMIC);
+ if (!ver_addr) {
retvalue = ARCMSR_MESSAGE_FAIL;
goto message_out;
}
- ptmpuserbuffer = (uint8_t *)ver_addr;
+ ptmpuserbuffer = ver_addr;
user_len = pcmdmessagefld->cmdmessage.Length;
memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
wqbuf_lastindex = acb->wqbuf_lastindex;
@@ -1492,7 +1488,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
retvalue = ARCMSR_MESSAGE_FAIL;
}
}
- kfree(tmp);
+ kfree(ver_addr);
}
break;
diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h
index 3e73e264972..b65f4cf0eec 100644
--- a/drivers/scsi/arm/fas216.h
+++ b/drivers/scsi/arm/fas216.h
@@ -313,7 +313,7 @@ typedef struct {
/* miscellaneous */
int internal_done; /* flag to indicate request done */
- struct scsi_eh_save *ses; /* holds request sense restore info */
+ struct scsi_eh_save ses; /* holds request sense restore info */
unsigned long magic_end;
} FAS216_Info;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 6d67f5c0eb8..27ebd336409 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -160,7 +160,7 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application,
static void gdth_clear_events(void);
static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
- char *buffer, ushort count, int to_buffer);
+ char *buffer, ushort count);
static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp);
static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive);
@@ -182,7 +182,6 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg);
static void gdth_flush(gdth_ha_str *ha);
-static int gdth_halt(struct notifier_block *nb, ulong event, void *buf);
static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *));
static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
struct gdth_cmndinfo *cmndinfo);
@@ -417,12 +416,6 @@ static inline void gdth_set_sglist(struct scsi_cmnd *cmd,
#include "gdth_proc.h"
#include "gdth_proc.c"
-/* notifier block to get a notify on system shutdown/halt/reboot */
-static struct notifier_block gdth_notifier = {
- gdth_halt, NULL, 0
-};
-static int notifier_disabled = 0;
-
static gdth_ha_str *gdth_find_ha(int hanum)
{
gdth_ha_str *ha;
@@ -445,8 +438,8 @@ static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha)
for (i=0; i<GDTH_MAXCMDS; ++i) {
if (ha->cmndinfo[i].index == 0) {
priv = &ha->cmndinfo[i];
- priv->index = i+1;
memset(priv, 0, sizeof(*priv));
+ priv->index = i+1;
break;
}
}
@@ -493,7 +486,6 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
gdth_ha_str *ha = shost_priv(sdev->host);
Scsi_Cmnd *scp;
struct gdth_cmndinfo cmndinfo;
- struct scatterlist one_sg;
DECLARE_COMPLETION_ONSTACK(wait);
int rval;
@@ -507,13 +499,10 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
/* use request field to save the ptr. to completion struct. */
scp->request = (struct request *)&wait;
scp->timeout_per_command = timeout*HZ;
- sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd));
- gdth_set_sglist(scp, &one_sg);
- gdth_set_sg_count(scp, 1);
- gdth_set_bufflen(scp, sizeof(*gdtcmd));
scp->cmd_len = 12;
memcpy(scp->cmnd, cmnd, 12);
cmndinfo.priority = IOCTL_PRI;
+ cmndinfo.internal_cmd_str = gdtcmd;
cmndinfo.internal_command = 1;
TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0]));
@@ -2355,7 +2344,7 @@ static void gdth_next(gdth_ha_str *ha)
* buffers, kmap_atomic() as needed.
*/
static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
- char *buffer, ushort count, int to_buffer)
+ char *buffer, ushort count)
{
ushort cpcount,i, max_sg = gdth_sg_count(scp);
ushort cpsum,cpnow;
@@ -2381,10 +2370,7 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
}
local_irq_save(flags);
address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
- if (to_buffer)
- memcpy(buffer, address, cpnow);
- else
- memcpy(address, buffer, cpnow);
+ memcpy(address, buffer, cpnow);
flush_dcache_page(sg_page(sl));
kunmap_atomic(address, KM_BIO_SRC_IRQ);
local_irq_restore(flags);
@@ -2438,7 +2424,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
strcpy(inq.vendor,ha->oem_name);
sprintf(inq.product,"Host Drive #%02d",t);
strcpy(inq.revision," ");
- gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0);
+ gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data));
break;
case REQUEST_SENSE:
@@ -2448,7 +2434,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
sd.key = NO_SENSE;
sd.info = 0;
sd.add_length= 0;
- gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0);
+ gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data));
break;
case MODE_SENSE:
@@ -2460,7 +2446,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
- gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0);
+ gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data));
break;
case READ_CAPACITY:
@@ -2470,7 +2456,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
else
rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1);
rdc.block_length = cpu_to_be32(SECTOR_SIZE);
- gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0);
+ gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data));
break;
case SERVICE_ACTION_IN:
@@ -2482,7 +2468,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1);
rdc16.block_length = cpu_to_be32(SECTOR_SIZE);
gdth_copy_internal_data(ha, scp, (char*)&rdc16,
- sizeof(gdth_rdcap16_data), 0);
+ sizeof(gdth_rdcap16_data));
} else {
scp->result = DID_ABORT << 16;
}
@@ -2852,6 +2838,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
{
register gdth_cmd_str *cmdp;
+ struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
int cmd_index;
cmdp= ha->pccb;
@@ -2860,7 +2847,7 @@ static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
if (ha->type==GDT_EISA && ha->cmd_cnt>0)
return 0;
- gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1);
+ *cmdp = *cmndinfo->internal_cmd_str;
cmdp->RequestBuffer = scp;
/* search free command index */
@@ -3794,6 +3781,8 @@ static void gdth_timeout(ulong data)
gdth_ha_str *ha;
ulong flags;
+ BUG_ON(list_empty(&gdth_instances));
+
ha = list_first_entry(&gdth_instances, gdth_ha_str, list);
spin_lock_irqsave(&ha->smp_lock, flags);
@@ -4669,45 +4658,6 @@ static void gdth_flush(gdth_ha_str *ha)
}
}
-/* shutdown routine */
-static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
-{
- gdth_ha_str *ha;
-#ifndef __alpha__
- gdth_cmd_str gdtcmd;
- char cmnd[MAX_COMMAND_SIZE];
-#endif
-
- if (notifier_disabled)
- return NOTIFY_OK;
-
- TRACE2(("gdth_halt() event %d\n",(int)event));
- if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
- return NOTIFY_DONE;
-
- notifier_disabled = 1;
- printk("GDT-HA: Flushing all host drives .. ");
- list_for_each_entry(ha, &gdth_instances, list) {
- gdth_flush(ha);
-
-#ifndef __alpha__
- /* controller reset */
- memset(cmnd, 0xff, MAX_COMMAND_SIZE);
- gdtcmd.BoardNode = LOCALBOARD;
- gdtcmd.Service = CACHESERVICE;
- gdtcmd.OpCode = GDT_RESET;
- TRACE2(("gdth_halt(): reset controller %d\n", ha->hanum));
- gdth_execute(ha->shost, &gdtcmd, cmnd, 10, NULL);
-#endif
- }
- printk("Done.\n");
-
-#ifdef GDTH_STATISTICS
- del_timer(&gdth_timer);
-#endif
- return NOTIFY_OK;
-}
-
/* configure lun */
static int gdth_slave_configure(struct scsi_device *sdev)
{
@@ -5142,13 +5092,13 @@ static void gdth_remove_one(gdth_ha_str *ha)
scsi_remove_host(shp);
+ gdth_flush(ha);
+
if (ha->sdev) {
scsi_free_host_dev(ha->sdev);
ha->sdev = NULL;
}
- gdth_flush(ha);
-
if (shp->irq)
free_irq(shp->irq,ha);
@@ -5174,6 +5124,24 @@ static void gdth_remove_one(gdth_ha_str *ha)
scsi_host_put(shp);
}
+static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
+{
+ gdth_ha_str *ha;
+
+ TRACE2(("gdth_halt() event %d\n", (int)event));
+ if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
+ return NOTIFY_DONE;
+
+ list_for_each_entry(ha, &gdth_instances, list)
+ gdth_flush(ha);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block gdth_notifier = {
+ gdth_halt, NULL, 0
+};
+
static int __init gdth_init(void)
{
if (disable) {
@@ -5236,7 +5204,6 @@ static int __init gdth_init(void)
add_timer(&gdth_timer);
#endif
major = register_chrdev(0,"gdth", &gdth_fops);
- notifier_disabled = 0;
register_reboot_notifier(&gdth_notifier);
gdth_polling = FALSE;
return 0;
@@ -5246,14 +5213,15 @@ static void __exit gdth_exit(void)
{
gdth_ha_str *ha;
- list_for_each_entry(ha, &gdth_instances, list)
- gdth_remove_one(ha);
+ unregister_chrdev(major, "gdth");
+ unregister_reboot_notifier(&gdth_notifier);
#ifdef GDTH_STATISTICS
- del_timer(&gdth_timer);
+ del_timer_sync(&gdth_timer);
#endif
- unregister_chrdev(major,"gdth");
- unregister_reboot_notifier(&gdth_notifier);
+
+ list_for_each_entry(ha, &gdth_instances, list)
+ gdth_remove_one(ha);
}
module_init(gdth_init);
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
index 1434c6b0297..26e4e92515e 100644
--- a/drivers/scsi/gdth.h
+++ b/drivers/scsi/gdth.h
@@ -915,6 +915,7 @@ typedef struct {
struct gdth_cmndinfo { /* per-command private info */
int index;
int internal_command; /* don't call scsi_done */
+ gdth_cmd_str *internal_cmd_str; /* crier for internal messages*/
dma_addr_t sense_paddr; /* sense dma-addr */
unchar priority;
int timeout;
diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
index de5773443c6..ce0228e26ae 100644
--- a/drivers/scsi/gdth_proc.c
+++ b/drivers/scsi/gdth_proc.c
@@ -694,15 +694,13 @@ static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr)
{
ulong flags;
- spin_lock_irqsave(&ha->smp_lock, flags);
-
if (buf == ha->pscratch) {
+ spin_lock_irqsave(&ha->smp_lock, flags);
ha->scratch_busy = FALSE;
+ spin_unlock_irqrestore(&ha->smp_lock, flags);
} else {
pci_free_consistent(ha->pdev, size, buf, paddr);
}
-
- spin_unlock_irqrestore(&ha->smp_lock, flags);
}
#ifdef GDTH_IOCTL_PROC
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c
index bd62131b97a..e5881e92d0f 100644
--- a/drivers/scsi/ibmvscsi/ibmvstgt.c
+++ b/drivers/scsi/ibmvscsi/ibmvstgt.c
@@ -290,7 +290,7 @@ static int ibmvstgt_cmd_done(struct scsi_cmnd *sc,
int err = 0;
dprintk("%p %p %x %u\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0],
- cmd->usg_sg);
+ scsi_sg_count(sc));
if (scsi_sg_count(sc))
err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1);
@@ -838,9 +838,6 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id)
if (!shost)
goto free_vport;
shost->transportt = ibmvstgt_transport_template;
- err = scsi_tgt_alloc_queue(shost);
- if (err)
- goto put_host;
target = host_to_srp_target(shost);
target->shost = shost;
@@ -872,6 +869,10 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id)
if (err)
goto destroy_queue;
+ err = scsi_tgt_alloc_queue(shost);
+ if (err)
+ goto destroy_queue;
+
return 0;
destroy_queue:
crq_queue_destroy(target);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 2074701f7e7..c72014a3e7d 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5140,7 +5140,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
struct ipr_ioadl_desc *last_ioadl = NULL;
- int len = qc->nbytes + qc->pad_len;
+ int len = qc->nbytes;
struct scatterlist *sg;
unsigned int si;
@@ -5206,7 +5206,7 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU;
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
- ipr_cmd->dma_use_sg = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;
+ ipr_cmd->dma_use_sg = qc->n_elem;
ipr_build_ata_ioadl(ipr_cmd, qc);
regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index bb152fb9fec..7ed568f180a 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1576,7 +1576,7 @@ ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr)
METHOD_TRACE("ips_make_passthru", 1);
scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
- length += sg[i].length;
+ length += sg->length;
if (length < sizeof (ips_passthru_t)) {
/* wrong size */
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 59f8445eab0..bdd7de7da39 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1708,8 +1708,8 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
qdepth = ISCSI_DEF_CMD_PER_LUN;
}
- if (!is_power_of_2(cmds_max) ||
- cmds_max >= ISCSI_MGMT_ITT_OFFSET) {
+ if (!is_power_of_2(cmds_max) || cmds_max >= ISCSI_MGMT_ITT_OFFSET ||
+ cmds_max < 2) {
if (cmds_max != 0)
printk(KERN_ERR "iscsi: invalid can_queue of %d. "
"can_queue must be a power of 2 and between "
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 0996f866f14..b0e5ac372a3 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -178,8 +178,8 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
task->uldd_task = qc;
if (ata_is_atapi(qc->tf.protocol)) {
memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
- task->total_xfer_len = qc->nbytes + qc->pad_len;
- task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;
+ task->total_xfer_len = qc->nbytes;
+ task->num_scatter = qc->n_elem;
} else {
for_each_sg(qc->sg, sg, qc->n_elem, si)
xfer += sg->length;
@@ -236,12 +236,12 @@ static void sas_ata_phy_reset(struct ata_port *ap)
struct domain_device *dev = ap->private_data;
struct sas_internal *i =
to_sas_internal(dev->port->ha->core.shost->transportt);
- int res = 0;
+ int res = TMF_RESP_FUNC_FAILED;
if (i->dft->lldd_I_T_nexus_reset)
res = i->dft->lldd_I_T_nexus_reset(dev);
- if (res)
+ if (res != TMF_RESP_FUNC_COMPLETE)
SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __FUNCTION__);
switch (dev->sata_dev.command_set) {
@@ -656,21 +656,6 @@ out:
return res;
}
-static void sas_sata_propagate_sas_addr(struct domain_device *dev)
-{
- unsigned long flags;
- struct asd_sas_port *port = dev->port;
- struct asd_sas_phy *phy;
-
- BUG_ON(dev->parent);
-
- memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
- spin_lock_irqsave(&port->phy_list_lock, flags);
- list_for_each_entry(phy, &port->phy_list, port_phy_el)
- memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
- spin_unlock_irqrestore(&port->phy_list_lock, flags);
-}
-
#define ATA_IDENTIFY_DEV 0xEC
#define ATA_IDENTIFY_PACKET_DEV 0xA1
#define ATA_SET_FEATURES 0xEF
@@ -728,26 +713,6 @@ static int sas_discover_sata_dev(struct domain_device *dev)
goto out_err;
}
cont1:
- /* Get WWN */
- if (dev->port->oob_mode != SATA_OOB_MODE) {
- memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr,
- SAS_ADDR_SIZE);
- } else if (dev->sata_dev.command_set == ATA_COMMAND_SET &&
- (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000)
- == 0x5000) {
- int i;
-
- for (i = 0; i < 4; i++) {
- dev->sas_addr[2*i] =
- (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8;
- dev->sas_addr[2*i+1] =
- le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF;
- }
- }
- sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
- if (!dev->parent)
- sas_sata_propagate_sas_addr(dev);
-
/* XXX Hint: register this SATA device with SATL.
When this returns, dev->sata_dev->lu is alive and
present.
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index e1e2d085c92..39ae68a3b0e 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -92,9 +92,6 @@ static void sas_form_port(struct asd_sas_phy *phy)
if (!port->phy)
port->phy = phy->phy;
- SAS_DPRINTK("phy%d added to port%d, phy_mask:0x%x\n", phy->id,
- port->id, port->phy_mask);
-
if (*(u64 *)port->attached_sas_addr == 0) {
port->class = phy->class;
memcpy(port->attached_sas_addr, phy->attached_sas_addr,
@@ -115,6 +112,11 @@ static void sas_form_port(struct asd_sas_phy *phy)
}
sas_port_add_phy(port->port, phy->phy);
+ SAS_DPRINTK("%s added to %s, phy_mask:0x%x (%16llx)\n",
+ phy->phy->dev.bus_id,port->port->dev.bus_id,
+ port->phy_mask,
+ SAS_ADDR(port->attached_sas_addr));
+
if (port->port_dev)
port->port_dev->pathways = port->num_phys;
@@ -255,12 +257,11 @@ void sas_porte_hard_reset(struct work_struct *work)
static void sas_init_port(struct asd_sas_port *port,
struct sas_ha_struct *sas_ha, int i)
{
+ memset(port, 0, sizeof(*port));
port->id = i;
INIT_LIST_HEAD(&port->dev_list);
spin_lock_init(&port->phy_list_lock);
INIT_LIST_HEAD(&port->phy_list);
- port->num_phys = 0;
- port->phy_mask = 0;
port->ha = sas_ha;
spin_lock_init(&port->dev_list_lock);
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index f869fba8680..1f8241563c6 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -51,10 +51,14 @@ static void sas_scsi_task_done(struct sas_task *task)
{
struct task_status_struct *ts = &task->task_status;
struct scsi_cmnd *sc = task->uldd_task;
- struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(sc->device->host);
- unsigned ts_flags = task->task_state_flags;
int hs = 0, stat = 0;
+ if (unlikely(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
+ /* Aborted tasks will be completed by the error handler */
+ SAS_DPRINTK("task done but aborted\n");
+ return;
+ }
+
if (unlikely(!sc)) {
SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
list_del_init(&task->list);
@@ -120,11 +124,7 @@ static void sas_scsi_task_done(struct sas_task *task)
sc->result = (hs << 16) | stat;
list_del_init(&task->list);
sas_free_task(task);
- /* This is very ugly but this is how SCSI Core works. */
- if (ts_flags & SAS_TASK_STATE_ABORTED)
- scsi_eh_finish_cmd(sc, &sas_ha->eh_done_q);
- else
- sc->scsi_done(sc);
+ sc->scsi_done(sc);
}
static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd)
@@ -255,13 +255,34 @@ out:
return res;
}
+static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
+{
+ struct sas_task *task = TO_SAS_TASK(cmd);
+ struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);
+
+ /* remove the aborted task flag to allow the task to be
+ * completed now. At this point, we only get called following
+ * an actual abort of the task, so we should be guaranteed not
+ * to be racing with any completions from the LLD (hence we
+ * don't need the task state lock to clear the flag) */
+ task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
+ /* Now call task_done. However, task will be free'd after
+ * this */
+ task->task_done(task);
+ /* now finish the command and move it on to the error
+ * handler done list, this also takes it off the
+ * error handler pending list */
+ scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
+}
+
static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
{
struct scsi_cmnd *cmd, *n;
list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
- if (cmd == my_cmd)
- list_del_init(&cmd->eh_entry);
+ if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
+ cmd->device->lun == my_cmd->device->lun)
+ sas_eh_finish_cmd(cmd);
}
}
@@ -274,7 +295,7 @@ static void sas_scsi_clear_queue_I_T(struct list_head *error_q,
struct domain_device *x = cmd_to_domain_dev(cmd);
if (x == dev)
- list_del_init(&cmd->eh_entry);
+ sas_eh_finish_cmd(cmd);
}
}
@@ -288,7 +309,7 @@ static void sas_scsi_clear_queue_port(struct list_head *error_q,
struct asd_sas_port *x = dev->port;
if (x == port)
- list_del_init(&cmd->eh_entry);
+ sas_eh_finish_cmd(cmd);
}
}
@@ -413,7 +434,7 @@ static int sas_recover_I_T(struct domain_device *dev)
}
/* Find the sas_phy that's attached to this device */
-static struct sas_phy *find_local_sas_phy(struct domain_device *dev)
+struct sas_phy *sas_find_local_phy(struct domain_device *dev)
{
struct domain_device *pdev = dev->parent;
struct ex_phy *exphy = NULL;
@@ -435,6 +456,7 @@ static struct sas_phy *find_local_sas_phy(struct domain_device *dev)
BUG_ON(!exphy);
return exphy->phy;
}
+EXPORT_SYMBOL_GPL(sas_find_local_phy);
/* Attempt to send a LUN reset message to a device */
int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
@@ -461,7 +483,7 @@ int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd)
{
struct domain_device *dev = cmd_to_domain_dev(cmd);
- struct sas_phy *phy = find_local_sas_phy(dev);
+ struct sas_phy *phy = sas_find_local_phy(dev);
int res;
res = sas_phy_reset(phy, 1);
@@ -476,10 +498,10 @@ int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd)
}
/* Try to reset a device */
-static int try_to_reset_cmd_device(struct Scsi_Host *shost,
- struct scsi_cmnd *cmd)
+static int try_to_reset_cmd_device(struct scsi_cmnd *cmd)
{
int res;
+ struct Scsi_Host *shost = cmd->device->host;
if (!shost->hostt->eh_device_reset_handler)
goto try_bus_reset;
@@ -519,6 +541,12 @@ Again:
need_reset = task->task_state_flags & SAS_TASK_NEED_DEV_RESET;
spin_unlock_irqrestore(&task->task_state_lock, flags);
+ if (need_reset) {
+ SAS_DPRINTK("%s: task 0x%p requests reset\n",
+ __FUNCTION__, task);
+ goto reset;
+ }
+
SAS_DPRINTK("trying to find task 0x%p\n", task);
res = sas_scsi_find_task(task);
@@ -528,28 +556,23 @@ Again:
case TASK_IS_DONE:
SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
task);
- task->task_done(task);
- if (need_reset)
- try_to_reset_cmd_device(shost, cmd);
+ sas_eh_finish_cmd(cmd);
continue;
case TASK_IS_ABORTED:
SAS_DPRINTK("%s: task 0x%p is aborted\n",
__FUNCTION__, task);
- task->task_done(task);
- if (need_reset)
- try_to_reset_cmd_device(shost, cmd);
+ sas_eh_finish_cmd(cmd);
continue;
case TASK_IS_AT_LU:
SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
+ reset:
tmf_resp = sas_recover_lu(task->dev, cmd);
if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
SAS_DPRINTK("dev %016llx LU %x is "
"recovered\n",
SAS_ADDR(task->dev),
cmd->device->lun);
- task->task_done(task);
- if (need_reset)
- try_to_reset_cmd_device(shost, cmd);
+ sas_eh_finish_cmd(cmd);
sas_scsi_clear_queue_lu(work_q, cmd);
goto Again;
}
@@ -560,15 +583,15 @@ Again:
task);
tmf_resp = sas_recover_I_T(task->dev);
if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
+ struct domain_device *dev = task->dev;
SAS_DPRINTK("I_T %016llx recovered\n",
SAS_ADDR(task->dev->sas_addr));
- task->task_done(task);
- if (need_reset)
- try_to_reset_cmd_device(shost, cmd);
- sas_scsi_clear_queue_I_T(work_q, task->dev);
+ sas_eh_finish_cmd(cmd);
+ sas_scsi_clear_queue_I_T(work_q, dev);
goto Again;
}
/* Hammer time :-) */
+ try_to_reset_cmd_device(cmd);
if (i->dft->lldd_clear_nexus_port) {
struct asd_sas_port *port = task->dev->port;
SAS_DPRINTK("clearing nexus for port:%d\n",
@@ -577,9 +600,7 @@ Again:
if (res == TMF_RESP_FUNC_COMPLETE) {
SAS_DPRINTK("clear nexus port:%d "
"succeeded\n", port->id);
- task->task_done(task);
- if (need_reset)
- try_to_reset_cmd_device(shost, cmd);
+ sas_eh_finish_cmd(cmd);
sas_scsi_clear_queue_port(work_q,
port);
goto Again;
@@ -591,10 +612,8 @@ Again:
if (res == TMF_RESP_FUNC_COMPLETE) {
SAS_DPRINTK("clear nexus ha "
"succeeded\n");
- task->task_done(task);
- if (need_reset)
- try_to_reset_cmd_device(shost, cmd);
- goto out;
+ sas_eh_finish_cmd(cmd);
+ goto clear_q;
}
}
/* If we are here -- this means that no amount
@@ -606,21 +625,16 @@ Again:
SAS_ADDR(task->dev->sas_addr),
cmd->device->lun);
- task->task_done(task);
- if (need_reset)
- try_to_reset_cmd_device(shost, cmd);
+ sas_eh_finish_cmd(cmd);
goto clear_q;
}
}
-out:
return list_empty(work_q);
clear_q:
SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__);
- list_for_each_entry_safe(cmd, n, work_q, eh_entry) {
- struct sas_task *task = TO_SAS_TASK(cmd);
- list_del_init(&cmd->eh_entry);
- task->task_done(task);
- }
+ list_for_each_entry_safe(cmd, n, work_q, eh_entry)
+ sas_eh_finish_cmd(cmd);
+
return list_empty(work_q);
}
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 848d97744b4..0819f5f39de 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -55,7 +55,6 @@ void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_enqueue_node(struct lpfc_vport *, struct lpfc_nodelist *);
void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *);
-void lpfc_disable_node(struct lpfc_vport *, struct lpfc_nodelist *);
struct lpfc_nodelist *lpfc_enable_node(struct lpfc_vport *,
struct lpfc_nodelist *, int);
void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index bd572d6b60a..976653440fb 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1694,7 +1694,7 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
NLP_STE_UNUSED_NODE);
}
-void
+static void
lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{
if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index f53206411cd..fc0d9501aba 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -648,28 +648,24 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count)
unsigned long flags;
struct hbq_dmabuf *hbq_buffer;
- if (!phba->hbqs[hbqno].hbq_alloc_buffer) {
+ if (!phba->hbqs[hbqno].hbq_alloc_buffer)
return 0;
- }
start = phba->hbqs[hbqno].buffer_count;
end = count + start;
- if (end > lpfc_hbq_defs[hbqno]->entry_count) {
+ if (end > lpfc_hbq_defs[hbqno]->entry_count)
end = lpfc_hbq_defs[hbqno]->entry_count;
- }
/* Check whether HBQ is still in use */
spin_lock_irqsave(&phba->hbalock, flags);
- if (!phba->hbq_in_use) {
- spin_unlock_irqrestore(&phba->hbalock, flags);
- return 0;
- }
+ if (!phba->hbq_in_use)
+ goto out;
/* Populate HBQ entries */
for (i = start; i < end; i++) {
hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
if (!hbq_buffer)
- return 1;
+ goto err;
hbq_buffer->tag = (i | (hbqno << 16));
if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer))
phba->hbqs[hbqno].buffer_count++;
@@ -677,8 +673,12 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count)
(phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer);
}
+ out:
spin_unlock_irqrestore(&phba->hbalock, flags);
return 0;
+ err:
+ spin_unlock_irqrestore(&phba->hbalock, flags);
+ return 1;
}
int
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 4d59ae8491a..b135a1ed4b2 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -151,19 +151,19 @@ mega_setup_mailbox(adapter_t *adapter)
*/
if( adapter->flag & BOARD_IOMAP ) {
- outb_p(adapter->mbox_dma & 0xFF,
+ outb(adapter->mbox_dma & 0xFF,
adapter->host->io_port + MBOX_PORT0);
- outb_p((adapter->mbox_dma >> 8) & 0xFF,
+ outb((adapter->mbox_dma >> 8) & 0xFF,
adapter->host->io_port + MBOX_PORT1);
- outb_p((adapter->mbox_dma >> 16) & 0xFF,
+ outb((adapter->mbox_dma >> 16) & 0xFF,
adapter->host->io_port + MBOX_PORT2);
- outb_p((adapter->mbox_dma >> 24) & 0xFF,
+ outb((adapter->mbox_dma >> 24) & 0xFF,
adapter->host->io_port + MBOX_PORT3);
- outb_p(ENABLE_MBOX_BYTE,
+ outb(ENABLE_MBOX_BYTE,
adapter->host->io_port + ENABLE_MBOX_REGION);
irq_ack(adapter);
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 651d09b08f2..fd63b06d9ef 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1759,6 +1759,7 @@ static int mesh_suspend(struct macio_dev *mdev, pm_message_t mesg)
switch (mesg.event) {
case PM_EVENT_SUSPEND:
+ case PM_EVENT_HIBERNATE:
case PM_EVENT_FREEZE:
break;
default:
diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c
new file mode 100644
index 00000000000..5ec0665b3a3
--- /dev/null
+++ b/drivers/scsi/mvsas.c
@@ -0,0 +1,2969 @@
+/*
+ mvsas.c - Marvell 88SE6440 SAS/SATA support
+
+ Copyright 2007 Red Hat, Inc.
+ Copyright 2008 Marvell. <kewei@marvell.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 Free Software Foundation; either version 2,
+ 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; see the file COPYING. If not,
+ write to the Free Software Foundation, 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+
+ ---------------------------------------------------------------
+
+ Random notes:
+ * hardware supports controlling the endian-ness of data
+ structures. this permits elimination of all the le32_to_cpu()
+ and cpu_to_le32() conversions.
+
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/ctype.h>
+#include <scsi/libsas.h>
+#include <asm/io.h>
+
+#define DRV_NAME "mvsas"
+#define DRV_VERSION "0.5.1"
+#define _MV_DUMP 0
+#define MVS_DISABLE_NVRAM
+#define MVS_DISABLE_MSI
+
+#define mr32(reg) readl(regs + MVS_##reg)
+#define mw32(reg,val) writel((val), regs + MVS_##reg)
+#define mw32_f(reg,val) do { \
+ writel((val), regs + MVS_##reg); \
+ readl(regs + MVS_##reg); \
+ } while (0)
+
+#define MVS_ID_NOT_MAPPED 0xff
+#define MVS_CHIP_SLOT_SZ (1U << mvi->chip->slot_width)
+
+/* offset for D2H FIS in the Received FIS List Structure */
+#define SATA_RECEIVED_D2H_FIS(reg_set) \
+ ((void *) mvi->rx_fis + 0x400 + 0x100 * reg_set + 0x40)
+#define SATA_RECEIVED_PIO_FIS(reg_set) \
+ ((void *) mvi->rx_fis + 0x400 + 0x100 * reg_set + 0x20)
+#define UNASSOC_D2H_FIS(id) \
+ ((void *) mvi->rx_fis + 0x100 * id)
+
+#define for_each_phy(__lseq_mask, __mc, __lseq, __rest) \
+ for ((__mc) = (__lseq_mask), (__lseq) = 0; \
+ (__mc) != 0 && __rest; \
+ (++__lseq), (__mc) >>= 1)
+
+/* driver compile-time configuration */
+enum driver_configuration {
+ MVS_TX_RING_SZ = 1024, /* TX ring size (12-bit) */
+ MVS_RX_RING_SZ = 1024, /* RX ring size (12-bit) */
+ /* software requires power-of-2
+ ring size */
+
+ MVS_SLOTS = 512, /* command slots */
+ MVS_SLOT_BUF_SZ = 8192, /* cmd tbl + IU + status + PRD */
+ MVS_SSP_CMD_SZ = 64, /* SSP command table buffer size */
+ MVS_ATA_CMD_SZ = 96, /* SATA command table buffer size */
+ MVS_OAF_SZ = 64, /* Open address frame buffer size */
+
+ MVS_RX_FIS_COUNT = 17, /* Optional rx'd FISs (max 17) */
+
+ MVS_QUEUE_SIZE = 30, /* Support Queue depth */
+};
+
+/* unchangeable hardware details */
+enum hardware_details {
+ MVS_MAX_PHYS = 8, /* max. possible phys */
+ MVS_MAX_PORTS = 8, /* max. possible ports */
+ MVS_RX_FISL_SZ = 0x400 + (MVS_RX_FIS_COUNT * 0x100),
+};
+
+/* peripheral registers (BAR2) */
+enum peripheral_registers {
+ SPI_CTL = 0x10, /* EEPROM control */
+ SPI_CMD = 0x14, /* EEPROM command */
+ SPI_DATA = 0x18, /* EEPROM data */
+};
+
+enum peripheral_register_bits {
+ TWSI_RDY = (1U << 7), /* EEPROM interface ready */
+ TWSI_RD = (1U << 4), /* EEPROM read access */
+
+ SPI_ADDR_MASK = 0x3ffff, /* bits 17:0 */
+};
+
+/* enhanced mode registers (BAR4) */
+enum hw_registers {
+ MVS_GBL_CTL = 0x04, /* global control */
+ MVS_GBL_INT_STAT = 0x08, /* global irq status */
+ MVS_GBL_PI = 0x0C, /* ports implemented bitmask */
+ MVS_GBL_PORT_TYPE = 0xa0, /* port type */
+
+ MVS_CTL = 0x100, /* SAS/SATA port configuration */
+ MVS_PCS = 0x104, /* SAS/SATA port control/status */
+ MVS_CMD_LIST_LO = 0x108, /* cmd list addr */
+ MVS_CMD_LIST_HI = 0x10C,
+ MVS_RX_FIS_LO = 0x110, /* RX FIS list addr */
+ MVS_RX_FIS_HI = 0x114,
+
+ MVS_TX_CFG = 0x120, /* TX configuration */
+ MVS_TX_LO = 0x124, /* TX (delivery) ring addr */
+ MVS_TX_HI = 0x128,
+
+ MVS_TX_PROD_IDX = 0x12C, /* TX producer pointer */
+ MVS_TX_CONS_IDX = 0x130, /* TX consumer pointer (RO) */
+ MVS_RX_CFG = 0x134, /* RX configuration */
+ MVS_RX_LO = 0x138, /* RX (completion) ring addr */
+ MVS_RX_HI = 0x13C,
+ MVS_RX_CONS_IDX = 0x140, /* RX consumer pointer (RO) */
+
+ MVS_INT_COAL = 0x148, /* Int coalescing config */
+ MVS_INT_COAL_TMOUT = 0x14C, /* Int coalescing timeout */
+ MVS_INT_STAT = 0x150, /* Central int status */
+ MVS_INT_MASK = 0x154, /* Central int enable */
+ MVS_INT_STAT_SRS = 0x158, /* SATA register set status */
+ MVS_INT_MASK_SRS = 0x15C,
+
+ /* ports 1-3 follow after this */
+ MVS_P0_INT_STAT = 0x160, /* port0 interrupt status */
+ MVS_P0_INT_MASK = 0x164, /* port0 interrupt mask */
+ MVS_P4_INT_STAT = 0x200, /* Port 4 interrupt status */
+ MVS_P4_INT_MASK = 0x204, /* Port 4 interrupt enable mask */
+
+ /* ports 1-3 follow after this */
+ MVS_P0_SER_CTLSTAT = 0x180, /* port0 serial control/status */
+ MVS_P4_SER_CTLSTAT = 0x220, /* port4 serial control/status */
+
+ MVS_CMD_ADDR = 0x1B8, /* Command register port (addr) */
+ MVS_CMD_DATA = 0x1BC, /* Command register port (data) */
+
+ /* ports 1-3 follow after this */
+ MVS_P0_CFG_ADDR = 0x1C0, /* port0 phy register address */
+ MVS_P0_CFG_DATA = 0x1C4, /* port0 phy register data */
+ MVS_P4_CFG_ADDR = 0x230, /* Port 4 config address */
+ MVS_P4_CFG_DATA = 0x234, /* Port 4 config data */
+
+ /* ports 1-3 follow after this */
+ MVS_P0_VSR_ADDR = 0x1E0, /* port0 VSR address */
+ MVS_P0_VSR_DATA = 0x1E4, /* port0 VSR data */
+ MVS_P4_VSR_ADDR = 0x250, /* port 4 VSR addr */
+ MVS_P4_VSR_DATA = 0x254, /* port 4 VSR data */
+};
+
+enum hw_register_bits {
+ /* MVS_GBL_CTL */
+ INT_EN = (1U << 1), /* Global int enable */
+ HBA_RST = (1U << 0), /* HBA reset */
+
+ /* MVS_GBL_INT_STAT */
+ INT_XOR = (1U << 4), /* XOR engine event */
+ INT_SAS_SATA = (1U << 0), /* SAS/SATA event */
+
+ /* MVS_GBL_PORT_TYPE */ /* shl for ports 1-3 */
+ SATA_TARGET = (1U << 16), /* port0 SATA target enable */
+ MODE_AUTO_DET_PORT7 = (1U << 15), /* port0 SAS/SATA autodetect */
+ MODE_AUTO_DET_PORT6 = (1U << 14),
+ MODE_AUTO_DET_PORT5 = (1U << 13),
+ MODE_AUTO_DET_PORT4 = (1U << 12),
+ MODE_AUTO_DET_PORT3 = (1U << 11),
+ MODE_AUTO_DET_PORT2 = (1U << 10),
+ MODE_AUTO_DET_PORT1 = (1U << 9),
+ MODE_AUTO_DET_PORT0 = (1U << 8),
+ MODE_AUTO_DET_EN = MODE_AUTO_DET_PORT0 | MODE_AUTO_DET_PORT1 |
+ MODE_AUTO_DET_PORT2 | MODE_AUTO_DET_PORT3 |
+ MODE_AUTO_DET_PORT4 | MODE_AUTO_DET_PORT5 |
+ MODE_AUTO_DET_PORT6 | MODE_AUTO_DET_PORT7,
+ MODE_SAS_PORT7_MASK = (1U << 7), /* port0 SAS(1), SATA(0) mode */
+ MODE_SAS_PORT6_MASK = (1U << 6),
+ MODE_SAS_PORT5_MASK = (1U << 5),
+ MODE_SAS_PORT4_MASK = (1U << 4),
+ MODE_SAS_PORT3_MASK = (1U << 3),
+ MODE_SAS_PORT2_MASK = (1U << 2),
+ MODE_SAS_PORT1_MASK = (1U << 1),
+ MODE_SAS_PORT0_MASK = (1U << 0),
+ MODE_SAS_SATA = MODE_SAS_PORT0_MASK | MODE_SAS_PORT1_MASK |
+ MODE_SAS_PORT2_MASK | MODE_SAS_PORT3_MASK |
+ MODE_SAS_PORT4_MASK | MODE_SAS_PORT5_MASK |
+ MODE_SAS_PORT6_MASK | MODE_SAS_PORT7_MASK,
+
+ /* SAS_MODE value may be
+ * dictated (in hw) by values
+ * of SATA_TARGET & AUTO_DET
+ */
+
+ /* MVS_TX_CFG */
+ TX_EN = (1U << 16), /* Enable TX */
+ TX_RING_SZ_MASK = 0xfff, /* TX ring size, bits 11:0 */
+
+ /* MVS_RX_CFG */
+ RX_EN = (1U << 16), /* Enable RX */
+ RX_RING_SZ_MASK = 0xfff, /* RX ring size, bits 11:0 */
+
+ /* MVS_INT_COAL */
+ COAL_EN = (1U << 16), /* Enable int coalescing */
+
+ /* MVS_INT_STAT, MVS_INT_MASK */
+ CINT_I2C = (1U << 31), /* I2C event */
+ CINT_SW0 = (1U << 30), /* software event 0 */
+ CINT_SW1 = (1U << 29), /* software event 1 */
+ CINT_PRD_BC = (1U << 28), /* PRD BC err for read cmd */
+ CINT_DMA_PCIE = (1U << 27), /* DMA to PCIE timeout */
+ CINT_MEM = (1U << 26), /* int mem parity err */
+ CINT_I2C_SLAVE = (1U << 25), /* slave I2C event */
+ CINT_SRS = (1U << 3), /* SRS event */
+ CINT_CI_STOP = (1U << 1), /* cmd issue stopped */
+ CINT_DONE = (1U << 0), /* cmd completion */
+
+ /* shl for ports 1-3 */
+ CINT_PORT_STOPPED = (1U << 16), /* port0 stopped */
+ CINT_PORT = (1U << 8), /* port0 event */
+ CINT_PORT_MASK_OFFSET = 8,
+ CINT_PORT_MASK = (0xFF << CINT_PORT_MASK_OFFSET),
+
+ /* TX (delivery) ring bits */
+ TXQ_CMD_SHIFT = 29,
+ TXQ_CMD_SSP = 1, /* SSP protocol */
+ TXQ_CMD_SMP = 2, /* SMP protocol */
+ TXQ_CMD_STP = 3, /* STP/SATA protocol */
+ TXQ_CMD_SSP_FREE_LIST = 4, /* add to SSP targ free list */
+ TXQ_CMD_SLOT_RESET = 7, /* reset command slot */
+ TXQ_MODE_I = (1U << 28), /* mode: 0=target,1=initiator */
+ TXQ_PRIO_HI = (1U << 27), /* priority: 0=normal, 1=high */
+ TXQ_SRS_SHIFT = 20, /* SATA register set */
+ TXQ_SRS_MASK = 0x7f,
+ TXQ_PHY_SHIFT = 12, /* PHY bitmap */
+ TXQ_PHY_MASK = 0xff,
+ TXQ_SLOT_MASK = 0xfff, /* slot number */
+
+ /* RX (completion) ring bits */
+ RXQ_GOOD = (1U << 23), /* Response good */
+ RXQ_SLOT_RESET = (1U << 21), /* Slot reset complete */
+ RXQ_CMD_RX = (1U << 20), /* target cmd received */
+ RXQ_ATTN = (1U << 19), /* attention */
+ RXQ_RSP = (1U << 18), /* response frame xfer'd */
+ RXQ_ERR = (1U << 17), /* err info rec xfer'd */
+ RXQ_DONE = (1U << 16), /* cmd complete */
+ RXQ_SLOT_MASK = 0xfff, /* slot number */
+
+ /* mvs_cmd_hdr bits */
+ MCH_PRD_LEN_SHIFT = 16, /* 16-bit PRD table len */
+ MCH_SSP_FR_TYPE_SHIFT = 13, /* SSP frame type */
+
+ /* SSP initiator only */
+ MCH_SSP_FR_CMD = 0x0, /* COMMAND frame */
+
+ /* SSP initiator or target */
+ MCH_SSP_FR_TASK = 0x1, /* TASK frame */
+
+ /* SSP target only */
+ MCH_SSP_FR_XFER_RDY = 0x4, /* XFER_RDY frame */
+ MCH_SSP_FR_RESP = 0x5, /* RESPONSE frame */
+ MCH_SSP_FR_READ = 0x6, /* Read DATA frame(s) */
+ MCH_SSP_FR_READ_RESP = 0x7, /* ditto, plus RESPONSE */
+
+ MCH_PASSTHRU = (1U << 12), /* pass-through (SSP) */
+ MCH_FBURST = (1U << 11), /* first burst (SSP) */
+ MCH_CHK_LEN = (1U << 10), /* chk xfer len (SSP) */
+ MCH_RETRY = (1U << 9), /* tport layer retry (SSP) */
+ MCH_PROTECTION = (1U << 8), /* protection info rec (SSP) */
+ MCH_RESET = (1U << 7), /* Reset (STP/SATA) */
+ MCH_FPDMA = (1U << 6), /* First party DMA (STP/SATA) */
+ MCH_ATAPI = (1U << 5), /* ATAPI (STP/SATA) */
+ MCH_BIST = (1U << 4), /* BIST activate (STP/SATA) */
+ MCH_PMP_MASK = 0xf, /* PMP from cmd FIS (STP/SATA)*/
+
+ CCTL_RST = (1U << 5), /* port logic reset */
+
+ /* 0(LSB first), 1(MSB first) */
+ CCTL_ENDIAN_DATA = (1U << 3), /* PRD data */
+ CCTL_ENDIAN_RSP = (1U << 2), /* response frame */
+ CCTL_ENDIAN_OPEN = (1U << 1), /* open address frame */
+ CCTL_ENDIAN_CMD = (1U << 0), /* command table */
+
+ /* MVS_Px_SER_CTLSTAT (per-phy control) */
+ PHY_SSP_RST = (1U << 3), /* reset SSP link layer */
+ PHY_BCAST_CHG = (1U << 2), /* broadcast(change) notif */
+ PHY_RST_HARD = (1U << 1), /* hard reset + phy reset */
+ PHY_RST = (1U << 0), /* phy reset */
+ PHY_MIN_SPP_PHYS_LINK_RATE_MASK = (0xF << 8),
+ PHY_MAX_SPP_PHYS_LINK_RATE_MASK = (0xF << 12),
+ PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET = (16),
+ PHY_NEG_SPP_PHYS_LINK_RATE_MASK =
+ (0xF << PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET),
+ PHY_READY_MASK = (1U << 20),
+
+ /* MVS_Px_INT_STAT, MVS_Px_INT_MASK (per-phy events) */
+ PHYEV_DEC_ERR = (1U << 24), /* Phy Decoding Error */
+ PHYEV_UNASSOC_FIS = (1U << 19), /* unassociated FIS rx'd */
+ PHYEV_AN = (1U << 18), /* SATA async notification */
+ PHYEV_BIST_ACT = (1U << 17), /* BIST activate FIS */
+ PHYEV_SIG_FIS = (1U << 16), /* signature FIS */
+ PHYEV_POOF = (1U << 12), /* phy ready from 1 -> 0 */
+ PHYEV_IU_BIG = (1U << 11), /* IU too long err */
+ PHYEV_IU_SMALL = (1U << 10), /* IU too short err */
+ PHYEV_UNK_TAG = (1U << 9), /* unknown tag */
+ PHYEV_BROAD_CH = (1U << 8), /* broadcast(CHANGE) */
+ PHYEV_COMWAKE = (1U << 7), /* COMWAKE rx'd */
+ PHYEV_PORT_SEL = (1U << 6), /* port selector present */
+ PHYEV_HARD_RST = (1U << 5), /* hard reset rx'd */
+ PHYEV_ID_TMOUT = (1U << 4), /* identify timeout */
+ PHYEV_ID_FAIL = (1U << 3), /* identify failed */
+ PHYEV_ID_DONE = (1U << 2), /* identify done */
+ PHYEV_HARD_RST_DONE = (1U << 1), /* hard reset done */
+ PHYEV_RDY_CH = (1U << 0), /* phy ready changed state */
+
+ /* MVS_PCS */
+ PCS_EN_SATA_REG_SHIFT = (16), /* Enable SATA Register Set */
+ PCS_EN_PORT_XMT_SHIFT = (12), /* Enable Port Transmit */
+ PCS_EN_PORT_XMT_SHIFT2 = (8), /* For 6480 */
+ PCS_SATA_RETRY = (1U << 8), /* retry ctl FIS on R_ERR */
+ PCS_RSP_RX_EN = (1U << 7), /* raw response rx */
+ PCS_SELF_CLEAR = (1U << 5), /* self-clearing int mode */
+ PCS_FIS_RX_EN = (1U << 4), /* FIS rx enable */
+ PCS_CMD_STOP_ERR = (1U << 3), /* cmd stop-on-err enable */
+ PCS_CMD_RST = (1U << 1), /* reset cmd issue */
+ PCS_CMD_EN = (1U << 0), /* enable cmd issue */
+
+ /* Port n Attached Device Info */
+ PORT_DEV_SSP_TRGT = (1U << 19),
+ PORT_DEV_SMP_TRGT = (1U << 18),
+ PORT_DEV_STP_TRGT = (1U << 17),
+ PORT_DEV_SSP_INIT = (1U << 11),
+ PORT_DEV_SMP_INIT = (1U << 10),
+ PORT_DEV_STP_INIT = (1U << 9),
+ PORT_PHY_ID_MASK = (0xFFU << 24),
+ PORT_DEV_TRGT_MASK = (0x7U << 17),
+ PORT_DEV_INIT_MASK = (0x7U << 9),
+ PORT_DEV_TYPE_MASK = (0x7U << 0),
+
+ /* Port n PHY Status */
+ PHY_RDY = (1U << 2),
+ PHY_DW_SYNC = (1U << 1),
+ PHY_OOB_DTCTD = (1U << 0),
+
+ /* VSR */
+ /* PHYMODE 6 (CDB) */
+ PHY_MODE6_DTL_SPEED = (1U << 27),
+};
+
+enum mvs_info_flags {
+ MVF_MSI = (1U << 0), /* MSI is enabled */
+ MVF_PHY_PWR_FIX = (1U << 1), /* bug workaround */
+};
+
+enum sas_cmd_port_registers {
+ CMD_CMRST_OOB_DET = 0x100, /* COMRESET OOB detect register */
+ CMD_CMWK_OOB_DET = 0x104, /* COMWAKE OOB detect register */
+ CMD_CMSAS_OOB_DET = 0x108, /* COMSAS OOB detect register */
+ CMD_BRST_OOB_DET = 0x10c, /* burst OOB detect register */
+ CMD_OOB_SPACE = 0x110, /* OOB space control register */
+ CMD_OOB_BURST = 0x114, /* OOB burst control register */
+ CMD_PHY_TIMER = 0x118, /* PHY timer control register */
+ CMD_PHY_CONFIG0 = 0x11c, /* PHY config register 0 */
+ CMD_PHY_CONFIG1 = 0x120, /* PHY config register 1 */
+ CMD_SAS_CTL0 = 0x124, /* SAS control register 0 */
+ CMD_SAS_CTL1 = 0x128, /* SAS control register 1 */
+ CMD_SAS_CTL2 = 0x12c, /* SAS control register 2 */
+ CMD_SAS_CTL3 = 0x130, /* SAS control register 3 */
+ CMD_ID_TEST = 0x134, /* ID test register */
+ CMD_PL_TIMER = 0x138, /* PL timer register */
+ CMD_WD_TIMER = 0x13c, /* WD timer register */
+ CMD_PORT_SEL_COUNT = 0x140, /* port selector count register */
+ CMD_APP_MEM_CTL = 0x144, /* Application Memory Control */
+ CMD_XOR_MEM_CTL = 0x148, /* XOR Block Memory Control */
+ CMD_DMA_MEM_CTL = 0x14c, /* DMA Block Memory Control */
+ CMD_PORT_MEM_CTL0 = 0x150, /* Port Memory Control 0 */
+ CMD_PORT_MEM_CTL1 = 0x154, /* Port Memory Control 1 */
+ CMD_SATA_PORT_MEM_CTL0 = 0x158, /* SATA Port Memory Control 0 */
+ CMD_SATA_PORT_MEM_CTL1 = 0x15c, /* SATA Port Memory Control 1 */
+ CMD_XOR_MEM_BIST_CTL = 0x160, /* XOR Memory BIST Control */
+ CMD_XOR_MEM_BIST_STAT = 0x164, /* XOR Memroy BIST Status */
+ CMD_DMA_MEM_BIST_CTL = 0x168, /* DMA Memory BIST Control */
+ CMD_DMA_MEM_BIST_STAT = 0x16c, /* DMA Memory BIST Status */
+ CMD_PORT_MEM_BIST_CTL = 0x170, /* Port Memory BIST Control */
+ CMD_PORT_MEM_BIST_STAT0 = 0x174, /* Port Memory BIST Status 0 */
+ CMD_PORT_MEM_BIST_STAT1 = 0x178, /* Port Memory BIST Status 1 */
+ CMD_STP_MEM_BIST_CTL = 0x17c, /* STP Memory BIST Control */
+ CMD_STP_MEM_BIST_STAT0 = 0x180, /* STP Memory BIST Status 0 */
+ CMD_STP_MEM_BIST_STAT1 = 0x184, /* STP Memory BIST Status 1 */
+ CMD_RESET_COUNT = 0x188, /* Reset Count */
+ CMD_MONTR_DATA_SEL = 0x18C, /* Monitor Data/Select */
+ CMD_PLL_PHY_CONFIG = 0x190, /* PLL/PHY Configuration */
+ CMD_PHY_CTL = 0x194, /* PHY Control and Status */
+ CMD_PHY_TEST_COUNT0 = 0x198, /* Phy Test Count 0 */
+ CMD_PHY_TEST_COUNT1 = 0x19C, /* Phy Test Count 1 */
+ CMD_PHY_TEST_COUNT2 = 0x1A0, /* Phy Test Count 2 */
+ CMD_APP_ERR_CONFIG = 0x1A4, /* Application Error Configuration */
+ CMD_PND_FIFO_CTL0 = 0x1A8, /* Pending FIFO Control 0 */
+ CMD_HOST_CTL = 0x1AC, /* Host Control Status */
+ CMD_HOST_WR_DATA = 0x1B0, /* Host Write Data */
+ CMD_HOST_RD_DATA = 0x1B4, /* Host Read Data */
+ CMD_PHY_MODE_21 = 0x1B8, /* Phy Mode 21 */
+ CMD_SL_MODE0 = 0x1BC, /* SL Mode 0 */
+ CMD_SL_MODE1 = 0x1C0, /* SL Mode 1 */
+ CMD_PND_FIFO_CTL1 = 0x1C4, /* Pending FIFO Control 1 */
+};
+
+/* SAS/SATA configuration port registers, aka phy registers */
+enum sas_sata_config_port_regs {
+ PHYR_IDENTIFY = 0x00, /* info for IDENTIFY frame */
+ PHYR_ADDR_LO = 0x04, /* my SAS address (low) */
+ PHYR_ADDR_HI = 0x08, /* my SAS address (high) */
+ PHYR_ATT_DEV_INFO = 0x0C, /* attached device info */
+ PHYR_ATT_ADDR_LO = 0x10, /* attached dev SAS addr (low) */
+ PHYR_ATT_ADDR_HI = 0x14, /* attached dev SAS addr (high) */
+ PHYR_SATA_CTL = 0x18, /* SATA control */
+ PHYR_PHY_STAT = 0x1C, /* PHY status */
+ PHYR_SATA_SIG0 = 0x20, /*port SATA signature FIS(Byte 0-3) */
+ PHYR_SATA_SIG1 = 0x24, /*port SATA signature FIS(Byte 4-7) */
+ PHYR_SATA_SIG2 = 0x28, /*port SATA signature FIS(Byte 8-11) */
+ PHYR_SATA_SIG3 = 0x2c, /*port SATA signature FIS(Byte 12-15) */
+ PHYR_R_ERR_COUNT = 0x30, /* port R_ERR count register */
+ PHYR_CRC_ERR_COUNT = 0x34, /* port CRC error count register */
+ PHYR_WIDE_PORT = 0x38, /* wide port participating */
+ PHYR_CURRENT0 = 0x80, /* current connection info 0 */
+ PHYR_CURRENT1 = 0x84, /* current connection info 1 */
+ PHYR_CURRENT2 = 0x88, /* current connection info 2 */
+};
+
+/* SAS/SATA Vendor Specific Port Registers */
+enum sas_sata_vsp_regs {
+ VSR_PHY_STAT = 0x00, /* Phy Status */
+ VSR_PHY_MODE1 = 0x01, /* phy tx */
+ VSR_PHY_MODE2 = 0x02, /* tx scc */
+ VSR_PHY_MODE3 = 0x03, /* pll */
+ VSR_PHY_MODE4 = 0x04, /* VCO */
+ VSR_PHY_MODE5 = 0x05, /* Rx */
+ VSR_PHY_MODE6 = 0x06, /* CDR */
+ VSR_PHY_MODE7 = 0x07, /* Impedance */
+ VSR_PHY_MODE8 = 0x08, /* Voltage */
+ VSR_PHY_MODE9 = 0x09, /* Test */
+ VSR_PHY_MODE10 = 0x0A, /* Power */
+ VSR_PHY_MODE11 = 0x0B, /* Phy Mode */
+ VSR_PHY_VS0 = 0x0C, /* Vednor Specific 0 */
+ VSR_PHY_VS1 = 0x0D, /* Vednor Specific 1 */
+};
+
+enum pci_cfg_registers {
+ PCR_PHY_CTL = 0x40,
+ PCR_PHY_CTL2 = 0x90,
+ PCR_DEV_CTRL = 0xE8,
+};
+
+enum pci_cfg_register_bits {
+ PCTL_PWR_ON = (0xFU << 24),
+ PCTL_OFF = (0xFU << 12),
+ PRD_REQ_SIZE = (0x4000),
+ PRD_REQ_MASK = (0x00007000),
+};
+
+enum nvram_layout_offsets {
+ NVR_SIG = 0x00, /* 0xAA, 0x55 */
+ NVR_SAS_ADDR = 0x02, /* 8-byte SAS address */
+};
+
+enum chip_flavors {
+ chip_6320,
+ chip_6440,
+ chip_6480,
+};
+
+enum port_type {
+ PORT_TYPE_SAS = (1L << 1),
+ PORT_TYPE_SATA = (1L << 0),
+};
+
+/* Command Table Format */
+enum ct_format {
+ /* SSP */
+ SSP_F_H = 0x00,
+ SSP_F_IU = 0x18,
+ SSP_F_MAX = 0x4D,
+ /* STP */
+ STP_CMD_FIS = 0x00,
+ STP_ATAPI_CMD = 0x40,
+ STP_F_MAX = 0x10,
+ /* SMP */
+ SMP_F_T = 0x00,
+ SMP_F_DEP = 0x01,
+ SMP_F_MAX = 0x101,
+};
+
+enum status_buffer {
+ SB_EIR_OFF = 0x00, /* Error Information Record */
+ SB_RFB_OFF = 0x08, /* Response Frame Buffer */
+ SB_RFB_MAX = 0x400, /* RFB size*/
+};
+
+enum error_info_rec {
+ CMD_ISS_STPD = (1U << 31), /* Cmd Issue Stopped */
+};
+
+struct mvs_chip_info {
+ u32 n_phy;
+ u32 srs_sz;
+ u32 slot_width;
+};
+
+struct mvs_err_info {
+ __le32 flags;
+ __le32 flags2;
+};
+
+struct mvs_prd {
+ __le64 addr; /* 64-bit buffer address */
+ __le32 reserved;
+ __le32 len; /* 16-bit length */
+};
+
+struct mvs_cmd_hdr {
+ __le32 flags; /* PRD tbl len; SAS, SATA ctl */
+ __le32 lens; /* cmd, max resp frame len */
+ __le32 tags; /* targ port xfer tag; tag */
+ __le32 data_len; /* data xfer len */
+ __le64 cmd_tbl; /* command table address */
+ __le64 open_frame; /* open addr frame address */
+ __le64 status_buf; /* status buffer address */
+ __le64 prd_tbl; /* PRD tbl address */
+ __le32 reserved[4];
+};
+
+struct mvs_slot_info {
+ struct sas_task *task;
+ u32 n_elem;
+ u32 tx;
+
+ /* DMA buffer for storing cmd tbl, open addr frame, status buffer,
+ * and PRD table
+ */
+ void *buf;
+ dma_addr_t buf_dma;
+#if _MV_DUMP
+ u32 cmd_size;
+#endif
+
+ void *response;
+};
+
+struct mvs_port {
+ struct asd_sas_port sas_port;
+ u8 port_attached;
+ u8 taskfileset;
+ u8 wide_port_phymap;
+};
+
+struct mvs_phy {
+ struct mvs_port *port;
+ struct asd_sas_phy sas_phy;
+ struct sas_identify identify;
+ struct scsi_device *sdev;
+ u64 dev_sas_addr;
+ u64 att_dev_sas_addr;
+ u32 att_dev_info;
+ u32 dev_info;
+ u32 phy_type;
+ u32 phy_status;
+ u32 irq_status;
+ u32 frame_rcvd_size;
+ u8 frame_rcvd[32];
+ u8 phy_attached;
+};
+
+struct mvs_info {
+ unsigned long flags;
+
+ spinlock_t lock; /* host-wide lock */
+ struct pci_dev *pdev; /* our device */
+ void __iomem *regs; /* enhanced mode registers */
+ void __iomem *peri_regs; /* peripheral registers */
+
+ u8 sas_addr[SAS_ADDR_SIZE];
+ struct sas_ha_struct sas; /* SCSI/SAS glue */
+ struct Scsi_Host *shost;
+
+ __le32 *tx; /* TX (delivery) DMA ring */
+ dma_addr_t tx_dma;
+ u32 tx_prod; /* cached next-producer idx */
+
+ __le32 *rx; /* RX (completion) DMA ring */
+ dma_addr_t rx_dma;
+ u32 rx_cons; /* RX consumer idx */
+
+ __le32 *rx_fis; /* RX'd FIS area */
+ dma_addr_t rx_fis_dma;
+
+ struct mvs_cmd_hdr *slot; /* DMA command header slots */
+ dma_addr_t slot_dma;
+
+ const struct mvs_chip_info *chip;
+
+ unsigned long tags[MVS_SLOTS];
+ struct mvs_slot_info slot_info[MVS_SLOTS];
+ /* further per-slot information */
+ struct mvs_phy phy[MVS_MAX_PHYS];
+ struct mvs_port port[MVS_MAX_PHYS];
+
+ u32 can_queue; /* per adapter */
+ u32 tag_out; /*Get*/
+ u32 tag_in; /*Give*/
+};
+
+struct mvs_queue_task {
+ struct list_head list;
+
+ void *uldd_task;
+};
+
+static int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
+ void *funcdata);
+static u32 mvs_read_phy_ctl(struct mvs_info *mvi, u32 port);
+static void mvs_write_phy_ctl(struct mvs_info *mvi, u32 port, u32 val);
+static u32 mvs_read_port_irq_stat(struct mvs_info *mvi, u32 port);
+static void mvs_write_port_irq_stat(struct mvs_info *mvi, u32 port, u32 val);
+static void mvs_write_port_irq_mask(struct mvs_info *mvi, u32 port, u32 val);
+static u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port);
+
+static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i);
+static void mvs_detect_porttype(struct mvs_info *mvi, int i);
+static void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st);
+
+static int mvs_scan_finished(struct Scsi_Host *, unsigned long);
+static void mvs_scan_start(struct Scsi_Host *);
+static int mvs_sas_slave_alloc(struct scsi_device *scsi_dev);
+
+static struct scsi_transport_template *mvs_stt;
+
+static const struct mvs_chip_info mvs_chips[] = {
+ [chip_6320] = { 2, 16, 9 },
+ [chip_6440] = { 4, 16, 9 },
+ [chip_6480] = { 8, 32, 10 },
+};
+
+static struct scsi_host_template mvs_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .queuecommand = sas_queuecommand,
+ .target_alloc = sas_target_alloc,
+ .slave_configure = sas_slave_configure,
+ .slave_destroy = sas_slave_destroy,
+ .scan_finished = mvs_scan_finished,
+ .scan_start = mvs_scan_start,
+ .change_queue_depth = sas_change_queue_depth,
+ .change_queue_type = sas_change_queue_type,
+ .bios_param = sas_bios_param,
+ .can_queue = 1,
+ .cmd_per_lun = 1,
+ .this_id = -1,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+ .use_clustering = ENABLE_CLUSTERING,
+ .eh_device_reset_handler = sas_eh_device_reset_handler,
+ .eh_bus_reset_handler = sas_eh_bus_reset_handler,
+ .slave_alloc = mvs_sas_slave_alloc,
+ .target_destroy = sas_target_destroy,
+ .ioctl = sas_ioctl,
+};
+
+static void mvs_hexdump(u32 size, u8 *data, u32 baseaddr)
+{
+ u32 i;
+ u32 run;
+ u32 offset;
+
+ offset = 0;
+ while (size) {
+ printk("%08X : ", baseaddr + offset);
+ if (size >= 16)
+ run = 16;
+ else
+ run = size;
+ size -= run;
+ for (i = 0; i < 16; i++) {
+ if (i < run)
+ printk("%02X ", (u32)data[i]);
+ else
+ printk(" ");
+ }
+ printk(": ");
+ for (i = 0; i < run; i++)
+ printk("%c", isalnum(data[i]) ? data[i] : '.');
+ printk("\n");
+ data = &data[16];
+ offset += run;
+ }
+ printk("\n");
+}
+
+static void mvs_hba_sb_dump(struct mvs_info *mvi, u32 tag,
+ enum sas_protocol proto)
+{
+#if _MV_DUMP
+ u32 offset;
+ struct pci_dev *pdev = mvi->pdev;
+ struct mvs_slot_info *slot = &mvi->slot_info[tag];
+
+ offset = slot->cmd_size + MVS_OAF_SZ +
+ sizeof(struct mvs_prd) * slot->n_elem;
+ dev_printk(KERN_DEBUG, &pdev->dev, "+---->Status buffer[%d] :\n",
+ tag);
+ mvs_hexdump(32, (u8 *) slot->response,
+ (u32) slot->buf_dma + offset);
+#endif
+}
+
+static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag,
+ enum sas_protocol proto)
+{
+#if _MV_DUMP
+ u32 sz, w_ptr, r_ptr;
+ u64 addr;
+ void __iomem *regs = mvi->regs;
+ struct pci_dev *pdev = mvi->pdev;
+ struct mvs_slot_info *slot = &mvi->slot_info[tag];
+
+ /*Delivery Queue */
+ sz = mr32(TX_CFG) & TX_RING_SZ_MASK;
+ w_ptr = mr32(TX_PROD_IDX) & TX_RING_SZ_MASK;
+ r_ptr = mr32(TX_CONS_IDX) & TX_RING_SZ_MASK;
+ addr = mr32(TX_HI) << 16 << 16 | mr32(TX_LO);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "Delivery Queue Size=%04d , WRT_PTR=%04X , RD_PTR=%04X\n",
+ sz, w_ptr, r_ptr);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "Delivery Queue Base Address=0x%llX (PA)"
+ "(tx_dma=0x%llX), Entry=%04d\n",
+ addr, mvi->tx_dma, w_ptr);
+ mvs_hexdump(sizeof(u32), (u8 *)(&mvi->tx[mvi->tx_prod]),
+ (u32) mvi->tx_dma + sizeof(u32) * w_ptr);
+ /*Command List */
+ addr = mr32(CMD_LIST_HI) << 16 << 16 | mr32(CMD_LIST_LO);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "Command List Base Address=0x%llX (PA)"
+ "(slot_dma=0x%llX), Header=%03d\n",
+ addr, mvi->slot_dma, tag);
+ dev_printk(KERN_DEBUG, &pdev->dev, "Command Header[%03d]:\n", tag);
+ /*mvs_cmd_hdr */
+ mvs_hexdump(sizeof(struct mvs_cmd_hdr), (u8 *)(&mvi->slot[tag]),
+ (u32) mvi->slot_dma + tag * sizeof(struct mvs_cmd_hdr));
+ /*1.command table area */
+ dev_printk(KERN_DEBUG, &pdev->dev, "+---->Command Table :\n");
+ mvs_hexdump(slot->cmd_size, (u8 *) slot->buf, (u32) slot->buf_dma);
+ /*2.open address frame area */
+ dev_printk(KERN_DEBUG, &pdev->dev, "+---->Open Address Frame :\n");
+ mvs_hexdump(MVS_OAF_SZ, (u8 *) slot->buf + slot->cmd_size,
+ (u32) slot->buf_dma + slot->cmd_size);
+ /*3.status buffer */
+ mvs_hba_sb_dump(mvi, tag, proto);
+ /*4.PRD table */
+ dev_printk(KERN_DEBUG, &pdev->dev, "+---->PRD table :\n");
+ mvs_hexdump(sizeof(struct mvs_prd) * slot->n_elem,
+ (u8 *) slot->buf + slot->cmd_size + MVS_OAF_SZ,
+ (u32) slot->buf_dma + slot->cmd_size + MVS_OAF_SZ);
+#endif
+}
+
+static void mvs_hba_cq_dump(struct mvs_info *mvi)
+{
+#if _MV_DUMP
+ u64 addr;
+ void __iomem *regs = mvi->regs;
+ struct pci_dev *pdev = mvi->pdev;
+ u32 entry = mvi->rx_cons + 1;
+ u32 rx_desc = le32_to_cpu(mvi->rx[entry]);
+
+ /*Completion Queue */
+ addr = mr32(RX_HI) << 16 << 16 | mr32(RX_LO);
+ dev_printk(KERN_DEBUG, &pdev->dev, "Completion Task = 0x%08X\n",
+ (u32) mvi->slot_info[rx_desc & RXQ_SLOT_MASK].task);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "Completion List Base Address=0x%llX (PA), "
+ "CQ_Entry=%04d, CQ_WP=0x%08X\n",
+ addr, entry - 1, mvi->rx[0]);
+ mvs_hexdump(sizeof(u32), (u8 *)(&rx_desc),
+ mvi->rx_dma + sizeof(u32) * entry);
+#endif
+}
+
+static void mvs_hba_interrupt_enable(struct mvs_info *mvi)
+{
+ void __iomem *regs = mvi->regs;
+ u32 tmp;
+
+ tmp = mr32(GBL_CTL);
+
+ mw32(GBL_CTL, tmp | INT_EN);
+}
+
+static void mvs_hba_interrupt_disable(struct mvs_info *mvi)
+{
+ void __iomem *regs = mvi->regs;
+ u32 tmp;
+
+ tmp = mr32(GBL_CTL);
+
+ mw32(GBL_CTL, tmp & ~INT_EN);
+}
+
+static int mvs_int_rx(struct mvs_info *mvi, bool self_clear);
+
+/* move to PCI layer or libata core? */
+static int pci_go_64(struct pci_dev *pdev)
+{
+ int rc;
+
+ if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (rc) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "64-bit DMA enable failed\n");
+ return rc;
+ }
+ }
+ } else {
+ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
+ return rc;
+ }
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
+static void mvs_tag_clear(struct mvs_info *mvi, u32 tag)
+{
+ mvi->tag_in = (mvi->tag_in + 1) & (MVS_SLOTS - 1);
+ mvi->tags[mvi->tag_in] = tag;
+}
+
+static void mvs_tag_free(struct mvs_info *mvi, u32 tag)
+{
+ mvi->tag_out = (mvi->tag_out - 1) & (MVS_SLOTS - 1);
+}
+
+static int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out)
+{
+ if (mvi->tag_out != mvi->tag_in) {
+ *tag_out = mvi->tags[mvi->tag_out];
+ mvi->tag_out = (mvi->tag_out + 1) & (MVS_SLOTS - 1);
+ return 0;
+ }
+ return -EBUSY;
+}
+
+static void mvs_tag_init(struct mvs_info *mvi)
+{
+ int i;
+ for (i = 0; i < MVS_SLOTS; ++i)
+ mvi->tags[i] = i;
+ mvi->tag_out = 0;
+ mvi->tag_in = MVS_SLOTS - 1;
+}
+
+#ifndef MVS_DISABLE_NVRAM
+static int mvs_eep_read(void __iomem *regs, u32 addr, u32 *data)
+{
+ int timeout = 1000;
+
+ if (addr & ~SPI_ADDR_MASK)
+ return -EINVAL;
+
+ writel(addr, regs + SPI_CMD);
+ writel(TWSI_RD, regs + SPI_CTL);
+
+ while (timeout-- > 0) {
+ if (readl(regs + SPI_CTL) & TWSI_RDY) {
+ *data = readl(regs + SPI_DATA);
+ return 0;
+ }
+
+ udelay(10);
+ }
+
+ return -EBUSY;
+}
+
+static int mvs_eep_read_buf(void __iomem *regs, u32 addr,
+ void *buf, u32 buflen)
+{
+ u32 addr_end, tmp_addr, i, j;
+ u32 tmp = 0;
+ int rc;
+ u8 *tmp8, *buf8 = buf;
+
+ addr_end = addr + buflen;
+ tmp_addr = ALIGN(addr, 4);
+ if (addr > 0xff)
+ return -EINVAL;
+
+ j = addr & 0x3;
+ if (j) {
+ rc = mvs_eep_read(regs, tmp_addr, &tmp);
+ if (rc)
+ return rc;
+
+ tmp8 = (u8 *)&tmp;
+ for (i = j; i < 4; i++)
+ *buf8++ = tmp8[i];
+
+ tmp_addr += 4;
+ }
+
+ for (j = ALIGN(addr_end, 4); tmp_addr < j; tmp_addr += 4) {
+ rc = mvs_eep_read(regs, tmp_addr, &tmp);
+ if (rc)
+ return rc;
+
+ memcpy(buf8, &tmp, 4);
+ buf8 += 4;
+ }
+
+ if (tmp_addr < addr_end) {
+ rc = mvs_eep_read(regs, tmp_addr, &tmp);
+ if (rc)
+ return rc;
+
+ tmp8 = (u8 *)&tmp;
+ j = addr_end - tmp_addr;
+ for (i = 0; i < j; i++)
+ *buf8++ = tmp8[i];
+
+ tmp_addr += 4;
+ }
+
+ return 0;
+}
+#endif
+
+static int mvs_nvram_read(struct mvs_info *mvi, u32 addr,
+ void *buf, u32 buflen)
+{
+#ifndef MVS_DISABLE_NVRAM
+ void __iomem *regs = mvi->regs;
+ int rc, i;
+ u32 sum;
+ u8 hdr[2], *tmp;
+ const char *msg;
+
+ rc = mvs_eep_read_buf(regs, addr, &hdr, 2);
+ if (rc) {
+ msg = "nvram hdr read failed";
+ goto err_out;
+ }
+ rc = mvs_eep_read_buf(regs, addr + 2, buf, buflen);
+ if (rc) {
+ msg = "nvram read failed";
+ goto err_out;
+ }
+
+ if (hdr[0] != 0x5A) {
+ /* entry id */
+ msg = "invalid nvram entry id";
+ rc = -ENOENT;
+ goto err_out;
+ }
+
+ tmp = buf;
+ sum = ((u32)hdr[0]) + ((u32)hdr[1]);
+ for (i = 0; i < buflen; i++)
+ sum += ((u32)tmp[i]);
+
+ if (sum) {
+ msg = "nvram checksum failure";
+ rc = -EILSEQ;
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ dev_printk(KERN_ERR, &mvi->pdev->dev, "%s", msg);
+ return rc;
+#else
+ /* FIXME , For SAS target mode */
+ memcpy(buf, "\x50\x05\x04\x30\x11\xab\x00\x00", 8);
+ return 0;
+#endif
+}
+
+static void mvs_bytes_dmaed(struct mvs_info *mvi, int i)
+{
+ struct mvs_phy *phy = &mvi->phy[i];
+
+ if (!phy->phy_attached)
+ return;
+
+ if (phy->phy_type & PORT_TYPE_SAS) {
+ struct sas_identify_frame *id;
+
+ id = (struct sas_identify_frame *)phy->frame_rcvd;
+ id->dev_type = phy->identify.device_type;
+ id->initiator_bits = SAS_PROTOCOL_ALL;
+ id->target_bits = phy->identify.target_port_protocols;
+ } else if (phy->phy_type & PORT_TYPE_SATA) {
+ /* TODO */
+ }
+ mvi->sas.sas_phy[i]->frame_rcvd_size = phy->frame_rcvd_size;
+ mvi->sas.notify_port_event(mvi->sas.sas_phy[i],
+ PORTE_BYTES_DMAED);
+}
+
+static int mvs_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+ /* give the phy enabling interrupt event time to come in (1s
+ * is empirically about all it takes) */
+ if (time < HZ)
+ return 0;
+ /* Wait for discovery to finish */
+ scsi_flush_work(shost);
+ return 1;
+}
+
+static void mvs_scan_start(struct Scsi_Host *shost)
+{
+ int i;
+ struct mvs_info *mvi = SHOST_TO_SAS_HA(shost)->lldd_ha;
+
+ for (i = 0; i < mvi->chip->n_phy; ++i) {
+ mvs_bytes_dmaed(mvi, i);
+ }
+}
+
+static int mvs_sas_slave_alloc(struct scsi_device *scsi_dev)
+{
+ int rc;
+
+ rc = sas_slave_alloc(scsi_dev);
+
+ return rc;
+}
+
+static void mvs_int_port(struct mvs_info *mvi, int port_no, u32 events)
+{
+ struct pci_dev *pdev = mvi->pdev;
+ struct sas_ha_struct *sas_ha = &mvi->sas;
+ struct mvs_phy *phy = &mvi->phy[port_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+
+ phy->irq_status = mvs_read_port_irq_stat(mvi, port_no);
+ /*
+ * events is port event now ,
+ * we need check the interrupt status which belongs to per port.
+ */
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "Port %d Event = %X\n",
+ port_no, phy->irq_status);
+
+ if (phy->irq_status & (PHYEV_POOF | PHYEV_DEC_ERR)) {
+ if (!mvs_is_phy_ready(mvi, port_no)) {
+ sas_phy_disconnected(sas_phy);
+ sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL);
+ } else
+ mvs_phy_control(sas_phy, PHY_FUNC_LINK_RESET, NULL);
+ }
+ if (!(phy->irq_status & PHYEV_DEC_ERR)) {
+ if (phy->irq_status & PHYEV_COMWAKE) {
+ u32 tmp = mvs_read_port_irq_mask(mvi, port_no);
+ mvs_write_port_irq_mask(mvi, port_no,
+ tmp | PHYEV_SIG_FIS);
+ }
+ if (phy->irq_status & (PHYEV_SIG_FIS | PHYEV_ID_DONE)) {
+ phy->phy_status = mvs_is_phy_ready(mvi, port_no);
+ if (phy->phy_status) {
+ mvs_detect_porttype(mvi, port_no);
+
+ if (phy->phy_type & PORT_TYPE_SATA) {
+ u32 tmp = mvs_read_port_irq_mask(mvi,
+ port_no);
+ tmp &= ~PHYEV_SIG_FIS;
+ mvs_write_port_irq_mask(mvi,
+ port_no, tmp);
+ }
+
+ mvs_update_phyinfo(mvi, port_no, 0);
+ sas_ha->notify_phy_event(sas_phy,
+ PHYE_OOB_DONE);
+ mvs_bytes_dmaed(mvi, port_no);
+ } else {
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "plugin interrupt but phy is gone\n");
+ mvs_phy_control(sas_phy, PHY_FUNC_LINK_RESET,
+ NULL);
+ }
+ } else if (phy->irq_status & PHYEV_BROAD_CH)
+ sas_ha->notify_port_event(sas_phy,
+ PORTE_BROADCAST_RCVD);
+ }
+ mvs_write_port_irq_stat(mvi, port_no, phy->irq_status);
+}
+
+static void mvs_int_sata(struct mvs_info *mvi)
+{
+ /* FIXME */
+}
+
+static void mvs_slot_free(struct mvs_info *mvi, struct sas_task *task,
+ struct mvs_slot_info *slot, u32 slot_idx)
+{
+ if (!sas_protocol_ata(task->task_proto))
+ if (slot->n_elem)
+ pci_unmap_sg(mvi->pdev, task->scatter,
+ slot->n_elem, task->data_dir);
+
+ switch (task->task_proto) {
+ case SAS_PROTOCOL_SMP:
+ pci_unmap_sg(mvi->pdev, &task->smp_task.smp_resp, 1,
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_sg(mvi->pdev, &task->smp_task.smp_req, 1,
+ PCI_DMA_TODEVICE);
+ break;
+
+ case SAS_PROTOCOL_SATA:
+ case SAS_PROTOCOL_STP:
+ case SAS_PROTOCOL_SSP:
+ default:
+ /* do nothing */
+ break;
+ }
+
+ slot->task = NULL;
+ mvs_tag_clear(mvi, slot_idx);
+}
+
+static void mvs_slot_err(struct mvs_info *mvi, struct sas_task *task,
+ u32 slot_idx)
+{
+ struct mvs_slot_info *slot = &mvi->slot_info[slot_idx];
+ u64 err_dw0 = *(u32 *) slot->response;
+ void __iomem *regs = mvi->regs;
+ u32 tmp;
+
+ if (err_dw0 & CMD_ISS_STPD)
+ if (sas_protocol_ata(task->task_proto)) {
+ tmp = mr32(INT_STAT_SRS);
+ mw32(INT_STAT_SRS, tmp & 0xFFFF);
+ }
+
+ mvs_hba_sb_dump(mvi, slot_idx, task->task_proto);
+}
+
+static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc)
+{
+ u32 slot_idx = rx_desc & RXQ_SLOT_MASK;
+ struct mvs_slot_info *slot = &mvi->slot_info[slot_idx];
+ struct sas_task *task = slot->task;
+ struct task_status_struct *tstat = &task->task_status;
+ struct mvs_port *port = &mvi->port[task->dev->port->id];
+ bool aborted;
+ void *to;
+
+ spin_lock(&task->task_state_lock);
+ aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED;
+ if (!aborted) {
+ task->task_state_flags &=
+ ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR);
+ task->task_state_flags |= SAS_TASK_STATE_DONE;
+ }
+ spin_unlock(&task->task_state_lock);
+
+ if (aborted)
+ return -1;
+
+ memset(tstat, 0, sizeof(*tstat));
+ tstat->resp = SAS_TASK_COMPLETE;
+
+
+ if (unlikely(!port->port_attached)) {
+ tstat->stat = SAS_PHY_DOWN;
+ goto out;
+ }
+
+ /* error info record present */
+ if ((rx_desc & RXQ_ERR) && (*(u64 *) slot->response)) {
+ tstat->stat = SAM_CHECK_COND;
+ mvs_slot_err(mvi, task, slot_idx);
+ goto out;
+ }
+
+ switch (task->task_proto) {
+ case SAS_PROTOCOL_SSP:
+ /* hw says status == 0, datapres == 0 */
+ if (rx_desc & RXQ_GOOD) {
+ tstat->stat = SAM_GOOD;
+ tstat->resp = SAS_TASK_COMPLETE;
+ }
+ /* response frame present */
+ else if (rx_desc & RXQ_RSP) {
+ struct ssp_response_iu *iu =
+ slot->response + sizeof(struct mvs_err_info);
+ sas_ssp_task_response(&mvi->pdev->dev, task, iu);
+ }
+
+ /* should never happen? */
+ else
+ tstat->stat = SAM_CHECK_COND;
+ break;
+
+ case SAS_PROTOCOL_SMP: {
+ struct scatterlist *sg_resp = &task->smp_task.smp_resp;
+ tstat->stat = SAM_GOOD;
+ to = kmap_atomic(sg_page(sg_resp), KM_IRQ0);
+ memcpy(to + sg_resp->offset,
+ slot->response + sizeof(struct mvs_err_info),
+ sg_dma_len(sg_resp));
+ kunmap_atomic(to, KM_IRQ0);
+ break;
+ }
+
+ case SAS_PROTOCOL_SATA:
+ case SAS_PROTOCOL_STP:
+ case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: {
+ struct ata_task_resp *resp =
+ (struct ata_task_resp *)tstat->buf;
+
+ if ((rx_desc & (RXQ_DONE | RXQ_ERR | RXQ_ATTN)) ==
+ RXQ_DONE)
+ tstat->stat = SAM_GOOD;
+ else
+ tstat->stat = SAM_CHECK_COND;
+
+ resp->frame_len = sizeof(struct dev_to_host_fis);
+ memcpy(&resp->ending_fis[0],
+ SATA_RECEIVED_D2H_FIS(port->taskfileset),
+ sizeof(struct dev_to_host_fis));
+ if (resp->ending_fis[2] & ATA_ERR)
+ mvs_hexdump(16, resp->ending_fis, 0);
+ break;
+ }
+
+ default:
+ tstat->stat = SAM_CHECK_COND;
+ break;
+ }
+
+out:
+ mvs_slot_free(mvi, task, slot, slot_idx);
+ task->task_done(task);
+ return tstat->stat;
+}
+
+static void mvs_int_full(struct mvs_info *mvi)
+{
+ void __iomem *regs = mvi->regs;
+ u32 tmp, stat;
+ int i;
+
+ stat = mr32(INT_STAT);
+
+ mvs_int_rx(mvi, false);
+
+ for (i = 0; i < MVS_MAX_PORTS; i++) {
+ tmp = (stat >> i) & (CINT_PORT | CINT_PORT_STOPPED);
+ if (tmp)
+ mvs_int_port(mvi, i, tmp);
+ }
+
+ if (stat & CINT_SRS)
+ mvs_int_sata(mvi);
+
+ mw32(INT_STAT, stat);
+}
+
+static int mvs_int_rx(struct mvs_info *mvi, bool self_clear)
+{
+ void __iomem *regs = mvi->regs;
+ u32 rx_prod_idx, rx_desc;
+ bool attn = false;
+ struct pci_dev *pdev = mvi->pdev;
+
+ /* the first dword in the RX ring is special: it contains
+ * a mirror of the hardware's RX producer index, so that
+ * we don't have to stall the CPU reading that register.
+ * The actual RX ring is offset by one dword, due to this.
+ */
+ rx_prod_idx = mr32(RX_CONS_IDX) & RX_RING_SZ_MASK;
+ if (rx_prod_idx == 0xfff) { /* h/w hasn't touched RX ring yet */
+ mvi->rx_cons = 0xfff;
+ return 0;
+ }
+
+ /* The CMPL_Q may come late, read from register and try again
+ * note: if coalescing is enabled,
+ * it will need to read from register every time for sure
+ */
+ if (mvi->rx_cons == rx_prod_idx)
+ return 0;
+
+ if (mvi->rx_cons == 0xfff)
+ mvi->rx_cons = MVS_RX_RING_SZ - 1;
+
+ while (mvi->rx_cons != rx_prod_idx) {
+
+ /* increment our internal RX consumer pointer */
+ mvi->rx_cons = (mvi->rx_cons + 1) & (MVS_RX_RING_SZ - 1);
+
+ rx_desc = le32_to_cpu(mvi->rx[mvi->rx_cons + 1]);
+
+ mvs_hba_cq_dump(mvi);
+
+ if (likely(rx_desc & RXQ_DONE))
+ mvs_slot_complete(mvi, rx_desc);
+ if (rx_desc & RXQ_ATTN) {
+ attn = true;
+ dev_printk(KERN_DEBUG, &pdev->dev, "ATTN %X\n",
+ rx_desc);
+ } else if (rx_desc & RXQ_ERR) {
+ dev_printk(KERN_DEBUG, &pdev->dev, "RXQ_ERR %X\n",
+ rx_desc);
+ }
+ }
+
+ if (attn && self_clear)
+ mvs_int_full(mvi);
+
+ return 0;
+}
+
+static irqreturn_t mvs_interrupt(int irq, void *opaque)
+{
+ struct mvs_info *mvi = opaque;
+ void __iomem *regs = mvi->regs;
+ u32 stat;
+
+ stat = mr32(GBL_INT_STAT);
+
+ /* clear CMD_CMPLT ASAP */
+ mw32_f(INT_STAT, CINT_DONE);
+
+ if (stat == 0 || stat == 0xffffffff)
+ return IRQ_NONE;
+
+ spin_lock(&mvi->lock);
+
+ mvs_int_full(mvi);
+
+ spin_unlock(&mvi->lock);
+
+ return IRQ_HANDLED;
+}
+
+#ifndef MVS_DISABLE_MSI
+static irqreturn_t mvs_msi_interrupt(int irq, void *opaque)
+{
+ struct mvs_info *mvi = opaque;
+
+ spin_lock(&mvi->lock);
+
+ mvs_int_rx(mvi, true);
+
+ spin_unlock(&mvi->lock);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+struct mvs_task_exec_info {
+ struct sas_task *task;
+ struct mvs_cmd_hdr *hdr;
+ struct mvs_port *port;
+ u32 tag;
+ int n_elem;
+};
+
+static int mvs_task_prep_smp(struct mvs_info *mvi,
+ struct mvs_task_exec_info *tei)
+{
+ int elem, rc, i;
+ struct sas_task *task = tei->task;
+ struct mvs_cmd_hdr *hdr = tei->hdr;
+ struct scatterlist *sg_req, *sg_resp;
+ u32 req_len, resp_len, tag = tei->tag;
+ void *buf_tmp;
+ u8 *buf_oaf;
+ dma_addr_t buf_tmp_dma;
+ struct mvs_prd *buf_prd;
+ struct scatterlist *sg;
+ struct mvs_slot_info *slot = &mvi->slot_info[tag];
+ struct asd_sas_port *sas_port = task->dev->port;
+ u32 flags = (tei->n_elem << MCH_PRD_LEN_SHIFT);
+#if _MV_DUMP
+ u8 *buf_cmd;
+ void *from;
+#endif
+ /*
+ * DMA-map SMP request, response buffers
+ */
+ sg_req = &task->smp_task.smp_req;
+ elem = pci_map_sg(mvi->pdev, sg_req, 1, PCI_DMA_TODEVICE);
+ if (!elem)
+ return -ENOMEM;
+ req_len = sg_dma_len(sg_req);
+
+ sg_resp = &task->smp_task.smp_resp;
+ elem = pci_map_sg(mvi->pdev, sg_resp, 1, PCI_DMA_FROMDEVICE);
+ if (!elem) {
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ resp_len = sg_dma_len(sg_resp);
+
+ /* must be in dwords */
+ if ((req_len & 0x3) || (resp_len & 0x3)) {
+ rc = -EINVAL;
+ goto err_out_2;
+ }
+
+ /*
+ * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs
+ */
+
+ /* region 1: command table area (MVS_SSP_CMD_SZ bytes) ************** */
+ buf_tmp = slot->buf;
+ buf_tmp_dma = slot->buf_dma;
+
+#if _MV_DUMP
+ buf_cmd = buf_tmp;
+ hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma);
+ buf_tmp += req_len;
+ buf_tmp_dma += req_len;
+ slot->cmd_size = req_len;
+#else
+ hdr->cmd_tbl = cpu_to_le64(sg_dma_address(sg_req));
+#endif
+
+ /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */
+ buf_oaf = buf_tmp;
+ hdr->open_frame = cpu_to_le64(buf_tmp_dma);
+
+ buf_tmp += MVS_OAF_SZ;
+ buf_tmp_dma += MVS_OAF_SZ;
+
+ /* region 3: PRD table ********************************************* */
+ buf_prd = buf_tmp;
+ if (tei->n_elem)
+ hdr->prd_tbl = cpu_to_le64(buf_tmp_dma);
+ else
+ hdr->prd_tbl = 0;
+
+ i = sizeof(struct mvs_prd) * tei->n_elem;
+ buf_tmp += i;
+ buf_tmp_dma += i;
+
+ /* region 4: status buffer (larger the PRD, smaller this buf) ****** */
+ slot->response = buf_tmp;
+ hdr->status_buf = cpu_to_le64(buf_tmp_dma);
+
+ /*
+ * Fill in TX ring and command slot header
+ */
+ slot->tx = mvi->tx_prod;
+ mvi->tx[mvi->tx_prod] = cpu_to_le32((TXQ_CMD_SMP << TXQ_CMD_SHIFT) |
+ TXQ_MODE_I | tag |
+ (sas_port->phy_mask << TXQ_PHY_SHIFT));
+
+ hdr->flags |= flags;
+ hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | ((req_len - 4) / 4));
+ hdr->tags = cpu_to_le32(tag);
+ hdr->data_len = 0;
+
+ /* generate open address frame hdr (first 12 bytes) */
+ buf_oaf[0] = (1 << 7) | (0 << 4) | 0x01; /* initiator, SMP, ftype 1h */
+ buf_oaf[1] = task->dev->linkrate & 0xf;
+ *(u16 *)(buf_oaf + 2) = 0xFFFF; /* SAS SPEC */
+ memcpy(buf_oaf + 4, task->dev->sas_addr, SAS_ADDR_SIZE);
+
+ /* fill in PRD (scatter/gather) table, if any */
+ for_each_sg(task->scatter, sg, tei->n_elem, i) {
+ buf_prd->addr = cpu_to_le64(sg_dma_address(sg));
+ buf_prd->len = cpu_to_le32(sg_dma_len(sg));
+ buf_prd++;
+ }
+
+#if _MV_DUMP
+ /* copy cmd table */
+ from = kmap_atomic(sg_page(sg_req), KM_IRQ0);
+ memcpy(buf_cmd, from + sg_req->offset, req_len);
+ kunmap_atomic(from, KM_IRQ0);
+#endif
+ return 0;
+
+err_out_2:
+ pci_unmap_sg(mvi->pdev, &tei->task->smp_task.smp_resp, 1,
+ PCI_DMA_FROMDEVICE);
+err_out:
+ pci_unmap_sg(mvi->pdev, &tei->task->smp_task.smp_req, 1,
+ PCI_DMA_TODEVICE);
+ return rc;
+}
+
+static void mvs_free_reg_set(struct mvs_info *mvi, struct mvs_port *port)
+{
+ void __iomem *regs = mvi->regs;
+ u32 tmp, offs;
+ u8 *tfs = &port->taskfileset;
+
+ if (*tfs == MVS_ID_NOT_MAPPED)
+ return;
+
+ offs = 1U << ((*tfs & 0x0f) + PCS_EN_SATA_REG_SHIFT);
+ if (*tfs < 16) {
+ tmp = mr32(PCS);
+ mw32(PCS, tmp & ~offs);
+ } else {
+ tmp = mr32(CTL);
+ mw32(CTL, tmp & ~offs);
+ }
+
+ tmp = mr32(INT_STAT_SRS) & (1U << *tfs);
+ if (tmp)
+ mw32(INT_STAT_SRS, tmp);
+
+ *tfs = MVS_ID_NOT_MAPPED;
+}
+
+static u8 mvs_assign_reg_set(struct mvs_info *mvi, struct mvs_port *port)
+{
+ int i;
+ u32 tmp, offs;
+ void __iomem *regs = mvi->regs;
+
+ if (port->taskfileset != MVS_ID_NOT_MAPPED)
+ return 0;
+
+ tmp = mr32(PCS);
+
+ for (i = 0; i < mvi->chip->srs_sz; i++) {
+ if (i == 16)
+ tmp = mr32(CTL);
+ offs = 1U << ((i & 0x0f) + PCS_EN_SATA_REG_SHIFT);
+ if (!(tmp & offs)) {
+ port->taskfileset = i;
+
+ if (i < 16)
+ mw32(PCS, tmp | offs);
+ else
+ mw32(CTL, tmp | offs);
+ tmp = mr32(INT_STAT_SRS) & (1U << i);
+ if (tmp)
+ mw32(INT_STAT_SRS, tmp);
+ return 0;
+ }
+ }
+ return MVS_ID_NOT_MAPPED;
+}
+
+static u32 mvs_get_ncq_tag(struct sas_task *task)
+{
+ u32 tag = 0;
+ struct ata_queued_cmd *qc = task->uldd_task;
+
+ if (qc)
+ tag = qc->tag;
+
+ return tag;
+}
+
+static int mvs_task_prep_ata(struct mvs_info *mvi,
+ struct mvs_task_exec_info *tei)
+{
+ struct sas_task *task = tei->task;
+ struct domain_device *dev = task->dev;
+ struct mvs_cmd_hdr *hdr = tei->hdr;
+ struct asd_sas_port *sas_port = dev->port;
+ struct mvs_slot_info *slot;
+ struct scatterlist *sg;
+ struct mvs_prd *buf_prd;
+ struct mvs_port *port = tei->port;
+ u32 tag = tei->tag;
+ u32 flags = (tei->n_elem << MCH_PRD_LEN_SHIFT);
+ void *buf_tmp;
+ u8 *buf_cmd, *buf_oaf;
+ dma_addr_t buf_tmp_dma;
+ u32 i, req_len, resp_len;
+ const u32 max_resp_len = SB_RFB_MAX;
+
+ if (mvs_assign_reg_set(mvi, port) == MVS_ID_NOT_MAPPED)
+ return -EBUSY;
+
+ slot = &mvi->slot_info[tag];
+ slot->tx = mvi->tx_prod;
+ mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | tag |
+ (TXQ_CMD_STP << TXQ_CMD_SHIFT) |
+ (sas_port->phy_mask << TXQ_PHY_SHIFT) |
+ (port->taskfileset << TXQ_SRS_SHIFT));
+
+ if (task->ata_task.use_ncq)
+ flags |= MCH_FPDMA;
+ if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) {
+ if (task->ata_task.fis.command != ATA_CMD_ID_ATAPI)
+ flags |= MCH_ATAPI;
+ }
+
+ /* FIXME: fill in port multiplier number */
+
+ hdr->flags = cpu_to_le32(flags);
+
+ /* FIXME: the low order order 5 bits for the TAG if enable NCQ */
+ if (task->ata_task.use_ncq) {
+ hdr->tags = cpu_to_le32(mvs_get_ncq_tag(task));
+ /*Fill in task file */
+ task->ata_task.fis.sector_count = hdr->tags << 3;
+ } else
+ hdr->tags = cpu_to_le32(tag);
+ hdr->data_len = cpu_to_le32(task->total_xfer_len);
+
+ /*
+ * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs
+ */
+
+ /* region 1: command table area (MVS_ATA_CMD_SZ bytes) ************** */
+ buf_cmd = buf_tmp = slot->buf;
+ buf_tmp_dma = slot->buf_dma;
+
+ hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma);
+
+ buf_tmp += MVS_ATA_CMD_SZ;
+ buf_tmp_dma += MVS_ATA_CMD_SZ;
+#if _MV_DUMP
+ slot->cmd_size = MVS_ATA_CMD_SZ;
+#endif
+
+ /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */
+ /* used for STP. unused for SATA? */
+ buf_oaf = buf_tmp;
+ hdr->open_frame = cpu_to_le64(buf_tmp_dma);
+
+ buf_tmp += MVS_OAF_SZ;
+ buf_tmp_dma += MVS_OAF_SZ;
+
+ /* region 3: PRD table ********************************************* */
+ buf_prd = buf_tmp;
+ if (tei->n_elem)
+ hdr->prd_tbl = cpu_to_le64(buf_tmp_dma);
+ else
+ hdr->prd_tbl = 0;
+
+ i = sizeof(struct mvs_prd) * tei->n_elem;
+ buf_tmp += i;
+ buf_tmp_dma += i;
+
+ /* region 4: status buffer (larger the PRD, smaller this buf) ****** */
+ /* FIXME: probably unused, for SATA. kept here just in case
+ * we get a STP/SATA error information record
+ */
+ slot->response = buf_tmp;
+ hdr->status_buf = cpu_to_le64(buf_tmp_dma);
+
+ req_len = sizeof(struct host_to_dev_fis);
+ resp_len = MVS_SLOT_BUF_SZ - MVS_ATA_CMD_SZ -
+ sizeof(struct mvs_err_info) - i;
+
+ /* request, response lengths */
+ resp_len = min(resp_len, max_resp_len);
+ hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | (req_len / 4));
+
+ task->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
+ /* fill in command FIS and ATAPI CDB */
+ memcpy(buf_cmd, &task->ata_task.fis, sizeof(struct host_to_dev_fis));
+ if (dev->sata_dev.command_set == ATAPI_COMMAND_SET)
+ memcpy(buf_cmd + STP_ATAPI_CMD,
+ task->ata_task.atapi_packet, 16);
+
+ /* generate open address frame hdr (first 12 bytes) */
+ buf_oaf[0] = (1 << 7) | (2 << 4) | 0x1; /* initiator, STP, ftype 1h */
+ buf_oaf[1] = task->dev->linkrate & 0xf;
+ *(u16 *)(buf_oaf + 2) = cpu_to_be16(tag);
+ memcpy(buf_oaf + 4, task->dev->sas_addr, SAS_ADDR_SIZE);
+
+ /* fill in PRD (scatter/gather) table, if any */
+ for_each_sg(task->scatter, sg, tei->n_elem, i) {
+ buf_prd->addr = cpu_to_le64(sg_dma_address(sg));
+ buf_prd->len = cpu_to_le32(sg_dma_len(sg));
+ buf_prd++;
+ }
+
+ return 0;
+}
+
+static int mvs_task_prep_ssp(struct mvs_info *mvi,
+ struct mvs_task_exec_info *tei)
+{
+ struct sas_task *task = tei->task;
+ struct mvs_cmd_hdr *hdr = tei->hdr;
+ struct mvs_port *port = tei->port;
+ struct mvs_slot_info *slot;
+ struct scatterlist *sg;
+ struct mvs_prd *buf_prd;
+ struct ssp_frame_hdr *ssp_hdr;
+ void *buf_tmp;
+ u8 *buf_cmd, *buf_oaf, fburst = 0;
+ dma_addr_t buf_tmp_dma;
+ u32 flags;
+ u32 resp_len, req_len, i, tag = tei->tag;
+ const u32 max_resp_len = SB_RFB_MAX;
+
+ slot = &mvi->slot_info[tag];
+
+ slot->tx = mvi->tx_prod;
+ mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | tag |
+ (TXQ_CMD_SSP << TXQ_CMD_SHIFT) |
+ (port->wide_port_phymap << TXQ_PHY_SHIFT));
+
+ flags = MCH_RETRY;
+ if (task->ssp_task.enable_first_burst) {
+ flags |= MCH_FBURST;
+ fburst = (1 << 7);
+ }
+ hdr->flags = cpu_to_le32(flags |
+ (tei->n_elem << MCH_PRD_LEN_SHIFT) |
+ (MCH_SSP_FR_CMD << MCH_SSP_FR_TYPE_SHIFT));
+
+ hdr->tags = cpu_to_le32(tag);
+ hdr->data_len = cpu_to_le32(task->total_xfer_len);
+
+ /*
+ * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs
+ */
+
+ /* region 1: command table area (MVS_SSP_CMD_SZ bytes) ************** */
+ buf_cmd = buf_tmp = slot->buf;
+ buf_tmp_dma = slot->buf_dma;
+
+ hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma);
+
+ buf_tmp += MVS_SSP_CMD_SZ;
+ buf_tmp_dma += MVS_SSP_CMD_SZ;
+#if _MV_DUMP
+ slot->cmd_size = MVS_SSP_CMD_SZ;
+#endif
+
+ /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */
+ buf_oaf = buf_tmp;
+ hdr->open_frame = cpu_to_le64(buf_tmp_dma);
+
+ buf_tmp += MVS_OAF_SZ;
+ buf_tmp_dma += MVS_OAF_SZ;
+
+ /* region 3: PRD table ********************************************* */
+ buf_prd = buf_tmp;
+ if (tei->n_elem)
+ hdr->prd_tbl = cpu_to_le64(buf_tmp_dma);
+ else
+ hdr->prd_tbl = 0;
+
+ i = sizeof(struct mvs_prd) * tei->n_elem;
+ buf_tmp += i;
+ buf_tmp_dma += i;
+
+ /* region 4: status buffer (larger the PRD, smaller this buf) ****** */
+ slot->response = buf_tmp;
+ hdr->status_buf = cpu_to_le64(buf_tmp_dma);
+
+ resp_len = MVS_SLOT_BUF_SZ - MVS_SSP_CMD_SZ - MVS_OAF_SZ -
+ sizeof(struct mvs_err_info) - i;
+ resp_len = min(resp_len, max_resp_len);
+
+ req_len = sizeof(struct ssp_frame_hdr) + 28;
+
+ /* request, response lengths */
+ hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | (req_len / 4));
+
+ /* generate open address frame hdr (first 12 bytes) */
+ buf_oaf[0] = (1 << 7) | (1 << 4) | 0x1; /* initiator, SSP, ftype 1h */
+ buf_oaf[1] = task->dev->linkrate & 0xf;
+ *(u16 *)(buf_oaf + 2) = cpu_to_be16(tag);
+ memcpy(buf_oaf + 4, task->dev->sas_addr, SAS_ADDR_SIZE);
+
+ /* fill in SSP frame header (Command Table.SSP frame header) */
+ ssp_hdr = (struct ssp_frame_hdr *)buf_cmd;
+ ssp_hdr->frame_type = SSP_COMMAND;
+ memcpy(ssp_hdr->hashed_dest_addr, task->dev->hashed_sas_addr,
+ HASHED_SAS_ADDR_SIZE);
+ memcpy(ssp_hdr->hashed_src_addr,
+ task->dev->port->ha->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
+ ssp_hdr->tag = cpu_to_be16(tag);
+
+ /* fill in command frame IU */
+ buf_cmd += sizeof(*ssp_hdr);
+ memcpy(buf_cmd, &task->ssp_task.LUN, 8);
+ buf_cmd[9] = fburst | task->ssp_task.task_attr |
+ (task->ssp_task.task_prio << 3);
+ memcpy(buf_cmd + 12, &task->ssp_task.cdb, 16);
+
+ /* fill in PRD (scatter/gather) table, if any */
+ for_each_sg(task->scatter, sg, tei->n_elem, i) {
+ buf_prd->addr = cpu_to_le64(sg_dma_address(sg));
+ buf_prd->len = cpu_to_le32(sg_dma_len(sg));
+ buf_prd++;
+ }
+
+ return 0;
+}
+
+static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags)
+{
+ struct domain_device *dev = task->dev;
+ struct mvs_info *mvi = dev->port->ha->lldd_ha;
+ struct pci_dev *pdev = mvi->pdev;
+ void __iomem *regs = mvi->regs;
+ struct mvs_task_exec_info tei;
+ struct sas_task *t = task;
+ u32 tag = 0xdeadbeef, rc, n_elem = 0;
+ unsigned long flags;
+ u32 n = num, pass = 0;
+
+ spin_lock_irqsave(&mvi->lock, flags);
+
+ do {
+ tei.port = &mvi->port[dev->port->id];
+
+ if (!tei.port->port_attached) {
+ struct task_status_struct *ts = &t->task_status;
+ ts->stat = SAS_PHY_DOWN;
+ t->task_done(t);
+ rc = 0;
+ goto exec_exit;
+ }
+ if (!sas_protocol_ata(t->task_proto)) {
+ if (t->num_scatter) {
+ n_elem = pci_map_sg(mvi->pdev, t->scatter,
+ t->num_scatter,
+ t->data_dir);
+ if (!n_elem) {
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ }
+ } else {
+ n_elem = t->num_scatter;
+ }
+
+ rc = mvs_tag_alloc(mvi, &tag);
+ if (rc)
+ goto err_out;
+
+ mvi->slot_info[tag].task = t;
+ mvi->slot_info[tag].n_elem = n_elem;
+ memset(mvi->slot_info[tag].buf, 0, MVS_SLOT_BUF_SZ);
+ tei.task = t;
+ tei.hdr = &mvi->slot[tag];
+ tei.tag = tag;
+ tei.n_elem = n_elem;
+
+ switch (t->task_proto) {
+ case SAS_PROTOCOL_SMP:
+ rc = mvs_task_prep_smp(mvi, &tei);
+ break;
+ case SAS_PROTOCOL_SSP:
+ rc = mvs_task_prep_ssp(mvi, &tei);
+ break;
+ case SAS_PROTOCOL_SATA:
+ case SAS_PROTOCOL_STP:
+ case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+ rc = mvs_task_prep_ata(mvi, &tei);
+ break;
+ default:
+ dev_printk(KERN_ERR, &pdev->dev,
+ "unknown sas_task proto: 0x%x\n",
+ t->task_proto);
+ rc = -EINVAL;
+ break;
+ }
+
+ if (rc)
+ goto err_out_tag;
+
+ /* TODO: select normal or high priority */
+
+ spin_lock(&t->task_state_lock);
+ t->task_state_flags |= SAS_TASK_AT_INITIATOR;
+ spin_unlock(&t->task_state_lock);
+
+ if (n == 1) {
+ spin_unlock_irqrestore(&mvi->lock, flags);
+ mw32(TX_PROD_IDX, mvi->tx_prod);
+ }
+ mvs_hba_memory_dump(mvi, tag, t->task_proto);
+
+ ++pass;
+ mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1);
+
+ if (n == 1)
+ break;
+
+ t = list_entry(t->list.next, struct sas_task, list);
+ } while (--n);
+
+ return 0;
+
+err_out_tag:
+ mvs_tag_free(mvi, tag);
+err_out:
+ dev_printk(KERN_ERR, &pdev->dev, "mvsas exec failed[%d]!\n", rc);
+ if (!sas_protocol_ata(t->task_proto))
+ if (n_elem)
+ pci_unmap_sg(mvi->pdev, t->scatter, n_elem,
+ t->data_dir);
+exec_exit:
+ if (pass)
+ mw32(TX_PROD_IDX, (mvi->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1));
+ spin_unlock_irqrestore(&mvi->lock, flags);
+ return rc;
+}
+
+static int mvs_task_abort(struct sas_task *task)
+{
+ int rc = 1;
+ unsigned long flags;
+ struct mvs_info *mvi = task->dev->port->ha->lldd_ha;
+ struct pci_dev *pdev = mvi->pdev;
+
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ if (task->task_state_flags & SAS_TASK_STATE_DONE) {
+ rc = TMF_RESP_FUNC_COMPLETE;
+ goto out_done;
+ }
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+ /*FIXME*/
+ rc = TMF_RESP_FUNC_COMPLETE;
+
+ switch (task->task_proto) {
+ case SAS_PROTOCOL_SMP:
+ dev_printk(KERN_DEBUG, &pdev->dev, "SMP Abort! ");
+ break;
+ case SAS_PROTOCOL_SSP:
+ dev_printk(KERN_DEBUG, &pdev->dev, "SSP Abort! ");
+ break;
+ case SAS_PROTOCOL_SATA:
+ case SAS_PROTOCOL_STP:
+ case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:{
+ dev_printk(KERN_DEBUG, &pdev->dev, "STP Abort! "
+ "Dump D2H FIS: \n");
+ mvs_hexdump(sizeof(struct host_to_dev_fis),
+ (void *)&task->ata_task.fis, 0);
+ dev_printk(KERN_DEBUG, &pdev->dev, "Dump ATAPI Cmd : \n");
+ mvs_hexdump(16, task->ata_task.atapi_packet, 0);
+ break;
+ }
+ default:
+ break;
+ }
+out_done:
+ return rc;
+}
+
+static void mvs_free(struct mvs_info *mvi)
+{
+ int i;
+
+ if (!mvi)
+ return;
+
+ for (i = 0; i < MVS_SLOTS; i++) {
+ struct mvs_slot_info *slot = &mvi->slot_info[i];
+
+ if (slot->buf)
+ dma_free_coherent(&mvi->pdev->dev, MVS_SLOT_BUF_SZ,
+ slot->buf, slot->buf_dma);
+ }
+
+ if (mvi->tx)
+ dma_free_coherent(&mvi->pdev->dev,
+ sizeof(*mvi->tx) * MVS_CHIP_SLOT_SZ,
+ mvi->tx, mvi->tx_dma);
+ if (mvi->rx_fis)
+ dma_free_coherent(&mvi->pdev->dev, MVS_RX_FISL_SZ,
+ mvi->rx_fis, mvi->rx_fis_dma);
+ if (mvi->rx)
+ dma_free_coherent(&mvi->pdev->dev,
+ sizeof(*mvi->rx) * MVS_RX_RING_SZ,
+ mvi->rx, mvi->rx_dma);
+ if (mvi->slot)
+ dma_free_coherent(&mvi->pdev->dev,
+ sizeof(*mvi->slot) * MVS_SLOTS,
+ mvi->slot, mvi->slot_dma);
+#ifdef MVS_ENABLE_PERI
+ if (mvi->peri_regs)
+ iounmap(mvi->peri_regs);
+#endif
+ if (mvi->regs)
+ iounmap(mvi->regs);
+ if (mvi->shost)
+ scsi_host_put(mvi->shost);
+ kfree(mvi->sas.sas_port);
+ kfree(mvi->sas.sas_phy);
+ kfree(mvi);
+}
+
+/* FIXME: locking? */
+static int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
+ void *funcdata)
+{
+ struct mvs_info *mvi = sas_phy->ha->lldd_ha;
+ int rc = 0, phy_id = sas_phy->id;
+ u32 tmp;
+
+ tmp = mvs_read_phy_ctl(mvi, phy_id);
+
+ switch (func) {
+ case PHY_FUNC_SET_LINK_RATE:{
+ struct sas_phy_linkrates *rates = funcdata;
+ u32 lrmin = 0, lrmax = 0;
+
+ lrmin = (rates->minimum_linkrate << 8);
+ lrmax = (rates->maximum_linkrate << 12);
+
+ if (lrmin) {
+ tmp &= ~(0xf << 8);
+ tmp |= lrmin;
+ }
+ if (lrmax) {
+ tmp &= ~(0xf << 12);
+ tmp |= lrmax;
+ }
+ mvs_write_phy_ctl(mvi, phy_id, tmp);
+ break;
+ }
+
+ case PHY_FUNC_HARD_RESET:
+ if (tmp & PHY_RST_HARD)
+ break;
+ mvs_write_phy_ctl(mvi, phy_id, tmp | PHY_RST_HARD);
+ break;
+
+ case PHY_FUNC_LINK_RESET:
+ mvs_write_phy_ctl(mvi, phy_id, tmp | PHY_RST);
+ break;
+
+ case PHY_FUNC_DISABLE:
+ case PHY_FUNC_RELEASE_SPINUP_HOLD:
+ default:
+ rc = -EOPNOTSUPP;
+ }
+
+ return rc;
+}
+
+static void __devinit mvs_phy_init(struct mvs_info *mvi, int phy_id)
+{
+ struct mvs_phy *phy = &mvi->phy[phy_id];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+
+ sas_phy->enabled = (phy_id < mvi->chip->n_phy) ? 1 : 0;
+ sas_phy->class = SAS;
+ sas_phy->iproto = SAS_PROTOCOL_ALL;
+ sas_phy->tproto = 0;
+ sas_phy->type = PHY_TYPE_PHYSICAL;
+ sas_phy->role = PHY_ROLE_INITIATOR;
+ sas_phy->oob_mode = OOB_NOT_CONNECTED;
+ sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN;
+
+ sas_phy->id = phy_id;
+ sas_phy->sas_addr = &mvi->sas_addr[0];
+ sas_phy->frame_rcvd = &phy->frame_rcvd[0];
+ sas_phy->ha = &mvi->sas;
+ sas_phy->lldd_phy = phy;
+}
+
+static struct mvs_info *__devinit mvs_alloc(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct mvs_info *mvi;
+ unsigned long res_start, res_len, res_flag;
+ struct asd_sas_phy **arr_phy;
+ struct asd_sas_port **arr_port;
+ const struct mvs_chip_info *chip = &mvs_chips[ent->driver_data];
+ int i;
+
+ /*
+ * alloc and init our per-HBA mvs_info struct
+ */
+
+ mvi = kzalloc(sizeof(*mvi), GFP_KERNEL);
+ if (!mvi)
+ return NULL;
+
+ spin_lock_init(&mvi->lock);
+ mvi->pdev = pdev;
+ mvi->chip = chip;
+
+ if (pdev->device == 0x6440 && pdev->revision == 0)
+ mvi->flags |= MVF_PHY_PWR_FIX;
+
+ /*
+ * alloc and init SCSI, SAS glue
+ */
+
+ mvi->shost = scsi_host_alloc(&mvs_sht, sizeof(void *));
+ if (!mvi->shost)
+ goto err_out;
+
+ arr_phy = kcalloc(MVS_MAX_PHYS, sizeof(void *), GFP_KERNEL);
+ arr_port = kcalloc(MVS_MAX_PHYS, sizeof(void *), GFP_KERNEL);
+ if (!arr_phy || !arr_port)
+ goto err_out;
+
+ for (i = 0; i < MVS_MAX_PHYS; i++) {
+ mvs_phy_init(mvi, i);
+ arr_phy[i] = &mvi->phy[i].sas_phy;
+ arr_port[i] = &mvi->port[i].sas_port;
+ }
+
+ SHOST_TO_SAS_HA(mvi->shost) = &mvi->sas;
+ mvi->shost->transportt = mvs_stt;
+ mvi->shost->max_id = 21;
+ mvi->shost->max_lun = ~0;
+ mvi->shost->max_channel = 0;
+ mvi->shost->max_cmd_len = 16;
+
+ mvi->sas.sas_ha_name = DRV_NAME;
+ mvi->sas.dev = &pdev->dev;
+ mvi->sas.lldd_module = THIS_MODULE;
+ mvi->sas.sas_addr = &mvi->sas_addr[0];
+ mvi->sas.sas_phy = arr_phy;
+ mvi->sas.sas_port = arr_port;
+ mvi->sas.num_phys = chip->n_phy;
+ mvi->sas.lldd_max_execute_num = MVS_CHIP_SLOT_SZ - 1;
+ mvi->sas.lldd_queue_size = MVS_QUEUE_SIZE;
+ mvi->can_queue = (MVS_CHIP_SLOT_SZ >> 1) - 1;
+ mvi->sas.lldd_ha = mvi;
+ mvi->sas.core.shost = mvi->shost;
+
+ mvs_tag_init(mvi);
+
+ /*
+ * ioremap main and peripheral registers
+ */
+
+#ifdef MVS_ENABLE_PERI
+ res_start = pci_resource_start(pdev, 2);
+ res_len = pci_resource_len(pdev, 2);
+ if (!res_start || !res_len)
+ goto err_out;
+
+ mvi->peri_regs = ioremap_nocache(res_start, res_len);
+ if (!mvi->peri_regs)
+ goto err_out;
+#endif
+
+ res_start = pci_resource_start(pdev, 4);
+ res_len = pci_resource_len(pdev, 4);
+ if (!res_start || !res_len)
+ goto err_out;
+
+ res_flag = pci_resource_flags(pdev, 4);
+ if (res_flag & IORESOURCE_CACHEABLE)
+ mvi->regs = ioremap(res_start, res_len);
+ else
+ mvi->regs = ioremap_nocache(res_start, res_len);
+
+ if (!mvi->regs)
+ goto err_out;
+
+ /*
+ * alloc and init our DMA areas
+ */
+
+ mvi->tx = dma_alloc_coherent(&pdev->dev,
+ sizeof(*mvi->tx) * MVS_CHIP_SLOT_SZ,
+ &mvi->tx_dma, GFP_KERNEL);
+ if (!mvi->tx)
+ goto err_out;
+ memset(mvi->tx, 0, sizeof(*mvi->tx) * MVS_CHIP_SLOT_SZ);
+
+ mvi->rx_fis = dma_alloc_coherent(&pdev->dev, MVS_RX_FISL_SZ,
+ &mvi->rx_fis_dma, GFP_KERNEL);
+ if (!mvi->rx_fis)
+ goto err_out;
+ memset(mvi->rx_fis, 0, MVS_RX_FISL_SZ);
+
+ mvi->rx = dma_alloc_coherent(&pdev->dev,
+ sizeof(*mvi->rx) * MVS_RX_RING_SZ,
+ &mvi->rx_dma, GFP_KERNEL);
+ if (!mvi->rx)
+ goto err_out;
+ memset(mvi->rx, 0, sizeof(*mvi->rx) * MVS_RX_RING_SZ);
+
+ mvi->rx[0] = cpu_to_le32(0xfff);
+ mvi->rx_cons = 0xfff;
+
+ mvi->slot = dma_alloc_coherent(&pdev->dev,
+ sizeof(*mvi->slot) * MVS_SLOTS,
+ &mvi->slot_dma, GFP_KERNEL);
+ if (!mvi->slot)
+ goto err_out;
+ memset(mvi->slot, 0, sizeof(*mvi->slot) * MVS_SLOTS);
+
+ for (i = 0; i < MVS_SLOTS; i++) {
+ struct mvs_slot_info *slot = &mvi->slot_info[i];
+
+ slot->buf = dma_alloc_coherent(&pdev->dev, MVS_SLOT_BUF_SZ,
+ &slot->buf_dma, GFP_KERNEL);
+ if (!slot->buf)
+ goto err_out;
+ memset(slot->buf, 0, MVS_SLOT_BUF_SZ);
+ }
+
+ /* finally, read NVRAM to get our SAS address */
+ if (mvs_nvram_read(mvi, NVR_SAS_ADDR, &mvi->sas_addr, 8))
+ goto err_out;
+ return mvi;
+
+err_out:
+ mvs_free(mvi);
+ return NULL;
+}
+
+static u32 mvs_cr32(void __iomem *regs, u32 addr)
+{
+ mw32(CMD_ADDR, addr);
+ return mr32(CMD_DATA);
+}
+
+static void mvs_cw32(void __iomem *regs, u32 addr, u32 val)
+{
+ mw32(CMD_ADDR, addr);
+ mw32(CMD_DATA, val);
+}
+
+static u32 mvs_read_phy_ctl(struct mvs_info *mvi, u32 port)
+{
+ void __iomem *regs = mvi->regs;
+ return (port < 4)?mr32(P0_SER_CTLSTAT + port * 4):
+ mr32(P4_SER_CTLSTAT + (port - 4) * 4);
+}
+
+static void mvs_write_phy_ctl(struct mvs_info *mvi, u32 port, u32 val)
+{
+ void __iomem *regs = mvi->regs;
+ if (port < 4)
+ mw32(P0_SER_CTLSTAT + port * 4, val);
+ else
+ mw32(P4_SER_CTLSTAT + (port - 4) * 4, val);
+}
+
+static u32 mvs_read_port(struct mvs_info *mvi, u32 off, u32 off2, u32 port)
+{
+ void __iomem *regs = mvi->regs + off;
+ void __iomem *regs2 = mvi->regs + off2;
+ return (port < 4)?readl(regs + port * 8):
+ readl(regs2 + (port - 4) * 8);
+}
+
+static void mvs_write_port(struct mvs_info *mvi, u32 off, u32 off2,
+ u32 port, u32 val)
+{
+ void __iomem *regs = mvi->regs + off;
+ void __iomem *regs2 = mvi->regs + off2;
+ if (port < 4)
+ writel(val, regs + port * 8);
+ else
+ writel(val, regs2 + (port - 4) * 8);
+}
+
+static u32 mvs_read_port_cfg_data(struct mvs_info *mvi, u32 port)
+{
+ return mvs_read_port(mvi, MVS_P0_CFG_DATA, MVS_P4_CFG_DATA, port);
+}
+
+static void mvs_write_port_cfg_data(struct mvs_info *mvi, u32 port, u32 val)
+{
+ mvs_write_port(mvi, MVS_P0_CFG_DATA, MVS_P4_CFG_DATA, port, val);
+}
+
+static void mvs_write_port_cfg_addr(struct mvs_info *mvi, u32 port, u32 addr)
+{
+ mvs_write_port(mvi, MVS_P0_CFG_ADDR, MVS_P4_CFG_ADDR, port, addr);
+}
+
+static u32 mvs_read_port_vsr_data(struct mvs_info *mvi, u32 port)
+{
+ return mvs_read_port(mvi, MVS_P0_VSR_DATA, MVS_P4_VSR_DATA, port);
+}
+
+static void mvs_write_port_vsr_data(struct mvs_info *mvi, u32 port, u32 val)
+{
+ mvs_write_port(mvi, MVS_P0_VSR_DATA, MVS_P4_VSR_DATA, port, val);
+}
+
+static void mvs_write_port_vsr_addr(struct mvs_info *mvi, u32 port, u32 addr)
+{
+ mvs_write_port(mvi, MVS_P0_VSR_ADDR, MVS_P4_VSR_ADDR, port, addr);
+}
+
+static u32 mvs_read_port_irq_stat(struct mvs_info *mvi, u32 port)
+{
+ return mvs_read_port(mvi, MVS_P0_INT_STAT, MVS_P4_INT_STAT, port);
+}
+
+static void mvs_write_port_irq_stat(struct mvs_info *mvi, u32 port, u32 val)
+{
+ mvs_write_port(mvi, MVS_P0_INT_STAT, MVS_P4_INT_STAT, port, val);
+}
+
+static u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port)
+{
+ return mvs_read_port(mvi, MVS_P0_INT_MASK, MVS_P4_INT_MASK, port);
+}
+
+static void mvs_write_port_irq_mask(struct mvs_info *mvi, u32 port, u32 val)
+{
+ mvs_write_port(mvi, MVS_P0_INT_MASK, MVS_P4_INT_MASK, port, val);
+}
+
+static void __devinit mvs_phy_hacks(struct mvs_info *mvi)
+{
+ void __iomem *regs = mvi->regs;
+ u32 tmp;
+
+ /* workaround for SATA R-ERR, to ignore phy glitch */
+ tmp = mvs_cr32(regs, CMD_PHY_TIMER);
+ tmp &= ~(1 << 9);
+ tmp |= (1 << 10);
+ mvs_cw32(regs, CMD_PHY_TIMER, tmp);
+
+ /* enable retry 127 times */
+ mvs_cw32(regs, CMD_SAS_CTL1, 0x7f7f);
+
+ /* extend open frame timeout to max */
+ tmp = mvs_cr32(regs, CMD_SAS_CTL0);
+ tmp &= ~0xffff;
+ tmp |= 0x3fff;
+ mvs_cw32(regs, CMD_SAS_CTL0, tmp);
+
+ /* workaround for WDTIMEOUT , set to 550 ms */
+ mvs_cw32(regs, CMD_WD_TIMER, 0xffffff);
+
+ /* not to halt for different port op during wideport link change */
+ mvs_cw32(regs, CMD_APP_ERR_CONFIG, 0xffefbf7d);
+
+ /* workaround for Seagate disk not-found OOB sequence, recv
+ * COMINIT before sending out COMWAKE */
+ tmp = mvs_cr32(regs, CMD_PHY_MODE_21);
+ tmp &= 0x0000ffff;
+ tmp |= 0x00fa0000;
+ mvs_cw32(regs, CMD_PHY_MODE_21, tmp);
+
+ tmp = mvs_cr32(regs, CMD_PHY_TIMER);
+ tmp &= 0x1fffffff;
+ tmp |= (2U << 29); /* 8 ms retry */
+ mvs_cw32(regs, CMD_PHY_TIMER, tmp);
+
+ /* TEST - for phy decoding error, adjust voltage levels */
+ mw32(P0_VSR_ADDR + 0, 0x8);
+ mw32(P0_VSR_DATA + 0, 0x2F0);
+
+ mw32(P0_VSR_ADDR + 8, 0x8);
+ mw32(P0_VSR_DATA + 8, 0x2F0);
+
+ mw32(P0_VSR_ADDR + 16, 0x8);
+ mw32(P0_VSR_DATA + 16, 0x2F0);
+
+ mw32(P0_VSR_ADDR + 24, 0x8);
+ mw32(P0_VSR_DATA + 24, 0x2F0);
+
+}
+
+static void mvs_enable_xmt(struct mvs_info *mvi, int PhyId)
+{
+ void __iomem *regs = mvi->regs;
+ u32 tmp;
+
+ tmp = mr32(PCS);
+ if (mvi->chip->n_phy <= 4)
+ tmp |= 1 << (PhyId + PCS_EN_PORT_XMT_SHIFT);
+ else
+ tmp |= 1 << (PhyId + PCS_EN_PORT_XMT_SHIFT2);
+ mw32(PCS, tmp);
+}
+
+static void mvs_detect_porttype(struct mvs_info *mvi, int i)
+{
+ void __iomem *regs = mvi->regs;
+ u32 reg;
+ struct mvs_phy *phy = &mvi->phy[i];
+
+ /* TODO check & save device type */
+ reg = mr32(GBL_PORT_TYPE);
+
+ if (reg & MODE_SAS_SATA & (1 << i))
+ phy->phy_type |= PORT_TYPE_SAS;
+ else
+ phy->phy_type |= PORT_TYPE_SATA;
+}
+
+static void *mvs_get_d2h_reg(struct mvs_info *mvi, int i, void *buf)
+{
+ u32 *s = (u32 *) buf;
+
+ if (!s)
+ return NULL;
+
+ mvs_write_port_cfg_addr(mvi, i, PHYR_SATA_SIG3);
+ s[3] = mvs_read_port_cfg_data(mvi, i);
+
+ mvs_write_port_cfg_addr(mvi, i, PHYR_SATA_SIG2);
+ s[2] = mvs_read_port_cfg_data(mvi, i);
+
+ mvs_write_port_cfg_addr(mvi, i, PHYR_SATA_SIG1);
+ s[1] = mvs_read_port_cfg_data(mvi, i);
+
+ mvs_write_port_cfg_addr(mvi, i, PHYR_SATA_SIG0);
+ s[0] = mvs_read_port_cfg_data(mvi, i);
+
+ return (void *)s;
+}
+
+static u32 mvs_is_sig_fis_received(u32 irq_status)
+{
+ return irq_status & PHYEV_SIG_FIS;
+}
+
+static void mvs_update_wideport(struct mvs_info *mvi, int i)
+{
+ struct mvs_phy *phy = &mvi->phy[i];
+ struct mvs_port *port = phy->port;
+ int j, no;
+
+ for_each_phy(port->wide_port_phymap, no, j, mvi->chip->n_phy)
+ if (no & 1) {
+ mvs_write_port_cfg_addr(mvi, no, PHYR_WIDE_PORT);
+ mvs_write_port_cfg_data(mvi, no,
+ port->wide_port_phymap);
+ } else {
+ mvs_write_port_cfg_addr(mvi, no, PHYR_WIDE_PORT);
+ mvs_write_port_cfg_data(mvi, no, 0);
+ }
+}
+
+static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i)
+{
+ u32 tmp;
+ struct mvs_phy *phy = &mvi->phy[i];
+ struct mvs_port *port;
+
+ tmp = mvs_read_phy_ctl(mvi, i);
+
+ if ((tmp & PHY_READY_MASK) && !(phy->irq_status & PHYEV_POOF)) {
+ if (!phy->port)
+ phy->phy_attached = 1;
+ return tmp;
+ }
+
+ port = phy->port;
+ if (port) {
+ if (phy->phy_type & PORT_TYPE_SAS) {
+ port->wide_port_phymap &= ~(1U << i);
+ if (!port->wide_port_phymap)
+ port->port_attached = 0;
+ mvs_update_wideport(mvi, i);
+ } else if (phy->phy_type & PORT_TYPE_SATA)
+ port->port_attached = 0;
+ mvs_free_reg_set(mvi, phy->port);
+ phy->port = NULL;
+ phy->phy_attached = 0;
+ phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
+ }
+ return 0;
+}
+
+static void mvs_update_phyinfo(struct mvs_info *mvi, int i,
+ int get_st)
+{
+ struct mvs_phy *phy = &mvi->phy[i];
+ struct pci_dev *pdev = mvi->pdev;
+ u32 tmp, j;
+ u64 tmp64;
+
+ mvs_write_port_cfg_addr(mvi, i, PHYR_IDENTIFY);
+ phy->dev_info = mvs_read_port_cfg_data(mvi, i);
+
+ mvs_write_port_cfg_addr(mvi, i, PHYR_ADDR_HI);
+ phy->dev_sas_addr = (u64) mvs_read_port_cfg_data(mvi, i) << 32;
+
+ mvs_write_port_cfg_addr(mvi, i, PHYR_ADDR_LO);
+ phy->dev_sas_addr |= mvs_read_port_cfg_data(mvi, i);
+
+ if (get_st) {
+ phy->irq_status = mvs_read_port_irq_stat(mvi, i);
+ phy->phy_status = mvs_is_phy_ready(mvi, i);
+ }
+
+ if (phy->phy_status) {
+ u32 phy_st;
+ struct asd_sas_phy *sas_phy = mvi->sas.sas_phy[i];
+
+ mvs_write_port_cfg_addr(mvi, i, PHYR_PHY_STAT);
+ phy_st = mvs_read_port_cfg_data(mvi, i);
+
+ sas_phy->linkrate =
+ (phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>
+ PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET;
+
+ /* Updated attached_sas_addr */
+ mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_HI);
+ phy->att_dev_sas_addr =
+ (u64) mvs_read_port_cfg_data(mvi, i) << 32;
+
+ mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_LO);
+ phy->att_dev_sas_addr |= mvs_read_port_cfg_data(mvi, i);
+
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "phy[%d] Get Attached Address 0x%llX ,"
+ " SAS Address 0x%llX\n",
+ i, phy->att_dev_sas_addr, phy->dev_sas_addr);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "Rate = %x , type = %d\n",
+ sas_phy->linkrate, phy->phy_type);
+
+#if 1
+ /*
+ * If the device is capable of supporting a wide port
+ * on its phys, it may configure the phys as a wide port.
+ */
+ if (phy->phy_type & PORT_TYPE_SAS)
+ for (j = 0; j < mvi->chip->n_phy && j != i; ++j) {
+ if ((mvi->phy[j].phy_attached) &&
+ (mvi->phy[j].phy_type & PORT_TYPE_SAS))
+ if (phy->att_dev_sas_addr ==
+ mvi->phy[j].att_dev_sas_addr - 1) {
+ phy->att_dev_sas_addr =
+ mvi->phy[j].att_dev_sas_addr;
+ break;
+ }
+ }
+
+#endif
+
+ tmp64 = cpu_to_be64(phy->att_dev_sas_addr);
+ memcpy(sas_phy->attached_sas_addr, &tmp64, SAS_ADDR_SIZE);
+
+ if (phy->phy_type & PORT_TYPE_SAS) {
+ mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_DEV_INFO);
+ phy->att_dev_info = mvs_read_port_cfg_data(mvi, i);
+ phy->identify.device_type =
+ phy->att_dev_info & PORT_DEV_TYPE_MASK;
+
+ if (phy->identify.device_type == SAS_END_DEV)
+ phy->identify.target_port_protocols =
+ SAS_PROTOCOL_SSP;
+ else if (phy->identify.device_type != NO_DEVICE)
+ phy->identify.target_port_protocols =
+ SAS_PROTOCOL_SMP;
+ if (phy_st & PHY_OOB_DTCTD)
+ sas_phy->oob_mode = SAS_OOB_MODE;
+ phy->frame_rcvd_size =
+ sizeof(struct sas_identify_frame);
+ } else if (phy->phy_type & PORT_TYPE_SATA) {
+ phy->identify.target_port_protocols = SAS_PROTOCOL_STP;
+ if (mvs_is_sig_fis_received(phy->irq_status)) {
+ if (phy_st & PHY_OOB_DTCTD)
+ sas_phy->oob_mode = SATA_OOB_MODE;
+ phy->frame_rcvd_size =
+ sizeof(struct dev_to_host_fis);
+ mvs_get_d2h_reg(mvi, i,
+ (void *)sas_phy->frame_rcvd);
+ } else {
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "No sig fis\n");
+ }
+ }
+ /* workaround for HW phy decoding error on 1.5g disk drive */
+ mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE6);
+ tmp = mvs_read_port_vsr_data(mvi, i);
+ if (((phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>
+ PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET) ==
+ SAS_LINK_RATE_1_5_GBPS)
+ tmp &= ~PHY_MODE6_DTL_SPEED;
+ else
+ tmp |= PHY_MODE6_DTL_SPEED;
+ mvs_write_port_vsr_data(mvi, i, tmp);
+
+ }
+ if (get_st)
+ mvs_write_port_irq_stat(mvi, i, phy->irq_status);
+}
+
+static void mvs_port_formed(struct asd_sas_phy *sas_phy)
+{
+ struct sas_ha_struct *sas_ha = sas_phy->ha;
+ struct mvs_info *mvi = sas_ha->lldd_ha;
+ struct asd_sas_port *sas_port = sas_phy->port;
+ struct mvs_phy *phy = sas_phy->lldd_phy;
+ struct mvs_port *port = &mvi->port[sas_port->id];
+ unsigned long flags;
+
+ spin_lock_irqsave(&mvi->lock, flags);
+ port->port_attached = 1;
+ phy->port = port;
+ port->taskfileset = MVS_ID_NOT_MAPPED;
+ if (phy->phy_type & PORT_TYPE_SAS) {
+ port->wide_port_phymap = sas_port->phy_mask;
+ mvs_update_wideport(mvi, sas_phy->id);
+ }
+ spin_unlock_irqrestore(&mvi->lock, flags);
+}
+
+static int __devinit mvs_hw_init(struct mvs_info *mvi)
+{
+ void __iomem *regs = mvi->regs;
+ int i;
+ u32 tmp, cctl;
+
+ /* make sure interrupts are masked immediately (paranoia) */
+ mw32(GBL_CTL, 0);
+ tmp = mr32(GBL_CTL);
+
+ /* Reset Controller */
+ if (!(tmp & HBA_RST)) {
+ if (mvi->flags & MVF_PHY_PWR_FIX) {
+ pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, &tmp);
+ tmp &= ~PCTL_PWR_ON;
+ tmp |= PCTL_OFF;
+ pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, tmp);
+
+ pci_read_config_dword(mvi->pdev, PCR_PHY_CTL2, &tmp);
+ tmp &= ~PCTL_PWR_ON;
+ tmp |= PCTL_OFF;
+ pci_write_config_dword(mvi->pdev, PCR_PHY_CTL2, tmp);
+ }
+
+ /* global reset, incl. COMRESET/H_RESET_N (self-clearing) */
+ mw32_f(GBL_CTL, HBA_RST);
+ }
+
+ /* wait for reset to finish; timeout is just a guess */
+ i = 1000;
+ while (i-- > 0) {
+ msleep(10);
+
+ if (!(mr32(GBL_CTL) & HBA_RST))
+ break;
+ }
+ if (mr32(GBL_CTL) & HBA_RST) {
+ dev_printk(KERN_ERR, &mvi->pdev->dev, "HBA reset failed\n");
+ return -EBUSY;
+ }
+
+ /* Init Chip */
+ /* make sure RST is set; HBA_RST /should/ have done that for us */
+ cctl = mr32(CTL);
+ if (cctl & CCTL_RST)
+ cctl &= ~CCTL_RST;
+ else
+ mw32_f(CTL, cctl | CCTL_RST);
+
+ /* write to device control _AND_ device status register? - A.C. */
+ pci_read_config_dword(mvi->pdev, PCR_DEV_CTRL, &tmp);
+ tmp &= ~PRD_REQ_MASK;
+ tmp |= PRD_REQ_SIZE;
+ pci_write_config_dword(mvi->pdev, PCR_DEV_CTRL, tmp);
+
+ pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, &tmp);
+ tmp |= PCTL_PWR_ON;
+ tmp &= ~PCTL_OFF;
+ pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, tmp);
+
+ pci_read_config_dword(mvi->pdev, PCR_PHY_CTL2, &tmp);
+ tmp |= PCTL_PWR_ON;
+ tmp &= ~PCTL_OFF;
+ pci_write_config_dword(mvi->pdev, PCR_PHY_CTL2, tmp);
+
+ mw32_f(CTL, cctl);
+
+ /* reset control */
+ mw32(PCS, 0); /*MVS_PCS */
+
+ mvs_phy_hacks(mvi);
+
+ mw32(CMD_LIST_LO, mvi->slot_dma);
+ mw32(CMD_LIST_HI, (mvi->slot_dma >> 16) >> 16);
+
+ mw32(RX_FIS_LO, mvi->rx_fis_dma);
+ mw32(RX_FIS_HI, (mvi->rx_fis_dma >> 16) >> 16);
+
+ mw32(TX_CFG, MVS_CHIP_SLOT_SZ);
+ mw32(TX_LO, mvi->tx_dma);
+ mw32(TX_HI, (mvi->tx_dma >> 16) >> 16);
+
+ mw32(RX_CFG, MVS_RX_RING_SZ);
+ mw32(RX_LO, mvi->rx_dma);
+ mw32(RX_HI, (mvi->rx_dma >> 16) >> 16);
+
+ /* enable auto port detection */
+ mw32(GBL_PORT_TYPE, MODE_AUTO_DET_EN);
+ msleep(100);
+ /* init and reset phys */
+ for (i = 0; i < mvi->chip->n_phy; i++) {
+ u32 lo = be32_to_cpu(*(u32 *)&mvi->sas_addr[4]);
+ u32 hi = be32_to_cpu(*(u32 *)&mvi->sas_addr[0]);
+
+ mvs_detect_porttype(mvi, i);
+
+ /* set phy local SAS address */
+ mvs_write_port_cfg_addr(mvi, i, PHYR_ADDR_LO);
+ mvs_write_port_cfg_data(mvi, i, lo);
+ mvs_write_port_cfg_addr(mvi, i, PHYR_ADDR_HI);
+ mvs_write_port_cfg_data(mvi, i, hi);
+
+ /* reset phy */
+ tmp = mvs_read_phy_ctl(mvi, i);
+ tmp |= PHY_RST;
+ mvs_write_phy_ctl(mvi, i, tmp);
+ }
+
+ msleep(100);
+
+ for (i = 0; i < mvi->chip->n_phy; i++) {
+ /* clear phy int status */
+ tmp = mvs_read_port_irq_stat(mvi, i);
+ tmp &= ~PHYEV_SIG_FIS;
+ mvs_write_port_irq_stat(mvi, i, tmp);
+
+ /* set phy int mask */
+ tmp = PHYEV_RDY_CH | PHYEV_BROAD_CH | PHYEV_UNASSOC_FIS |
+ PHYEV_ID_DONE | PHYEV_DEC_ERR;
+ mvs_write_port_irq_mask(mvi, i, tmp);
+
+ msleep(100);
+ mvs_update_phyinfo(mvi, i, 1);
+ mvs_enable_xmt(mvi, i);
+ }
+
+ /* FIXME: update wide port bitmaps */
+
+ /* little endian for open address and command table, etc. */
+ /* A.C.
+ * it seems that ( from the spec ) turning on big-endian won't
+ * do us any good on big-endian machines, need further confirmation
+ */
+ cctl = mr32(CTL);
+ cctl |= CCTL_ENDIAN_CMD;
+ cctl |= CCTL_ENDIAN_DATA;
+ cctl &= ~CCTL_ENDIAN_OPEN;
+ cctl |= CCTL_ENDIAN_RSP;
+ mw32_f(CTL, cctl);
+
+ /* reset CMD queue */
+ tmp = mr32(PCS);
+ tmp |= PCS_CMD_RST;
+ mw32(PCS, tmp);
+ /* interrupt coalescing may cause missing HW interrput in some case,
+ * and the max count is 0x1ff, while our max slot is 0x200,
+ * it will make count 0.
+ */
+ tmp = 0;
+ mw32(INT_COAL, tmp);
+
+ tmp = 0x100;
+ mw32(INT_COAL_TMOUT, tmp);
+
+ /* ladies and gentlemen, start your engines */
+ mw32(TX_CFG, 0);
+ mw32(TX_CFG, MVS_CHIP_SLOT_SZ | TX_EN);
+ mw32(RX_CFG, MVS_RX_RING_SZ | RX_EN);
+ /* enable CMD/CMPL_Q/RESP mode */
+ mw32(PCS, PCS_SATA_RETRY | PCS_FIS_RX_EN | PCS_CMD_EN);
+
+ /* re-enable interrupts globally */
+ mvs_hba_interrupt_enable(mvi);
+
+ /* enable completion queue interrupt */
+ tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM);
+ mw32(INT_MASK, tmp);
+
+ return 0;
+}
+
+static void __devinit mvs_print_info(struct mvs_info *mvi)
+{
+ struct pci_dev *pdev = mvi->pdev;
+ static int printed_version;
+
+ if (!printed_version++)
+ dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
+ dev_printk(KERN_INFO, &pdev->dev, "%u phys, addr %llx\n",
+ mvi->chip->n_phy, SAS_ADDR(mvi->sas_addr));
+}
+
+static int __devinit mvs_pci_init(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ int rc;
+ struct mvs_info *mvi;
+ irq_handler_t irq_handler = mvs_interrupt;
+
+ rc = pci_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ pci_set_master(pdev);
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc)
+ goto err_out_disable;
+
+ rc = pci_go_64(pdev);
+ if (rc)
+ goto err_out_regions;
+
+ mvi = mvs_alloc(pdev, ent);
+ if (!mvi) {
+ rc = -ENOMEM;
+ goto err_out_regions;
+ }
+
+ rc = mvs_hw_init(mvi);
+ if (rc)
+ goto err_out_mvi;
+
+#ifndef MVS_DISABLE_MSI
+ if (!pci_enable_msi(pdev)) {
+ u32 tmp;
+ void __iomem *regs = mvi->regs;
+ mvi->flags |= MVF_MSI;
+ irq_handler = mvs_msi_interrupt;
+ tmp = mr32(PCS);
+ mw32(PCS, tmp | PCS_SELF_CLEAR);
+ }
+#endif
+
+ rc = request_irq(pdev->irq, irq_handler, IRQF_SHARED, DRV_NAME, mvi);
+ if (rc)
+ goto err_out_msi;
+
+ rc = scsi_add_host(mvi->shost, &pdev->dev);
+ if (rc)
+ goto err_out_irq;
+
+ rc = sas_register_ha(&mvi->sas);
+ if (rc)
+ goto err_out_shost;
+
+ pci_set_drvdata(pdev, mvi);
+
+ mvs_print_info(mvi);
+
+ scsi_scan_host(mvi->shost);
+
+ return 0;
+
+err_out_shost:
+ scsi_remove_host(mvi->shost);
+err_out_irq:
+ free_irq(pdev->irq, mvi);
+err_out_msi:
+ if (mvi->flags |= MVF_MSI)
+ pci_disable_msi(pdev);
+err_out_mvi:
+ mvs_free(mvi);
+err_out_regions:
+ pci_release_regions(pdev);
+err_out_disable:
+ pci_disable_device(pdev);
+ return rc;
+}
+
+static void __devexit mvs_pci_remove(struct pci_dev *pdev)
+{
+ struct mvs_info *mvi = pci_get_drvdata(pdev);
+
+ pci_set_drvdata(pdev, NULL);
+
+ if (mvi) {
+ sas_unregister_ha(&mvi->sas);
+ mvs_hba_interrupt_disable(mvi);
+ sas_remove_host(mvi->shost);
+ scsi_remove_host(mvi->shost);
+
+ free_irq(pdev->irq, mvi);
+ if (mvi->flags & MVF_MSI)
+ pci_disable_msi(pdev);
+ mvs_free(mvi);
+ pci_release_regions(pdev);
+ }
+ pci_disable_device(pdev);
+}
+
+static struct sas_domain_function_template mvs_transport_ops = {
+ .lldd_execute_task = mvs_task_exec,
+ .lldd_control_phy = mvs_phy_control,
+ .lldd_abort_task = mvs_task_abort,
+ .lldd_port_formed = mvs_port_formed
+};
+
+static struct pci_device_id __devinitdata mvs_pci_table[] = {
+ { PCI_VDEVICE(MARVELL, 0x6320), chip_6320 },
+ { PCI_VDEVICE(MARVELL, 0x6340), chip_6440 },
+ { PCI_VDEVICE(MARVELL, 0x6440), chip_6440 },
+ { PCI_VDEVICE(MARVELL, 0x6480), chip_6480 },
+
+ { } /* terminate list */
+};
+
+static struct pci_driver mvs_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = mvs_pci_table,
+ .probe = mvs_pci_init,
+ .remove = __devexit_p(mvs_pci_remove),
+};
+
+static int __init mvs_init(void)
+{
+ int rc;
+
+ mvs_stt = sas_domain_attach_transport(&mvs_transport_ops);
+ if (!mvs_stt)
+ return -ENOMEM;
+
+ rc = pci_register_driver(&mvs_pci_driver);
+ if (rc)
+ goto err_out;
+
+ return 0;
+
+err_out:
+ sas_release_transport(mvs_stt);
+ return rc;
+}
+
+static void __exit mvs_exit(void)
+{
+ pci_unregister_driver(&mvs_pci_driver);
+ sas_release_transport(mvs_stt);
+}
+
+module_init(mvs_init);
+module_exit(mvs_exit);
+
+MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
+MODULE_DESCRIPTION("Marvell 88SE6440 SAS/SATA controller driver");
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, mvs_pci_table);
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index 0cd614a0fa7..fad6cb5cba2 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -124,7 +124,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf)
}
req_len += sgpnt->length;
}
- scsi_set_resid(cmd, req_len - act_len);
+ scsi_set_resid(cmd, buflen - act_len);
return 0;
}
@@ -427,7 +427,7 @@ static struct scsi_host_template ps3rom_host_template = {
.cmd_per_lun = 1,
.emulated = 1, /* only sg driver uses this */
.max_sectors = PS3ROM_MAX_SECTORS,
- .use_clustering = ENABLE_CLUSTERING,
+ .use_clustering = DISABLE_CLUSTERING,
.module = THIS_MODULE,
};
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 1479c60441c..2cd899bfe84 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -23,7 +23,7 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
mutex_lock(&ha->fce_mutex);
seq_printf(s, "FCE Trace Buffer\n");
- seq_printf(s, "In Pointer = %llx\n\n", ha->fce_wr);
+ seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr);
seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma);
seq_printf(s, "FCE Enable Registers\n");
seq_printf(s, "%08x %08x %08x %08x %08x %08x\n",
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 6226d88479f..c1808763d40 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -39,7 +39,7 @@ qla2x00_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size)
ms_pkt->entry_count = 1;
SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
- ms_pkt->timeout = __constant_cpu_to_le16(25);
+ ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
@@ -75,7 +75,7 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size)
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle = __constant_cpu_to_le16(NPH_SNS);
- ct_pkt->timeout = __constant_cpu_to_le16(25);
+ ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
@@ -1144,7 +1144,7 @@ qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
ms_pkt->entry_count = 1;
SET_TARGET_ID(ha, ms_pkt->loop_id, ha->mgmt_svr_loop_id);
ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
- ms_pkt->timeout = __constant_cpu_to_le16(59);
+ ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
@@ -1181,7 +1181,7 @@ qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
- ct_pkt->timeout = __constant_cpu_to_le16(59);
+ ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
@@ -1761,7 +1761,7 @@ qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size,
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
- ct_pkt->timeout = __constant_cpu_to_le16(59);
+ ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index d5c7853e7eb..364be7d0687 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1733,8 +1733,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
ha->login_timeout = nv->login_timeout;
icb->login_timeout = nv->login_timeout;
- /* Set minimum RATOV to 200 tenths of a second. */
- ha->r_a_tov = 200;
+ /* Set minimum RATOV to 100 tenths of a second. */
+ ha->r_a_tov = 100;
ha->loop_reset_delay = nv->reset_delay;
@@ -3645,8 +3645,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
ha->login_timeout = le16_to_cpu(nv->login_timeout);
icb->login_timeout = cpu_to_le16(nv->login_timeout);
- /* Set minimum RATOV to 200 tenths of a second. */
- ha->r_a_tov = 200;
+ /* Set minimum RATOV to 100 tenths of a second. */
+ ha->r_a_tov = 100;
ha->loop_reset_delay = nv->reset_delay;
@@ -4022,7 +4022,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha)
return;
ret = qla2x00_stop_firmware(ha);
- for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) {
+ for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT &&
+ retries ; retries--) {
qla2x00_reset_chip(ha);
if (qla2x00_chip_diag(ha) != QLA_SUCCESS)
continue;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 14e6f22944b..f0337036c7b 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -958,6 +958,11 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
}
}
+ /* Check for overrun. */
+ if (IS_FWI2_CAPABLE(ha) && comp_status == CS_COMPLETE &&
+ scsi_status & SS_RESIDUAL_OVER)
+ comp_status = CS_DATA_OVERRUN;
+
/*
* Based on Host and scsi status generate status code for Linux
*/
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 99d29fff836..bb103580e1b 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -2206,7 +2206,7 @@ qla24xx_abort_target(fc_port_t *fcport)
tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
tsk->p.tsk.entry_count = 1;
tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
- tsk->p.tsk.timeout = __constant_cpu_to_le16(25);
+ tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET);
tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index c5742cc15ab..ea08a129fee 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.02.00-k8"
+#define QLA2XXX_VERSION "8.02.00-k9"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 2
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 10b3b9a620f..109c5f5985e 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -1299,9 +1299,9 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha,
ddb_entry->fw_ddb_device_state = state;
/* Device is back online. */
if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) {
+ atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
atomic_set(&ddb_entry->port_down_timer,
ha->port_down_retry_count);
- atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
atomic_set(&ddb_entry->relogin_retry_count, 0);
atomic_set(&ddb_entry->relogin_timer, 0);
clear_bit(DF_RELOGIN, &ddb_entry->flags);
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 0f029d0d731..fc84db4069f 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -100,8 +100,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) {
scsi_set_resid(cmd, residual);
- if (!scsi_status && ((scsi_bufflen(cmd) - residual) <
- cmd->underflow)) {
+ if ((scsi_bufflen(cmd) - residual) < cmd->underflow) {
cmd->result = DID_ERROR << 16;
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index c3c59d76303..8b92f348f02 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -75,6 +75,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd);
static int qla4xxx_slave_alloc(struct scsi_device *device);
static int qla4xxx_slave_configure(struct scsi_device *device);
static void qla4xxx_slave_destroy(struct scsi_device *sdev);
+static void qla4xxx_scan_start(struct Scsi_Host *shost);
static struct scsi_host_template qla4xxx_driver_template = {
.module = THIS_MODULE,
@@ -90,6 +91,7 @@ static struct scsi_host_template qla4xxx_driver_template = {
.slave_destroy = qla4xxx_slave_destroy,
.scan_finished = iscsi_scan_finished,
+ .scan_start = qla4xxx_scan_start,
.this_id = -1,
.cmd_per_lun = 3,
@@ -299,6 +301,18 @@ struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha)
return ddb_entry;
}
+static void qla4xxx_scan_start(struct Scsi_Host *shost)
+{
+ struct scsi_qla_host *ha = shost_priv(shost);
+ struct ddb_entry *ddb_entry, *ddbtemp;
+
+ /* finish setup of sessions that were already setup in firmware */
+ list_for_each_entry_safe(ddb_entry, ddbtemp, &ha->ddb_list, list) {
+ if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE)
+ qla4xxx_add_sess(ddb_entry);
+ }
+}
+
/*
* Timer routines
*/
@@ -864,8 +878,9 @@ static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha)
* qla4xxx_recover_adapter - recovers adapter after a fatal error
* @ha: Pointer to host adapter structure.
* @renew_ddb_list: Indicates what to do with the adapter's ddb list
- * after adapter recovery has completed.
- * 0=preserve ddb list, 1=destroy and rebuild ddb list
+ *
+ * renew_ddb_list value can be 0=preserve ddb list, 1=destroy and rebuild
+ * ddb list.
**/
static int qla4xxx_recover_adapter(struct scsi_qla_host *ha,
uint8_t renew_ddb_list)
@@ -874,6 +889,7 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha,
/* Stall incoming I/O until we are done */
clear_bit(AF_ONLINE, &ha->flags);
+
DEBUG2(printk("scsi%ld: %s calling qla4xxx_cmd_wait\n", ha->host_no,
__func__));
@@ -1176,7 +1192,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
int ret = -ENODEV, status;
struct Scsi_Host *host;
struct scsi_qla_host *ha;
- struct ddb_entry *ddb_entry, *ddbtemp;
uint8_t init_retry_count = 0;
char buf[34];
@@ -1295,13 +1310,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
if (ret)
goto probe_failed;
- /* Update transport device information for all devices. */
- list_for_each_entry_safe(ddb_entry, ddbtemp, &ha->ddb_list, list) {
- if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE)
- if (qla4xxx_add_sess(ddb_entry))
- goto remove_host;
- }
-
printk(KERN_INFO
" QLogic iSCSI HBA Driver version: %s\n"
" QLogic ISP%04x @ %s, host#=%ld, fw=%02d.%02d.%02d.%02d\n",
@@ -1311,10 +1319,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
scsi_scan_host(host);
return 0;
-remove_host:
- qla4xxx_free_ddb_list(ha);
- scsi_remove_host(host);
-
probe_failed:
qla4xxx_free_adapter(ha);
scsi_host_put(ha->host);
@@ -1600,9 +1604,12 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
return FAILED;
}
- if (qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST) == QLA_SUCCESS) {
+ /* make sure the dpc thread is stopped while we reset the hba */
+ clear_bit(AF_ONLINE, &ha->flags);
+ flush_workqueue(ha->dpc_thread);
+
+ if (qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST) == QLA_SUCCESS)
return_status = SUCCESS;
- }
dev_info(&ha->pdev->dev, "HOST RESET %s.\n",
return_status == FAILED ? "FAILED" : "SUCCEDED");
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index 65455ab1f3b..4a1cf6377f6 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -651,7 +651,7 @@ static int qlogicpti_verify_tmon(struct qlogicpti *qpti)
static irqreturn_t qpti_intr(int irq, void *dev_id);
-static void __init qpti_chain_add(struct qlogicpti *qpti)
+static void __devinit qpti_chain_add(struct qlogicpti *qpti)
{
spin_lock_irq(&qptichain_lock);
if (qptichain != NULL) {
@@ -667,7 +667,7 @@ static void __init qpti_chain_add(struct qlogicpti *qpti)
spin_unlock_irq(&qptichain_lock);
}
-static void __init qpti_chain_del(struct qlogicpti *qpti)
+static void __devexit qpti_chain_del(struct qlogicpti *qpti)
{
spin_lock_irq(&qptichain_lock);
if (qptichain == qpti) {
@@ -682,7 +682,7 @@ static void __init qpti_chain_del(struct qlogicpti *qpti)
spin_unlock_irq(&qptichain_lock);
}
-static int __init qpti_map_regs(struct qlogicpti *qpti)
+static int __devinit qpti_map_regs(struct qlogicpti *qpti)
{
struct sbus_dev *sdev = qpti->sdev;
@@ -705,7 +705,7 @@ static int __init qpti_map_regs(struct qlogicpti *qpti)
return 0;
}
-static int __init qpti_register_irq(struct qlogicpti *qpti)
+static int __devinit qpti_register_irq(struct qlogicpti *qpti)
{
struct sbus_dev *sdev = qpti->sdev;
@@ -730,7 +730,7 @@ fail:
return -1;
}
-static void __init qpti_get_scsi_id(struct qlogicpti *qpti)
+static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti)
{
qpti->scsi_id = prom_getintdefault(qpti->prom_node,
"initiator-id",
@@ -783,7 +783,7 @@ static void qpti_get_clock(struct qlogicpti *qpti)
/* The request and response queues must each be aligned
* on a page boundary.
*/
-static int __init qpti_map_queues(struct qlogicpti *qpti)
+static int __devinit qpti_map_queues(struct qlogicpti *qpti)
{
struct sbus_dev *sdev = qpti->sdev;
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index fecba05b4e7..e5c6f6af876 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -757,7 +757,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
"Notifying upper driver of completion "
"(result %x)\n", cmd->result));
- good_bytes = scsi_bufflen(cmd);
+ good_bytes = scsi_bufflen(cmd) + cmd->request->extra_len;
if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) {
drv = scsi_cmd_to_driver(cmd);
if (drv->done)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 1541c174937..d1777a9a962 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -222,7 +222,7 @@ static struct scsi_host_template sdebug_driver_template = {
.cmd_per_lun = 16,
.max_sectors = 0xffff,
.unchecked_isa_dma = 0,
- .use_clustering = ENABLE_CLUSTERING,
+ .use_clustering = DISABLE_CLUSTERING,
.module = THIS_MODULE,
};
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 135c1d05470..ba21d97d185 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1014,10 +1014,6 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
}
req->buffer = NULL;
- if (blk_pc_request(req))
- sdb->length = req->data_len;
- else
- sdb->length = req->nr_sectors << 9;
/*
* Next, walk the list, and fill in the addresses and sizes of
@@ -1026,6 +1022,10 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
count = blk_rq_map_sg(req->q, req, sdb->table.sgl);
BUG_ON(count > sdb->table.nents);
sdb->table.nents = count;
+ if (blk_pc_request(req))
+ sdb->length = req->data_len;
+ else
+ sdb->length = req->nr_sectors << 9;
return BLKPREP_OK;
}
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 1dc165ad17f..e67c14e31ba 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1577,8 +1577,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
}
/**
- * scsi_scan_target - scan a target id, possibly including all LUNs on the
- * target.
+ * scsi_scan_target - scan a target id, possibly including all LUNs on the target.
* @parent: host to scan
* @channel: channel to scan
* @id: target id to scan
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 3677fbb30b7..a0f308bd145 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -103,7 +103,6 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost,
if (!cmd)
goto release_rq;
- memset(cmd, 0, sizeof(*cmd));
cmd->sc_data_direction = data_dir;
cmd->jiffies_at_alloc = jiffies;
cmd->request = rq;
@@ -382,6 +381,11 @@ static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd,
scsi_release_buffers(cmd);
goto unmap_rq;
}
+ /*
+ * we use REQ_TYPE_BLOCK_PC so scsi_init_io doesn't set the
+ * length for us.
+ */
+ cmd->sdb.length = rq->data_len;
return 0;
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index fac7534f3ec..ca7bb6f63bd 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -33,7 +33,7 @@
#define ISCSI_SESSION_ATTRS 19
#define ISCSI_CONN_ATTRS 13
#define ISCSI_HOST_ATTRS 4
-#define ISCSI_TRANSPORT_VERSION "2.0-868"
+#define ISCSI_TRANSPORT_VERSION "2.0-869"
struct iscsi_internal {
int daemon_pid;
@@ -231,7 +231,7 @@ static struct {
{ ISCSI_SESSION_FREE, "FREE" },
};
-const char *iscsi_session_state_name(int state)
+static const char *iscsi_session_state_name(int state)
{
int i;
char *name = NULL;
@@ -373,24 +373,25 @@ static void session_recovery_timedout(struct work_struct *work)
scsi_target_unblock(&session->dev);
}
-void __iscsi_unblock_session(struct iscsi_cls_session *session)
-{
- if (!cancel_delayed_work(&session->recovery_work))
- flush_workqueue(iscsi_eh_timer_workq);
- scsi_target_unblock(&session->dev);
-}
-
-void iscsi_unblock_session(struct iscsi_cls_session *session)
+static void __iscsi_unblock_session(struct work_struct *work)
{
+ struct iscsi_cls_session *session =
+ container_of(work, struct iscsi_cls_session,
+ unblock_work);
struct Scsi_Host *shost = iscsi_session_to_shost(session);
struct iscsi_host *ihost = shost->shost_data;
unsigned long flags;
+ /*
+ * The recovery and unblock work get run from the same workqueue,
+ * so try to cancel it if it was going to run after this unblock.
+ */
+ cancel_delayed_work(&session->recovery_work);
spin_lock_irqsave(&session->lock, flags);
session->state = ISCSI_SESSION_LOGGED_IN;
spin_unlock_irqrestore(&session->lock, flags);
-
- __iscsi_unblock_session(session);
+ /* start IO */
+ scsi_target_unblock(&session->dev);
/*
* Only do kernel scanning if the driver is properly hooked into
* the async scanning code (drivers like iscsi_tcp do login and
@@ -401,20 +402,43 @@ void iscsi_unblock_session(struct iscsi_cls_session *session)
atomic_inc(&ihost->nr_scans);
}
}
+
+/**
+ * iscsi_unblock_session - set a session as logged in and start IO.
+ * @session: iscsi session
+ *
+ * Mark a session as ready to accept IO.
+ */
+void iscsi_unblock_session(struct iscsi_cls_session *session)
+{
+ queue_work(iscsi_eh_timer_workq, &session->unblock_work);
+ /*
+ * make sure all the events have completed before tell the driver
+ * it is safe
+ */
+ flush_workqueue(iscsi_eh_timer_workq);
+}
EXPORT_SYMBOL_GPL(iscsi_unblock_session);
-void iscsi_block_session(struct iscsi_cls_session *session)
+static void __iscsi_block_session(struct work_struct *work)
{
+ struct iscsi_cls_session *session =
+ container_of(work, struct iscsi_cls_session,
+ block_work);
unsigned long flags;
spin_lock_irqsave(&session->lock, flags);
session->state = ISCSI_SESSION_FAILED;
spin_unlock_irqrestore(&session->lock, flags);
-
scsi_target_block(&session->dev);
queue_delayed_work(iscsi_eh_timer_workq, &session->recovery_work,
session->recovery_tmo * HZ);
}
+
+void iscsi_block_session(struct iscsi_cls_session *session)
+{
+ queue_work(iscsi_eh_timer_workq, &session->block_work);
+}
EXPORT_SYMBOL_GPL(iscsi_block_session);
static void __iscsi_unbind_session(struct work_struct *work)
@@ -463,6 +487,8 @@ iscsi_alloc_session(struct Scsi_Host *shost,
INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout);
INIT_LIST_HEAD(&session->host_list);
INIT_LIST_HEAD(&session->sess_list);
+ INIT_WORK(&session->unblock_work, __iscsi_unblock_session);
+ INIT_WORK(&session->block_work, __iscsi_block_session);
INIT_WORK(&session->unbind_work, __iscsi_unbind_session);
INIT_WORK(&session->scan_work, iscsi_scan_session);
spin_lock_init(&session->lock);
@@ -575,24 +601,25 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
list_del(&session->sess_list);
spin_unlock_irqrestore(&sesslock, flags);
+ /* make sure there are no blocks/unblocks queued */
+ flush_workqueue(iscsi_eh_timer_workq);
+ /* make sure the timedout callout is not running */
+ if (!cancel_delayed_work(&session->recovery_work))
+ flush_workqueue(iscsi_eh_timer_workq);
/*
* If we are blocked let commands flow again. The lld or iscsi
* layer should set up the queuecommand to fail commands.
+ * We assume that LLD will not be calling block/unblock while
+ * removing the session.
*/
spin_lock_irqsave(&session->lock, flags);
session->state = ISCSI_SESSION_FREE;
spin_unlock_irqrestore(&session->lock, flags);
- __iscsi_unblock_session(session);
- __iscsi_unbind_session(&session->unbind_work);
- /* flush running scans */
+ scsi_target_unblock(&session->dev);
+ /* flush running scans then delete devices */
flush_workqueue(ihost->scan_workq);
- /*
- * If the session dropped while removing devices then we need to make
- * sure it is not blocked
- */
- if (!cancel_delayed_work(&session->recovery_work))
- flush_workqueue(iscsi_eh_timer_workq);
+ __iscsi_unbind_session(&session->unbind_work);
/* hw iscsi may not have removed all connections from session */
err = device_for_each_child(&session->dev, NULL,
@@ -802,23 +829,16 @@ EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
{
- struct iscsi_cls_session *session = iscsi_conn_to_session(conn);
struct nlmsghdr *nlh;
struct sk_buff *skb;
struct iscsi_uevent *ev;
struct iscsi_internal *priv;
int len = NLMSG_SPACE(sizeof(*ev));
- unsigned long flags;
priv = iscsi_if_transport_lookup(conn->transport);
if (!priv)
return;
- spin_lock_irqsave(&session->lock, flags);
- if (session->state == ISCSI_SESSION_LOGGED_IN)
- session->state = ISCSI_SESSION_FAILED;
- spin_unlock_irqrestore(&session->lock, flags);
-
skb = alloc_skb(len, GFP_ATOMIC);
if (!skb) {
iscsi_cls_conn_printk(KERN_ERR, conn, "gracefully ignored "
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 37df8bbe7f4..7aee64dbfbe 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1835,8 +1835,7 @@ static int sd_suspend(struct device *dev, pm_message_t mesg)
goto done;
}
- if (mesg.event == PM_EVENT_SUSPEND &&
- sdkp->device->manage_start_stop) {
+ if ((mesg.event & PM_EVENT_SLEEP) && sdkp->device->manage_start_stop) {
sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
ret = sd_start_stop_device(sdkp, 0);
}
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index a57fed47b39..a6d96694d0a 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -33,9 +33,9 @@
#include <scsi/scsi_host.h>
struct ses_device {
- char *page1;
- char *page2;
- char *page10;
+ unsigned char *page1;
+ unsigned char *page2;
+ unsigned char *page10;
short page1_len;
short page2_len;
short page10_len;
@@ -67,7 +67,7 @@ static int ses_probe(struct device *dev)
static int ses_recv_diag(struct scsi_device *sdev, int page_code,
void *buf, int bufflen)
{
- char cmd[] = {
+ unsigned char cmd[] = {
RECEIVE_DIAGNOSTIC,
1, /* Set PCV bit */
page_code,
@@ -85,7 +85,7 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code,
{
u32 result;
- char cmd[] = {
+ unsigned char cmd[] = {
SEND_DIAGNOSTIC,
0x10, /* Set PF bit */
0,
@@ -104,13 +104,13 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code,
static int ses_set_page2_descriptor(struct enclosure_device *edev,
struct enclosure_component *ecomp,
- char *desc)
+ unsigned char *desc)
{
int i, j, count = 0, descriptor = ecomp->number;
struct scsi_device *sdev = to_scsi_device(edev->cdev.dev);
struct ses_device *ses_dev = edev->scratch;
- char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
- char *desc_ptr = ses_dev->page2 + 8;
+ unsigned char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
+ unsigned char *desc_ptr = ses_dev->page2 + 8;
/* Clear everything */
memset(desc_ptr, 0, ses_dev->page2_len - 8);
@@ -133,14 +133,14 @@ static int ses_set_page2_descriptor(struct enclosure_device *edev,
return ses_send_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len);
}
-static char *ses_get_page2_descriptor(struct enclosure_device *edev,
+static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev,
struct enclosure_component *ecomp)
{
int i, j, count = 0, descriptor = ecomp->number;
struct scsi_device *sdev = to_scsi_device(edev->cdev.dev);
struct ses_device *ses_dev = edev->scratch;
- char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
- char *desc_ptr = ses_dev->page2 + 8;
+ unsigned char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
+ unsigned char *desc_ptr = ses_dev->page2 + 8;
ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len);
@@ -160,17 +160,18 @@ static char *ses_get_page2_descriptor(struct enclosure_device *edev,
static void ses_get_fault(struct enclosure_device *edev,
struct enclosure_component *ecomp)
{
- char *desc;
+ unsigned char *desc;
desc = ses_get_page2_descriptor(edev, ecomp);
- ecomp->fault = (desc[3] & 0x60) >> 4;
+ if (desc)
+ ecomp->fault = (desc[3] & 0x60) >> 4;
}
static int ses_set_fault(struct enclosure_device *edev,
struct enclosure_component *ecomp,
enum enclosure_component_setting val)
{
- char desc[4] = {0 };
+ unsigned char desc[4] = {0 };
switch (val) {
case ENCLOSURE_SETTING_DISABLED:
@@ -190,26 +191,28 @@ static int ses_set_fault(struct enclosure_device *edev,
static void ses_get_status(struct enclosure_device *edev,
struct enclosure_component *ecomp)
{
- char *desc;
+ unsigned char *desc;
desc = ses_get_page2_descriptor(edev, ecomp);
- ecomp->status = (desc[0] & 0x0f);
+ if (desc)
+ ecomp->status = (desc[0] & 0x0f);
}
static void ses_get_locate(struct enclosure_device *edev,
struct enclosure_component *ecomp)
{
- char *desc;
+ unsigned char *desc;
desc = ses_get_page2_descriptor(edev, ecomp);
- ecomp->locate = (desc[2] & 0x02) ? 1 : 0;
+ if (desc)
+ ecomp->locate = (desc[2] & 0x02) ? 1 : 0;
}
static int ses_set_locate(struct enclosure_device *edev,
struct enclosure_component *ecomp,
enum enclosure_component_setting val)
{
- char desc[4] = {0 };
+ unsigned char desc[4] = {0 };
switch (val) {
case ENCLOSURE_SETTING_DISABLED:
@@ -229,7 +232,7 @@ static int ses_set_active(struct enclosure_device *edev,
struct enclosure_component *ecomp,
enum enclosure_component_setting val)
{
- char desc[4] = {0 };
+ unsigned char desc[4] = {0 };
switch (val) {
case ENCLOSURE_SETTING_DISABLED:
@@ -409,11 +412,11 @@ static int ses_intf_add(struct class_device *cdev,
{
struct scsi_device *sdev = to_scsi_device(cdev->dev);
struct scsi_device *tmp_sdev;
- unsigned char *buf = NULL, *hdr_buf, *type_ptr, *desc_ptr,
- *addl_desc_ptr;
+ unsigned char *buf = NULL, *hdr_buf, *type_ptr, *desc_ptr = NULL,
+ *addl_desc_ptr = NULL;
struct ses_device *ses_dev;
u32 result;
- int i, j, types, len, components = 0;
+ int i, j, types, len, page7_len = 0, components = 0;
int err = -ENOMEM;
struct enclosure_device *edev;
struct ses_component *scomp = NULL;
@@ -447,7 +450,7 @@ static int ses_intf_add(struct class_device *cdev,
* traversal routines more complex */
sdev_printk(KERN_ERR, sdev,
"FIXME driver has no support for subenclosures (%d)\n",
- buf[1]);
+ hdr_buf[1]);
goto err_free;
}
@@ -461,9 +464,8 @@ static int ses_intf_add(struct class_device *cdev,
goto recv_failed;
types = buf[10];
- len = buf[11];
- type_ptr = buf + 12 + len;
+ type_ptr = buf + 12 + buf[11];
for (i = 0; i < types; i++, type_ptr += 4) {
if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
@@ -494,22 +496,21 @@ static int ses_intf_add(struct class_device *cdev,
/* The additional information page --- allows us
* to match up the devices */
result = ses_recv_diag(sdev, 10, hdr_buf, INIT_ALLOC_SIZE);
- if (result)
- goto no_page10;
-
- len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
- buf = kzalloc(len, GFP_KERNEL);
- if (!buf)
- goto err_free;
-
- result = ses_recv_diag(sdev, 10, buf, len);
- if (result)
- goto recv_failed;
- ses_dev->page10 = buf;
- ses_dev->page10_len = len;
- buf = NULL;
+ if (!result) {
+
+ len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
+ buf = kzalloc(len, GFP_KERNEL);
+ if (!buf)
+ goto err_free;
+
+ result = ses_recv_diag(sdev, 10, buf, len);
+ if (result)
+ goto recv_failed;
+ ses_dev->page10 = buf;
+ ses_dev->page10_len = len;
+ buf = NULL;
+ }
- no_page10:
scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL);
if (!scomp)
goto err_free;
@@ -530,7 +531,7 @@ static int ses_intf_add(struct class_device *cdev,
if (result)
goto simple_populate;
- len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
+ page7_len = len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
/* add 1 for trailing '\0' we'll use */
buf = kzalloc(len + 1, GFP_KERNEL);
if (!buf)
@@ -547,7 +548,8 @@ static int ses_intf_add(struct class_device *cdev,
len = (desc_ptr[2] << 8) + desc_ptr[3];
/* skip past overall descriptor */
desc_ptr += len + 4;
- addl_desc_ptr = ses_dev->page10 + 8;
+ if (ses_dev->page10)
+ addl_desc_ptr = ses_dev->page10 + 8;
}
type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
components = 0;
@@ -557,29 +559,35 @@ static int ses_intf_add(struct class_device *cdev,
struct enclosure_component *ecomp;
if (desc_ptr) {
- len = (desc_ptr[2] << 8) + desc_ptr[3];
- desc_ptr += 4;
- /* Add trailing zero - pushes into
- * reserved space */
- desc_ptr[len] = '\0';
- name = desc_ptr;
+ if (desc_ptr >= buf + page7_len) {
+ desc_ptr = NULL;
+ } else {
+ len = (desc_ptr[2] << 8) + desc_ptr[3];
+ desc_ptr += 4;
+ /* Add trailing zero - pushes into
+ * reserved space */
+ desc_ptr[len] = '\0';
+ name = desc_ptr;
+ }
}
- if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE &&
- type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE)
- continue;
- ecomp = enclosure_component_register(edev,
+ if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
+ type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) {
+
+ ecomp = enclosure_component_register(edev,
components++,
type_ptr[0],
name);
- if (desc_ptr) {
- desc_ptr += len;
- if (!IS_ERR(ecomp))
+
+ if (!IS_ERR(ecomp) && addl_desc_ptr)
ses_process_descriptor(ecomp,
addl_desc_ptr);
-
- if (addl_desc_ptr)
- addl_desc_ptr += addl_desc_ptr[1] + 2;
}
+ if (desc_ptr)
+ desc_ptr += len;
+
+ if (addl_desc_ptr)
+ addl_desc_ptr += addl_desc_ptr[1] + 2;
+
}
}
kfree(buf);
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 71952703125..0a52d9d2da2 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -17,7 +17,7 @@
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
*/
-static const char *verstr = "20080117";
+static const char *verstr = "20080221";
#include <linux/module.h>
@@ -1172,7 +1172,7 @@ static int st_open(struct inode *inode, struct file *filp)
STp->try_dio_now = STp->try_dio;
STp->recover_count = 0;
DEB( STp->nbr_waits = STp->nbr_finished = 0;
- STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = STp->nbr_combinable = 0; )
+ STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
retval = check_tape(STp, filp);
if (retval < 0)
@@ -1226,8 +1226,8 @@ static int st_flush(struct file *filp, fl_owner_t id)
}
DEBC( if (STp->nbr_requests)
- printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n",
- name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable));
+ printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
+ name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
if (STps->rw == ST_WRITING && !STp->pos_unknown) {
struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
@@ -1422,9 +1422,6 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
if (STbp->do_dio) {
STp->nbr_dio++;
STp->nbr_pages += STbp->do_dio;
- for (i=1; i < STbp->do_dio; i++)
- if (page_to_pfn(STbp->sg[i].page) == page_to_pfn(STbp->sg[i-1].page) + 1)
- STp->nbr_combinable++;
}
)
} else
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index 6c807571297..5931726fcf9 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -164,7 +164,6 @@ struct scsi_tape {
int nbr_requests;
int nbr_dio;
int nbr_pages;
- int nbr_combinable;
unsigned char last_cmnd[6];
unsigned char last_sense[16];
#endif
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 72f6d801535..654430edf74 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -461,30 +461,14 @@ static void stex_internal_copy(struct scsi_cmnd *cmd,
}
}
-static int stex_direct_copy(struct scsi_cmnd *cmd,
- const void *src, size_t count)
-{
- size_t cp_len = count;
- int n_elem = 0;
-
- n_elem = scsi_dma_map(cmd);
- if (n_elem < 0)
- return 0;
-
- stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD);
-
- scsi_dma_unmap(cmd);
-
- return cp_len == count;
-}
-
static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
{
struct st_frame *p;
size_t count = sizeof(struct st_frame);
p = hba->copy_buffer;
- stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_FROM_CMD);
+ stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd),
+ ST_FROM_CMD);
memset(p->base, 0, sizeof(u32)*6);
*(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0);
p->rom_addr = 0;
@@ -502,7 +486,8 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
p->subid =
hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
- stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_TO_CMD);
+ stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd),
+ ST_TO_CMD);
}
static void
@@ -569,8 +554,10 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
unsigned char page;
page = cmd->cmnd[2] & 0x3f;
if (page == 0x8 || page == 0x3f) {
- stex_direct_copy(cmd, ms10_caching_page,
- sizeof(ms10_caching_page));
+ size_t cp_len = sizeof(ms10_caching_page);
+ stex_internal_copy(cmd, ms10_caching_page,
+ &cp_len, scsi_sg_count(cmd),
+ ST_TO_CMD);
cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
done(cmd);
} else
@@ -599,8 +586,10 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
if (id != host->max_id - 1)
break;
if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
- stex_direct_copy(cmd, console_inq_page,
- sizeof(console_inq_page));
+ size_t cp_len = sizeof(console_inq_page);
+ stex_internal_copy(cmd, console_inq_page,
+ &cp_len, scsi_sg_count(cmd),
+ ST_TO_CMD);
cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
done(cmd);
} else
@@ -609,6 +598,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
case PASSTHRU_CMD:
if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) {
struct st_drvver ver;
+ size_t cp_len = sizeof(ver);
ver.major = ST_VER_MAJOR;
ver.minor = ST_VER_MINOR;
ver.oem = ST_OEM;
@@ -616,7 +606,9 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
ver.signature[0] = PASSTHRU_SIGNATURE;
ver.console_id = host->max_id - 1;
ver.host_no = hba->host->host_no;
- cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ?
+ stex_internal_copy(cmd, &ver, &cp_len,
+ scsi_sg_count(cmd), ST_TO_CMD);
+ cmd->result = sizeof(ver) == cp_len ?
DID_OK << 16 | COMMAND_COMPLETE << 8 :
DID_ERROR << 16 | COMMAND_COMPLETE << 8;
done(cmd);
@@ -709,7 +701,7 @@ static void stex_copy_data(struct st_ccb *ccb,
if (ccb->cmd == NULL)
return;
stex_internal_copy(ccb->cmd,
- resp->variable, &count, ccb->sg_count, ST_TO_CMD);
+ resp->variable, &count, scsi_sg_count(ccb->cmd), ST_TO_CMD);
}
static void stex_ys_commands(struct st_hba *hba,
@@ -734,7 +726,7 @@ static void stex_ys_commands(struct st_hba *hba,
count = STEX_EXTRA_SIZE;
stex_internal_copy(ccb->cmd, hba->copy_buffer,
- &count, ccb->sg_count, ST_FROM_CMD);
+ &count, scsi_sg_count(ccb->cmd), ST_FROM_CMD);
inq_data = (ST_INQ *)hba->copy_buffer;
if (inq_data->DeviceTypeQualifier != 0)
ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 6f09cbd7fc4..97c68d021d2 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -91,6 +91,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
/* Archtek America Corp. */
/* Archtek SmartLink Modem 3334BT Plug & Play */
{ "GVC000F", 0 },
+ /* Archtek SmartLink Modem 3334BRV 33.6K Data Fax Voice */
+ { "GVC0303", 0 },
/* Hayes */
/* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
{ "HAY0001", 0 },
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b82595cf13e..cf627cd1b4c 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -686,7 +686,7 @@ config UART0_RTS_PIN
config SERIAL_BFIN_UART1
bool "Enable UART1"
- depends on SERIAL_BFIN && (BF534 || BF536 || BF537 || BF54x)
+ depends on SERIAL_BFIN && (!BF531 && !BF532 && !BF533 && !BF561)
help
Enable UART1
@@ -699,14 +699,14 @@ config BFIN_UART1_CTSRTS
config UART1_CTS_PIN
int "UART1 CTS pin"
- depends on BFIN_UART1_CTSRTS && (BF53x || BF561)
+ depends on BFIN_UART1_CTSRTS && !BF54x
default -1
help
Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
config UART1_RTS_PIN
int "UART1 RTS pin"
- depends on BFIN_UART1_CTSRTS && (BF53x || BF561)
+ depends on BFIN_UART1_CTSRTS && !BF54x
default -1
help
Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index fad245b064d..d57bf3e708d 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -549,7 +549,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
atmel_handle_transmit(port, pending);
} while (pass_counter++ < ATMEL_ISR_PASS_LIMIT);
- return IRQ_HANDLED;
+ return pass_counter ? IRQ_HANDLED : IRQ_NONE;
}
/*
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index ac2a3ef28d5..0aa345b9a38 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -1,30 +1,11 @@
/*
- * File: drivers/serial/bfin_5xx.c
- * Based on: Based on drivers/serial/sa1100.c
- * Author: Aubrey Li <aubrey.li@analog.com>
+ * Blackfin On-Chip Serial Driver
*
- * Created:
- * Description: Driver for blackfin 5xx serial ports
+ * Copyright 2006-2007 Analog Devices Inc.
*
- * Modified:
- * Copyright 2006 Analog Devices Inc.
+ * Enter bugs at http://blackfin.uclinux.org/
*
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#if defined(CONFIG_SERIAL_BFIN_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -67,14 +48,12 @@
#define DMA_RX_XCOUNT 512
#define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT)
-#define DMA_RX_FLUSH_JIFFIES 5
+#define DMA_RX_FLUSH_JIFFIES (HZ / 50)
#ifdef CONFIG_SERIAL_BFIN_DMA
static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart);
#else
-static void bfin_serial_do_work(struct work_struct *work);
static void bfin_serial_tx_chars(struct bfin_serial_port *uart);
-static void local_put_char(struct bfin_serial_port *uart, char ch);
#endif
static void bfin_serial_mctrl_check(struct bfin_serial_port *uart);
@@ -85,23 +64,26 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart);
static void bfin_serial_stop_tx(struct uart_port *port)
{
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ struct circ_buf *xmit = &uart->port.info->xmit;
+#if !defined(CONFIG_BF54x) && !defined(CONFIG_SERIAL_BFIN_DMA)
+ unsigned short ier;
+#endif
while (!(UART_GET_LSR(uart) & TEMT))
- continue;
+ cpu_relax();
#ifdef CONFIG_SERIAL_BFIN_DMA
disable_dma(uart->tx_dma_channel);
+ xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1);
+ uart->port.icount.tx += uart->tx_count;
+ uart->tx_count = 0;
+ uart->tx_done = 1;
#else
#ifdef CONFIG_BF54x
- /* Waiting for Transmission Finished */
- while (!(UART_GET_LSR(uart) & TFI))
- continue;
/* Clear TFI bit */
UART_PUT_LSR(uart, TFI);
UART_CLEAR_IER(uart, ETBEI);
#else
- unsigned short ier;
-
ier = UART_GET_IER(uart);
ier &= ~ETBEI;
UART_PUT_IER(uart, ier);
@@ -117,7 +99,8 @@ static void bfin_serial_start_tx(struct uart_port *port)
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
#ifdef CONFIG_SERIAL_BFIN_DMA
- bfin_serial_dma_tx_chars(uart);
+ if (uart->tx_done)
+ bfin_serial_dma_tx_chars(uart);
#else
#ifdef CONFIG_BF54x
UART_SET_IER(uart, ETBEI);
@@ -209,34 +192,27 @@ int kgdb_get_debug_char(void)
}
#endif
-#ifdef CONFIG_SERIAL_BFIN_PIO
-static void local_put_char(struct bfin_serial_port *uart, char ch)
-{
- unsigned short status;
- int flags = 0;
-
- spin_lock_irqsave(&uart->port.lock, flags);
-
- do {
- status = UART_GET_LSR(uart);
- } while (!(status & THRE));
-
- UART_PUT_CHAR(uart, ch);
- SSYNC();
-
- spin_unlock_irqrestore(&uart->port.lock, flags);
-}
+#if ANOMALY_05000230 && defined(CONFIG_SERIAL_BFIN_PIO)
+# define UART_GET_ANOMALY_THRESHOLD(uart) ((uart)->anomaly_threshold)
+# define UART_SET_ANOMALY_THRESHOLD(uart, v) ((uart)->anomaly_threshold = (v))
+#else
+# define UART_GET_ANOMALY_THRESHOLD(uart) 0
+# define UART_SET_ANOMALY_THRESHOLD(uart, v)
+#endif
+#ifdef CONFIG_SERIAL_BFIN_PIO
static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
{
struct tty_struct *tty = uart->port.info->tty;
unsigned int status, ch, flg;
- static int in_break = 0;
+ static struct timeval anomaly_start = { .tv_sec = 0 };
#ifdef CONFIG_KGDB_UART
struct pt_regs *regs = get_irq_regs();
#endif
status = UART_GET_LSR(uart);
+ UART_CLEAR_LSR(uart);
+
ch = UART_GET_CHAR(uart);
uart->port.icount.rx++;
@@ -262,28 +238,56 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
#endif
if (ANOMALY_05000230) {
- /* The BF533 family of processors have a nice misbehavior where
- * they continuously generate characters for a "single" break.
+ /* The BF533 (and BF561) family of processors have a nice anomaly
+ * where they continuously generate characters for a "single" break.
* We have to basically ignore this flood until the "next" valid
- * character comes across. All other Blackfin families operate
- * properly though.
+ * character comes across. Due to the nature of the flood, it is
+ * not possible to reliably catch bytes that are sent too quickly
+ * after this break. So application code talking to the Blackfin
+ * which sends a break signal must allow at least 1.5 character
+ * times after the end of the break for things to stabilize. This
+ * timeout was picked as it must absolutely be larger than 1
+ * character time +/- some percent. So 1.5 sounds good. All other
+ * Blackfin families operate properly. Woo.
* Note: While Anomaly 05000230 does not directly address this,
* the changes that went in for it also fixed this issue.
+ * That anomaly was fixed in 0.5+ silicon. I like bunnies.
*/
- if (in_break) {
- if (ch != 0) {
- in_break = 0;
- ch = UART_GET_CHAR(uart);
- if (bfin_revid() < 5)
- return;
- } else
- return;
+ if (anomaly_start.tv_sec) {
+ struct timeval curr;
+ suseconds_t usecs;
+
+ if ((~ch & (~ch + 1)) & 0xff)
+ goto known_good_char;
+
+ do_gettimeofday(&curr);
+ if (curr.tv_sec - anomaly_start.tv_sec > 1)
+ goto known_good_char;
+
+ usecs = 0;
+ if (curr.tv_sec != anomaly_start.tv_sec)
+ usecs += USEC_PER_SEC;
+ usecs += curr.tv_usec - anomaly_start.tv_usec;
+
+ if (usecs > UART_GET_ANOMALY_THRESHOLD(uart))
+ goto known_good_char;
+
+ if (ch)
+ anomaly_start.tv_sec = 0;
+ else
+ anomaly_start = curr;
+
+ return;
+
+ known_good_char:
+ anomaly_start.tv_sec = 0;
}
}
if (status & BI) {
if (ANOMALY_05000230)
- in_break = 1;
+ if (bfin_revid() < 5)
+ do_gettimeofday(&anomaly_start);
uart->port.icount.brk++;
if (uart_handle_break(&uart->port))
goto ignore_char;
@@ -324,7 +328,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
UART_PUT_CHAR(uart, uart->port.x_char);
uart->port.icount.tx++;
uart->port.x_char = 0;
- return;
}
/*
* Check the modem control lines before
@@ -337,9 +340,12 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
return;
}
- local_put_char(uart, xmit->buf[xmit->tail]);
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- uart->port.icount.tx++;
+ while ((UART_GET_LSR(uart) & THRE) && xmit->tail != xmit->head) {
+ UART_PUT_CHAR(uart, xmit->buf[xmit->tail]);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ uart->port.icount.tx++;
+ SSYNC();
+ }
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&uart->port);
@@ -352,21 +358,11 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id)
{
struct bfin_serial_port *uart = dev_id;
-#ifdef CONFIG_BF54x
- unsigned short status;
- spin_lock(&uart->port.lock);
- status = UART_GET_LSR(uart);
- while ((UART_GET_IER(uart) & ERBFI) && (status & DR)) {
- bfin_serial_rx_chars(uart);
- status = UART_GET_LSR(uart);
- }
- spin_unlock(&uart->port.lock);
-#else
spin_lock(&uart->port.lock);
- while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY)
+ while (UART_GET_LSR(uart) & DR)
bfin_serial_rx_chars(uart);
spin_unlock(&uart->port.lock);
-#endif
+
return IRQ_HANDLED;
}
@@ -374,25 +370,16 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
{
struct bfin_serial_port *uart = dev_id;
-#ifdef CONFIG_BF54x
- unsigned short status;
spin_lock(&uart->port.lock);
- status = UART_GET_LSR(uart);
- while ((UART_GET_IER(uart) & ETBEI) && (status & THRE)) {
+ if (UART_GET_LSR(uart) & THRE)
bfin_serial_tx_chars(uart);
- status = UART_GET_LSR(uart);
- }
spin_unlock(&uart->port.lock);
-#else
- spin_lock(&uart->port.lock);
- while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY)
- bfin_serial_tx_chars(uart);
- spin_unlock(&uart->port.lock);
-#endif
+
return IRQ_HANDLED;
}
+#endif
-
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
static void bfin_serial_do_work(struct work_struct *work)
{
struct bfin_serial_port *uart = container_of(work, struct bfin_serial_port, cts_workqueue);
@@ -406,33 +393,27 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
{
struct circ_buf *xmit = &uart->port.info->xmit;
unsigned short ier;
- int flags = 0;
-
- if (!uart->tx_done)
- return;
uart->tx_done = 0;
+ if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
+ uart->tx_count = 0;
+ uart->tx_done = 1;
+ return;
+ }
+
if (uart->port.x_char) {
UART_PUT_CHAR(uart, uart->port.x_char);
uart->port.icount.tx++;
uart->port.x_char = 0;
- uart->tx_done = 1;
- return;
}
+
/*
* Check the modem control lines before
* transmitting anything.
*/
bfin_serial_mctrl_check(uart);
- if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
- bfin_serial_stop_tx(&uart->port);
- uart->tx_done = 1;
- return;
- }
-
- spin_lock_irqsave(&uart->port.lock, flags);
uart->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE);
if (uart->tx_count > (UART_XMIT_SIZE - xmit->tail))
uart->tx_count = UART_XMIT_SIZE - xmit->tail;
@@ -448,6 +429,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
set_dma_x_count(uart->tx_dma_channel, uart->tx_count);
set_dma_x_modify(uart->tx_dma_channel, 1);
enable_dma(uart->tx_dma_channel);
+
#ifdef CONFIG_BF54x
UART_SET_IER(uart, ETBEI);
#else
@@ -455,7 +437,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
ier |= ETBEI;
UART_PUT_IER(uart, ier);
#endif
- spin_unlock_irqrestore(&uart->port.lock, flags);
}
static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
@@ -464,7 +445,11 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
int i, flg, status;
status = UART_GET_LSR(uart);
- uart->port.icount.rx += CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, UART_XMIT_SIZE);;
+ UART_CLEAR_LSR(uart);
+
+ uart->port.icount.rx +=
+ CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail,
+ UART_XMIT_SIZE);
if (status & BI) {
uart->port.icount.brk++;
@@ -490,10 +475,12 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
else
flg = TTY_NORMAL;
- for (i = uart->rx_dma_buf.head; i < uart->rx_dma_buf.tail; i++) {
- if (uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i]))
- goto dma_ignore_char;
- uart_insert_char(&uart->port, status, OE, uart->rx_dma_buf.buf[i], flg);
+ for (i = uart->rx_dma_buf.tail; i != uart->rx_dma_buf.head; i++) {
+ if (i >= UART_XMIT_SIZE)
+ i = 0;
+ if (!uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i]))
+ uart_insert_char(&uart->port, status, OE,
+ uart->rx_dma_buf.buf[i], flg);
}
dma_ignore_char:
@@ -503,23 +490,23 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
{
int x_pos, pos;
- int flags = 0;
-
- bfin_serial_dma_tx_chars(uart);
- spin_lock_irqsave(&uart->port.lock, flags);
- x_pos = DMA_RX_XCOUNT - get_dma_curr_xcount(uart->rx_dma_channel);
+ uart->rx_dma_nrows = get_dma_curr_ycount(uart->rx_dma_channel);
+ x_pos = get_dma_curr_xcount(uart->rx_dma_channel);
+ uart->rx_dma_nrows = DMA_RX_YCOUNT - uart->rx_dma_nrows;
+ if (uart->rx_dma_nrows == DMA_RX_YCOUNT)
+ uart->rx_dma_nrows = 0;
+ x_pos = DMA_RX_XCOUNT - x_pos;
if (x_pos == DMA_RX_XCOUNT)
x_pos = 0;
pos = uart->rx_dma_nrows * DMA_RX_XCOUNT + x_pos;
-
- if (pos>uart->rx_dma_buf.tail) {
- uart->rx_dma_buf.tail = pos;
+ if (pos != uart->rx_dma_buf.tail) {
+ uart->rx_dma_buf.head = pos;
bfin_serial_dma_rx_chars(uart);
- uart->rx_dma_buf.head = uart->rx_dma_buf.tail;
+ uart->rx_dma_buf.tail = uart->rx_dma_buf.head;
}
- spin_unlock_irqrestore(&uart->port.lock, flags);
+
uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
add_timer(&(uart->rx_dma_timer));
}
@@ -532,8 +519,8 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
spin_lock(&uart->port.lock);
if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
- clear_dma_irqstat(uart->tx_dma_channel);
disable_dma(uart->tx_dma_channel);
+ clear_dma_irqstat(uart->tx_dma_channel);
#ifdef CONFIG_BF54x
UART_CLEAR_IER(uart, ETBEI);
#else
@@ -541,15 +528,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
ier &= ~ETBEI;
UART_PUT_IER(uart, ier);
#endif
- xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1);
- uart->port.icount.tx+=uart->tx_count;
+ xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1);
+ uart->port.icount.tx += uart->tx_count;
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&uart->port);
- if (uart_circ_empty(xmit))
- bfin_serial_stop_tx(&uart->port);
- uart->tx_done = 1;
+ bfin_serial_dma_tx_chars(uart);
}
spin_unlock(&uart->port.lock);
@@ -561,18 +546,15 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id)
struct bfin_serial_port *uart = dev_id;
unsigned short irqstat;
- uart->rx_dma_nrows++;
- if (uart->rx_dma_nrows == DMA_RX_YCOUNT) {
- uart->rx_dma_nrows = 0;
- uart->rx_dma_buf.tail = DMA_RX_XCOUNT*DMA_RX_YCOUNT;
- bfin_serial_dma_rx_chars(uart);
- uart->rx_dma_buf.head = uart->rx_dma_buf.tail = 0;
- }
spin_lock(&uart->port.lock);
irqstat = get_dma_curr_irqstat(uart->rx_dma_channel);
clear_dma_irqstat(uart->rx_dma_channel);
-
spin_unlock(&uart->port.lock);
+
+ del_timer(&(uart->rx_dma_timer));
+ uart->rx_dma_timer.expires = jiffies;
+ add_timer(&(uart->rx_dma_timer));
+
return IRQ_HANDLED;
}
#endif
@@ -599,7 +581,11 @@ static unsigned int bfin_serial_get_mctrl(struct uart_port *port)
if (uart->cts_pin < 0)
return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+# ifdef BF54x
+ if (UART_GET_MSR(uart) & CTS)
+# else
if (gpio_get_value(uart->cts_pin))
+# endif
return TIOCM_DSR | TIOCM_CAR;
else
#endif
@@ -614,9 +600,17 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
return;
if (mctrl & TIOCM_RTS)
+# ifdef BF54x
+ UART_PUT_MCR(uart, UART_GET_MCR(uart) & ~MRTS);
+# else
gpio_set_value(uart->rts_pin, 0);
+# endif
else
+# ifdef BF54x
+ UART_PUT_MCR(uart, UART_GET_MCR(uart) | MRTS);
+# else
gpio_set_value(uart->rts_pin, 1);
+# endif
#endif
}
@@ -627,22 +621,17 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart)
{
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
unsigned int status;
-# ifdef CONFIG_SERIAL_BFIN_DMA
struct uart_info *info = uart->port.info;
struct tty_struct *tty = info->tty;
status = bfin_serial_get_mctrl(&uart->port);
+ uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
if (!(status & TIOCM_CTS)) {
tty->hw_stopped = 1;
+ schedule_work(&uart->cts_workqueue);
} else {
tty->hw_stopped = 0;
}
-# else
- status = bfin_serial_get_mctrl(&uart->port);
- uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
- if (!(status & TIOCM_CTS))
- schedule_work(&uart->cts_workqueue);
-# endif
#endif
}
@@ -743,6 +732,7 @@ static void bfin_serial_shutdown(struct uart_port *port)
disable_dma(uart->rx_dma_channel);
free_dma(uart->rx_dma_channel);
del_timer(&(uart->rx_dma_timer));
+ dma_free_coherent(NULL, PAGE_SIZE, uart->rx_dma_buf.buf, 0);
#else
#ifdef CONFIG_KGDB_UART
if (uart->port.line != CONFIG_KGDB_UART_PORT)
@@ -814,6 +804,8 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
quot = uart_get_divisor(port, baud);
spin_lock_irqsave(&uart->port.lock, flags);
+ UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
+
do {
lsr = UART_GET_LSR(uart);
} while (!(lsr & TEMT));
@@ -956,10 +948,9 @@ static void __init bfin_serial_init_ports(void)
bfin_serial_ports[i].rx_dma_channel =
bfin_serial_resource[i].uart_rx_dma_channel;
init_timer(&(bfin_serial_ports[i].rx_dma_timer));
-#else
- INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work);
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work);
bfin_serial_ports[i].cts_pin =
bfin_serial_resource[i].uart_cts_pin;
bfin_serial_ports[i].rts_pin =
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 348ee2c19b5..c2bb11c02bd 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -421,7 +421,7 @@ static void transmit_chars(struct uart_sio_port *up)
up->port.icount.tx++;
if (uart_circ_empty(xmit))
break;
- while (!serial_in(up, UART_LSR) & UART_LSR_THRE);
+ while (!(serial_in(up, UART_LSR) & UART_LSR_THRE));
} while (--count > 0);
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 9ce12cb2ceb..a8c116b80bf 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -41,6 +41,7 @@
#include <linux/delay.h>
#include <linux/console.h>
#include <linux/platform_device.h>
+#include <linux/serial_sci.h>
#ifdef CONFIG_CPU_FREQ
#include <linux/notifier.h>
@@ -54,7 +55,6 @@
#include <asm/kgdb.h>
#endif
-#include <asm/sci.h>
#include "sh-sci.h"
struct sci_port {
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index 9cfcfd8dad5..617efb1640b 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -1,7 +1,7 @@
/*
* Core maple bus functionality
*
- * Copyright (C) 2007 Adrian McMenamin
+ * Copyright (C) 2007, 2008 Adrian McMenamin
*
* Based on 2.4 code by:
*
@@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/device.h>
-#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/io.h>
@@ -54,7 +53,7 @@ static struct device maple_bus;
static int subdevice_map[MAPLE_PORTS];
static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr;
static unsigned long maple_pnp_time;
-static int started, scanning, liststatus, realscan;
+static int started, scanning, liststatus, fullscan;
static struct kmem_cache *maple_queue_cache;
struct maple_device_specify {
@@ -62,6 +61,9 @@ struct maple_device_specify {
int unit;
};
+static bool checked[4];
+static struct maple_device *baseunits[4];
+
/**
* maple_driver_register - register a device driver
* automatically makes the driver bus a maple bus
@@ -309,11 +311,9 @@ static void maple_attach_driver(struct maple_device *mdev)
else
break;
- if (realscan) {
- printk(KERN_INFO "Maple device detected: %s\n",
- mdev->product_name);
- printk(KERN_INFO "Maple device: %s\n", mdev->product_licence);
- }
+ printk(KERN_INFO "Maple device detected: %s\n",
+ mdev->product_name);
+ printk(KERN_INFO "Maple device: %s\n", mdev->product_licence);
function = be32_to_cpu(mdev->devinfo.function);
@@ -323,10 +323,9 @@ static void maple_attach_driver(struct maple_device *mdev)
mdev->driver = &maple_dummy_driver;
sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port);
} else {
- if (realscan)
- printk(KERN_INFO
- "Maple bus at (%d, %d): Function 0x%lX\n",
- mdev->port, mdev->unit, function);
+ printk(KERN_INFO
+ "Maple bus at (%d, %d): Function 0x%lX\n",
+ mdev->port, mdev->unit, function);
matched =
bus_for_each_drv(&maple_bus_type, NULL, mdev,
@@ -334,9 +333,8 @@ static void maple_attach_driver(struct maple_device *mdev)
if (matched == 0) {
/* Driver does not exist yet */
- if (realscan)
- printk(KERN_INFO
- "No maple driver found.\n");
+ printk(KERN_INFO
+ "No maple driver found.\n");
mdev->driver = &maple_dummy_driver;
}
sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port,
@@ -472,9 +470,12 @@ static void maple_response_none(struct maple_device *mdev,
maple_detach_driver(mdev);
return;
}
- if (!started) {
- printk(KERN_INFO "No maple devices attached to port %d\n",
- mdev->port);
+ if (!started || !fullscan) {
+ if (checked[mdev->port] == false) {
+ checked[mdev->port] = true;
+ printk(KERN_INFO "No maple devices attached"
+ " to port %d\n", mdev->port);
+ }
return;
}
maple_clean_submap(mdev);
@@ -485,8 +486,14 @@ static void maple_response_devinfo(struct maple_device *mdev,
char *recvbuf)
{
char submask;
- if ((!started) || (scanning == 2)) {
- maple_attach_driver(mdev);
+ if (!started || (scanning == 2) || !fullscan) {
+ if ((mdev->unit == 0) && (checked[mdev->port] == false)) {
+ checked[mdev->port] = true;
+ maple_attach_driver(mdev);
+ } else {
+ if (mdev->unit != 0)
+ maple_attach_driver(mdev);
+ }
return;
}
if (mdev->unit == 0) {
@@ -505,6 +512,7 @@ static void maple_dma_handler(struct work_struct *work)
struct maple_device *dev;
char *recvbuf;
enum maple_code code;
+ int i;
if (!maple_dma_done())
return;
@@ -557,6 +565,19 @@ static void maple_dma_handler(struct work_struct *work)
} else
scanning = 0;
+ if (!fullscan) {
+ fullscan = 1;
+ for (i = 0; i < MAPLE_PORTS; i++) {
+ if (checked[i] == false) {
+ fullscan = 0;
+ dev = baseunits[i];
+ dev->mq->command =
+ MAPLE_COMMAND_DEVINFO;
+ dev->mq->length = 0;
+ maple_add_packet(dev->mq);
+ }
+ }
+ }
if (started == 0)
started = 1;
}
@@ -694,7 +715,9 @@ static int __init maple_bus_init(void)
/* setup maple ports */
for (i = 0; i < MAPLE_PORTS; i++) {
+ checked[i] = false;
mdev[i] = maple_alloc_dev(i, 0);
+ baseunits[i] = mdev[i];
if (!mdev[i]) {
while (i-- > 0)
maple_free_dev(mdev[i]);
@@ -703,12 +726,9 @@ static int __init maple_bus_init(void)
mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO;
mdev[i]->mq->length = 0;
maple_add_packet(mdev[i]->mq);
- /* delay aids hardware detection */
- mdelay(5);
subdevice_map[i] = 0;
}
- realscan = 1;
/* setup maplebus hardware */
maplebus_dma_reset();
/* initial detection */
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 293b7cab3e5..85687aaf9ca 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -87,6 +87,16 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
unsigned gpio = (unsigned) spi->controller_data;
unsigned active = spi->mode & SPI_CS_HIGH;
u32 mr;
+ int i;
+ u32 csr;
+ u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0;
+
+ /* Make sure clock polarity is correct */
+ for (i = 0; i < spi->master->num_chipselect; i++) {
+ csr = spi_readl(as, CSR0 + 4 * i);
+ if ((csr ^ cpol) & SPI_BIT(CPOL))
+ spi_writel(as, CSR0 + 4 * i, csr ^ SPI_BIT(CPOL));
+ }
mr = spi_readl(as, MR);
mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr);
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 253ed5682a6..a86315a0c5b 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -42,6 +42,7 @@ struct mpc52xx_psc_spi {
/* driver internal data */
struct mpc52xx_psc __iomem *psc;
+ struct mpc52xx_psc_fifo __iomem *fifo;
unsigned int irq;
u8 bits_per_word;
u8 busy;
@@ -139,6 +140,7 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
{
struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
struct mpc52xx_psc __iomem *psc = mps->psc;
+ struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;
unsigned rb = 0; /* number of bytes receieved */
unsigned sb = 0; /* number of bytes sent */
unsigned char *rx_buf = (unsigned char *)t->rx_buf;
@@ -190,11 +192,11 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
out_8(&psc->mode, 0);
} else {
out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);
- out_be16(&psc->rfalarm, rfalarm);
+ out_be16(&fifo->rfalarm, rfalarm);
}
out_be16(&psc->mpc52xx_psc_imr, MPC52xx_PSC_IMR_RXRDY);
wait_for_completion(&mps->done);
- recv_at_once = in_be16(&psc->rfnum);
+ recv_at_once = in_be16(&fifo->rfnum);
dev_dbg(&spi->dev, "%d bytes received\n", recv_at_once);
send_at_once = recv_at_once;
@@ -331,6 +333,7 @@ static void mpc52xx_psc_spi_cleanup(struct spi_device *spi)
static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
{
struct mpc52xx_psc __iomem *psc = mps->psc;
+ struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;
u32 mclken_div;
int ret = 0;
@@ -346,7 +349,7 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
/* Disable interrupts, interrupts are based on alarm level */
out_be16(&psc->mpc52xx_psc_imr, 0);
out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
- out_8(&psc->rfcntl, 0);
+ out_8(&fifo->rfcntl, 0);
out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);
/* Configure 8bit codec mode as a SPI master and use EOF flags */
@@ -419,6 +422,8 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
ret = -EFAULT;
goto free_master;
}
+ /* On the 5200, fifo regs are immediately ajacent to the psc regs */
+ mps->fifo = ((void __iomem *)mps->psc) + sizeof(struct mpc52xx_psc);
ret = request_irq(mps->irq, mpc52xx_psc_spi_isr, 0, "mpc52xx-psc-spi",
mps);
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 365e0e355ae..59deed79e0a 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -51,13 +51,19 @@ MODULE_LICENSE("GPL");
#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
-/* for testing SSCR1 changes that require SSP restart, basically
- * everything except the service and interrupt enables */
-#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_EBCEI | SSCR1_SCFR \
+/*
+ * for testing SSCR1 changes that require SSP restart, basically
+ * everything except the service and interrupt enables, the pxa270 developer
+ * manual says only SSCR1_SCFR, SSCR1_SPH, SSCR1_SPO need to be in this
+ * list, but the PXA255 dev man says all bits without really meaning the
+ * service and interrupt enables
+ */
+#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \
| SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \
- | SSCR1_RWOT | SSCR1_TRAIL | SSCR1_PINTE \
- | SSCR1_STRF | SSCR1_EFWR |SSCR1_RFT \
- | SSCR1_TFT | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
+ | SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \
+ | SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \
+ | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \
+ | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
#define DEFINE_SSP_REG(reg, off) \
static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \
@@ -973,9 +979,6 @@ static void pump_transfers(unsigned long data)
if (drv_data->ssp_type == PXA25x_SSP)
DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN;
- /* Fix me, need to handle cs polarity */
- drv_data->cs_control(PXA2XX_CS_ASSERT);
-
/* Clear status and start DMA engine */
cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1;
write_SSSR(drv_data->clear_sr, reg);
@@ -985,9 +988,6 @@ static void pump_transfers(unsigned long data)
/* Ensure we have the correct interrupt handler */
drv_data->transfer_handler = interrupt_transfer;
- /* Fix me, need to handle cs polarity */
- drv_data->cs_control(PXA2XX_CS_ASSERT);
-
/* Clear status */
cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1;
write_SSSR(drv_data->clear_sr, reg);
@@ -998,16 +998,29 @@ static void pump_transfers(unsigned long data)
|| (read_SSCR1(reg) & SSCR1_CHANGE_MASK) !=
(cr1 & SSCR1_CHANGE_MASK)) {
+ /* stop the SSP, and update the other bits */
write_SSCR0(cr0 & ~SSCR0_SSE, reg);
if (drv_data->ssp_type != PXA25x_SSP)
write_SSTO(chip->timeout, reg);
- write_SSCR1(cr1, reg);
+ /* first set CR1 without interrupt and service enables */
+ write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg);
+ /* restart the SSP */
write_SSCR0(cr0, reg);
+
} else {
if (drv_data->ssp_type != PXA25x_SSP)
write_SSTO(chip->timeout, reg);
- write_SSCR1(cr1, reg);
}
+
+ /* FIXME, need to handle cs polarity,
+ * this driver uses struct pxa2xx_spi_chip.cs_control to
+ * specify a CS handling function, and it ignores most
+ * struct spi_device.mode[s], including SPI_CS_HIGH */
+ drv_data->cs_control(PXA2XX_CS_ASSERT);
+
+ /* after chip select, release the data by enabling service
+ * requests and interrupts, without changing any mode bits */
+ write_SSCR1(cr1, reg);
}
static void pump_messages(struct work_struct *work)
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index d976660cb7f..adea792fb67 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -35,6 +35,11 @@ config SSB_PCIHOST
If unsure, say Y
+config SSB_B43_PCI_BRIDGE
+ bool
+ depends on SSB_PCIHOST
+ default n
+
config SSB_PCMCIAHOST_POSSIBLE
bool
depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL
@@ -105,6 +110,12 @@ config SSB_DRIVER_MIPS
If unsure, say N
+# Assumption: We are on embedded, if we compile the MIPS core.
+config SSB_EMBEDDED
+ bool
+ depends on SSB_DRIVER_MIPS
+ default y
+
config SSB_DRIVER_EXTIF
bool "SSB Broadcom EXTIF core driver (EXPERIMENTAL)"
depends on SSB_DRIVER_MIPS && EXPERIMENTAL
diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile
index 7be39759580..de94c2eb7a3 100644
--- a/drivers/ssb/Makefile
+++ b/drivers/ssb/Makefile
@@ -1,5 +1,6 @@
# core
ssb-y += main.o scan.o
+ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o
# host support
ssb-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o
@@ -13,6 +14,6 @@ ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
# b43 pci-ssb-bridge driver
# Not strictly a part of SSB, but kept here for convenience
-ssb-$(CONFIG_SSB_PCIHOST) += b43_pci_bridge.o
+ssb-$(CONFIG_SSB_B43_PCI_BRIDGE) += b43_pci_bridge.o
obj-$(CONFIG_SSB) += ssb.o
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 6fbf1c53b6f..e586321a473 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -39,12 +39,14 @@ static inline void chipco_write32(struct ssb_chipcommon *cc,
ssb_write32(cc->dev, offset, value);
}
-static inline void chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset,
- u32 mask, u32 value)
+static inline u32 chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset,
+ u32 mask, u32 value)
{
value &= mask;
value |= chipco_read32(cc, offset) & ~mask;
chipco_write32(cc, offset, value);
+
+ return value;
}
void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
@@ -356,14 +358,29 @@ u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask)
return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask;
}
-void ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)
+u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)
+{
+ return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
+}
+
+u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)
+{
+ return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
+}
+
+u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value)
+{
+ return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
+}
+
+u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)
{
- chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
+ return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);
}
-void ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)
+u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value)
{
- chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
+ return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);
}
#ifdef CONFIG_SSB_SERIAL
@@ -376,6 +393,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
unsigned int irq;
u32 baud_base, div;
u32 i, n;
+ unsigned int ccrev = cc->dev->id.revision;
plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
irq = ssb_mips_irq(cc->dev);
@@ -387,14 +405,39 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
chipco_read32(cc, SSB_CHIPCO_CLOCK_M2));
div = 1;
} else {
- if (cc->dev->id.revision >= 11) {
+ if (ccrev == 20) {
+ /* BCM5354 uses constant 25MHz clock */
+ baud_base = 25000000;
+ div = 48;
+ /* Set the override bit so we don't divide it */
+ chipco_write32(cc, SSB_CHIPCO_CORECTL,
+ chipco_read32(cc, SSB_CHIPCO_CORECTL)
+ | SSB_CHIPCO_CORECTL_UARTCLK0);
+ } else if ((ccrev >= 11) && (ccrev != 15)) {
/* Fixed ALP clock */
baud_base = 20000000;
+ if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
+ /* FIXME: baud_base is different for devices with a PMU */
+ SSB_WARN_ON(1);
+ }
div = 1;
+ if (ccrev >= 21) {
+ /* Turn off UART clock before switching clocksource. */
+ chipco_write32(cc, SSB_CHIPCO_CORECTL,
+ chipco_read32(cc, SSB_CHIPCO_CORECTL)
+ & ~SSB_CHIPCO_CORECTL_UARTCLKEN);
+ }
/* Set the override bit so we don't divide it */
chipco_write32(cc, SSB_CHIPCO_CORECTL,
- SSB_CHIPCO_CORECTL_UARTCLK0);
- } else if (cc->dev->id.revision >= 3) {
+ chipco_read32(cc, SSB_CHIPCO_CORECTL)
+ | SSB_CHIPCO_CORECTL_UARTCLK0);
+ if (ccrev >= 21) {
+ /* Re-enable the UART clock. */
+ chipco_write32(cc, SSB_CHIPCO_CORECTL,
+ chipco_read32(cc, SSB_CHIPCO_CORECTL)
+ | SSB_CHIPCO_CORECTL_UARTCLKEN);
+ }
+ } else if (ccrev >= 3) {
/* Internal backplane clock */
baud_base = ssb_clockspeed(bus);
div = chipco_read32(cc, SSB_CHIPCO_CLKDIV)
@@ -406,7 +449,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
}
/* Clock source depends on strapping if UartClkOverride is unset */
- if ((cc->dev->id.revision > 0) &&
+ if ((ccrev > 0) &&
!(chipco_read32(cc, SSB_CHIPCO_CORECTL) & SSB_CHIPCO_CORECTL_UARTCLK0)) {
if ((cc->capabilities & SSB_CHIPCO_CAP_UARTCLK) ==
SSB_CHIPCO_CAP_UARTCLK_INT) {
@@ -428,7 +471,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
cc_mmio = cc->dev->bus->mmio + (cc->dev->core_index * SSB_CORE_SIZE);
uart_regs = cc_mmio + SSB_CHIPCO_UART0_DATA;
/* Offset changed at after rev 0 */
- if (cc->dev->id.revision == 0)
+ if (ccrev == 0)
uart_regs += (i * 8);
else
uart_regs += (i * 256);
diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c
index fe55eb8b038..c3e1d3e6d61 100644
--- a/drivers/ssb/driver_extif.c
+++ b/drivers/ssb/driver_extif.c
@@ -27,12 +27,14 @@ static inline void extif_write32(struct ssb_extif *extif, u16 offset, u32 value)
ssb_write32(extif->dev, offset, value);
}
-static inline void extif_write32_masked(struct ssb_extif *extif, u16 offset,
- u32 mask, u32 value)
+static inline u32 extif_write32_masked(struct ssb_extif *extif, u16 offset,
+ u32 mask, u32 value)
{
value &= mask;
value |= extif_read32(extif, offset) & ~mask;
extif_write32(extif, offset, value);
+
+ return value;
}
#ifdef CONFIG_SSB_SERIAL
@@ -110,20 +112,35 @@ void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
*m = extif_read32(extif, SSB_EXTIF_CLOCK_SB);
}
+void ssb_extif_watchdog_timer_set(struct ssb_extif *extif,
+ u32 ticks)
+{
+ extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks);
+}
+
u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
{
return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;
}
-void ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
+u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
{
return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
mask, value);
}
-void ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
+u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
{
return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
mask, value);
}
+u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)
+{
+ return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
+}
+
+u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)
+{
+ return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
+}
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index 2faaa906d5d..74b9a8aea52 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -11,6 +11,7 @@
#include <linux/ssb/ssb.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/ssb/ssb_embedded.h>
#include "ssb_private.h"
@@ -27,6 +28,18 @@ void pcicore_write32(struct ssb_pcicore *pc, u16 offset, u32 value)
ssb_write32(pc->dev, offset, value);
}
+static inline
+u16 pcicore_read16(struct ssb_pcicore *pc, u16 offset)
+{
+ return ssb_read16(pc->dev, offset);
+}
+
+static inline
+void pcicore_write16(struct ssb_pcicore *pc, u16 offset, u16 value)
+{
+ ssb_write16(pc->dev, offset, value);
+}
+
/**************************************************
* Code for hostmode operation.
**************************************************/
@@ -66,6 +79,7 @@ int pcibios_plat_dev_init(struct pci_dev *d)
base = &ssb_pcicore_pcibus_iobase;
else
base = &ssb_pcicore_pcibus_membase;
+ res->flags |= IORESOURCE_PCI_FIXED;
if (res->end) {
size = res->end - res->start + 1;
if (*base & (size - 1))
@@ -88,20 +102,28 @@ int pcibios_plat_dev_init(struct pci_dev *d)
static void __init ssb_fixup_pcibridge(struct pci_dev *dev)
{
+ u8 lat;
+
if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0)
return;
- ssb_printk(KERN_INFO "PCI: fixing up bridge\n");
+ ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev));
/* Enable PCI bridge bus mastering and memory space */
pci_set_master(dev);
- pcibios_enable_device(dev, ~0);
+ if (pcibios_enable_device(dev, ~0) < 0) {
+ ssb_printk(KERN_ERR "PCI: SSB bridge enable failed\n");
+ return;
+ }
/* Enable PCI bridge BAR1 prefetch and burst */
pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3);
/* Make sure our latency is high enough to handle the devices behind us */
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xa8);
+ lat = 168;
+ ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n",
+ pci_name(dev), lat);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
}
DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_fixup_pcibridge);
@@ -117,8 +139,10 @@ static u32 get_cfgspace_addr(struct ssb_pcicore *pc,
u32 addr = 0;
u32 tmp;
- if (unlikely(pc->cardbusmode && dev > 1))
+ /* We do only have one cardbus device behind the bridge. */
+ if (pc->cardbusmode && (dev >= 1))
goto out;
+
if (bus == 0) {
/* Type 0 transaction */
if (unlikely(dev >= SSB_PCI_SLOT_MAX))
@@ -279,14 +303,14 @@ static struct resource ssb_pcicore_mem_resource = {
.name = "SSB PCIcore external memory",
.start = SSB_PCI_DMA,
.end = SSB_PCI_DMA + SSB_PCI_DMA_SZ - 1,
- .flags = IORESOURCE_MEM,
+ .flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED,
};
static struct resource ssb_pcicore_io_resource = {
.name = "SSB PCIcore external I/O",
.start = 0x100,
.end = 0x7FF,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED,
};
static struct pci_controller ssb_pcicore_controller = {
@@ -318,7 +342,16 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
pcicore_write32(pc, SSB_PCICORE_ARBCTL, val);
udelay(1); /* Assertion time demanded by the PCI standard */
- /*TODO cardbus mode */
+ if (pc->dev->bus->has_cardbus_slot) {
+ ssb_dprintk(KERN_INFO PFX "CardBus slot detected\n");
+ pc->cardbusmode = 1;
+ /* GPIO 1 resets the bridge */
+ ssb_gpio_out(pc->dev->bus, 1, 1);
+ ssb_gpio_outen(pc->dev->bus, 1, 1);
+ pcicore_write16(pc, SSB_PCICORE_SPROM(0),
+ pcicore_read16(pc, SSB_PCICORE_SPROM(0))
+ | 0x0400);
+ }
/* 64MB I/O window */
pcicore_write32(pc, SSB_PCICORE_SBTOPCI0,
@@ -344,7 +377,8 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
/* Ok, ready to run, register it to the system.
* The following needs change, if we want to port hostmode
* to non-MIPS platform. */
- set_io_port_base((unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000));
+ ssb_pcicore_controller.io_map_base = (unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000);
+ set_io_port_base(ssb_pcicore_controller.io_map_base);
/* Give some time to the PCI controller to configure itself with the new
* values. Not waiting at this point causes crashes of the machine. */
mdelay(10);
@@ -362,7 +396,7 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
chipid_top != 0x5300)
return 0;
- if (bus->sprom.r1.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
+ if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
return 0;
/* The 200-pin BCM4712 package does not bond out PCI. Even when
diff --git a/drivers/ssb/embedded.c b/drivers/ssb/embedded.c
new file mode 100644
index 00000000000..d3ade821555
--- /dev/null
+++ b/drivers/ssb/embedded.c
@@ -0,0 +1,132 @@
+/*
+ * Sonics Silicon Backplane
+ * Embedded systems support code
+ *
+ * Copyright 2005-2008, Broadcom Corporation
+ * Copyright 2006-2008, Michael Buesch <mb@bu3sch.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include <linux/ssb/ssb.h>
+#include <linux/ssb/ssb_embedded.h>
+
+#include "ssb_private.h"
+
+
+int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks)
+{
+ if (ssb_chipco_available(&bus->chipco)) {
+ ssb_chipco_watchdog_timer_set(&bus->chipco, ticks);
+ return 0;
+ }
+ if (ssb_extif_available(&bus->extif)) {
+ ssb_extif_watchdog_timer_set(&bus->extif, ticks);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask)
+{
+ unsigned long flags;
+ u32 res = 0;
+
+ spin_lock_irqsave(&bus->gpio_lock, flags);
+ if (ssb_chipco_available(&bus->chipco))
+ res = ssb_chipco_gpio_in(&bus->chipco, mask);
+ else if (ssb_extif_available(&bus->extif))
+ res = ssb_extif_gpio_in(&bus->extif, mask);
+ else
+ SSB_WARN_ON(1);
+ spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+ return res;
+}
+EXPORT_SYMBOL(ssb_gpio_in);
+
+u32 ssb_gpio_out(struct ssb_bus *bus, u32 mask, u32 value)
+{
+ unsigned long flags;
+ u32 res = 0;
+
+ spin_lock_irqsave(&bus->gpio_lock, flags);
+ if (ssb_chipco_available(&bus->chipco))
+ res = ssb_chipco_gpio_out(&bus->chipco, mask, value);
+ else if (ssb_extif_available(&bus->extif))
+ res = ssb_extif_gpio_out(&bus->extif, mask, value);
+ else
+ SSB_WARN_ON(1);
+ spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+ return res;
+}
+EXPORT_SYMBOL(ssb_gpio_out);
+
+u32 ssb_gpio_outen(struct ssb_bus *bus, u32 mask, u32 value)
+{
+ unsigned long flags;
+ u32 res = 0;
+
+ spin_lock_irqsave(&bus->gpio_lock, flags);
+ if (ssb_chipco_available(&bus->chipco))
+ res = ssb_chipco_gpio_outen(&bus->chipco, mask, value);
+ else if (ssb_extif_available(&bus->extif))
+ res = ssb_extif_gpio_outen(&bus->extif, mask, value);
+ else
+ SSB_WARN_ON(1);
+ spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+ return res;
+}
+EXPORT_SYMBOL(ssb_gpio_outen);
+
+u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value)
+{
+ unsigned long flags;
+ u32 res = 0;
+
+ spin_lock_irqsave(&bus->gpio_lock, flags);
+ if (ssb_chipco_available(&bus->chipco))
+ res = ssb_chipco_gpio_control(&bus->chipco, mask, value);
+ spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+ return res;
+}
+EXPORT_SYMBOL(ssb_gpio_control);
+
+u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value)
+{
+ unsigned long flags;
+ u32 res = 0;
+
+ spin_lock_irqsave(&bus->gpio_lock, flags);
+ if (ssb_chipco_available(&bus->chipco))
+ res = ssb_chipco_gpio_intmask(&bus->chipco, mask, value);
+ else if (ssb_extif_available(&bus->extif))
+ res = ssb_extif_gpio_intmask(&bus->extif, mask, value);
+ else
+ SSB_WARN_ON(1);
+ spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+ return res;
+}
+EXPORT_SYMBOL(ssb_gpio_intmask);
+
+u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value)
+{
+ unsigned long flags;
+ u32 res = 0;
+
+ spin_lock_irqsave(&bus->gpio_lock, flags);
+ if (ssb_chipco_available(&bus->chipco))
+ res = ssb_chipco_gpio_polarity(&bus->chipco, mask, value);
+ else if (ssb_extif_available(&bus->extif))
+ res = ssb_extif_gpio_polarity(&bus->extif, mask, value);
+ else
+ SSB_WARN_ON(1);
+ spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+ return res;
+}
+EXPORT_SYMBOL(ssb_gpio_polarity);
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 9028ed5715a..bedb2b4ee9d 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -557,6 +557,7 @@ static int ssb_fetch_invariants(struct ssb_bus *bus,
goto out;
memcpy(&bus->boardinfo, &iv.boardinfo, sizeof(iv.boardinfo));
memcpy(&bus->sprom, &iv.sprom, sizeof(iv.sprom));
+ bus->has_cardbus_slot = iv.has_cardbus_slot;
out:
return err;
}
@@ -569,6 +570,9 @@ static int ssb_bus_register(struct ssb_bus *bus,
spin_lock_init(&bus->bar_lock);
INIT_LIST_HEAD(&bus->list);
+#ifdef CONFIG_SSB_EMBEDDED
+ spin_lock_init(&bus->gpio_lock);
+#endif
/* Powerup the bus */
err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index a789364264a..21eca2b5118 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -120,10 +120,10 @@ extern int ssb_devices_thaw(struct ssb_bus *bus);
extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev);
/* b43_pci_bridge.c */
-#ifdef CONFIG_SSB_PCIHOST
+#ifdef CONFIG_SSB_B43_PCI_BRIDGE
extern int __init b43_pci_ssb_bridge_init(void);
extern void __exit b43_pci_ssb_bridge_exit(void);
-#else /* CONFIG_SSB_PCIHOST */
+#else /* CONFIG_SSB_B43_PCI_BRIDGR */
static inline int b43_pci_ssb_bridge_init(void)
{
return 0;
diff --git a/drivers/thermal/thermal.c b/drivers/thermal/thermal.c
index e782b3e7fcd..8b86e53ccf7 100644
--- a/drivers/thermal/thermal.c
+++ b/drivers/thermal/thermal.c
@@ -306,12 +306,23 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
{
struct thermal_cooling_device_instance *dev;
struct thermal_cooling_device_instance *pos;
+ struct thermal_zone_device *pos1;
+ struct thermal_cooling_device *pos2;
int result;
if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE))
return -EINVAL;
- if (!tz || !cdev)
+ list_for_each_entry(pos1, &thermal_tz_list, node) {
+ if (pos1 == tz)
+ break;
+ }
+ list_for_each_entry(pos2, &thermal_cdev_list, node) {
+ if (pos2 == cdev)
+ break;
+ }
+
+ if (tz != pos1 || cdev != pos2)
return -EINVAL;
dev =
@@ -437,20 +448,20 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
int result;
if (strlen(type) >= THERMAL_NAME_LENGTH)
- return NULL;
+ return ERR_PTR(-EINVAL);
if (!ops || !ops->get_max_state || !ops->get_cur_state ||
!ops->set_cur_state)
- return NULL;
+ return ERR_PTR(-EINVAL);
cdev = kzalloc(sizeof(struct thermal_cooling_device), GFP_KERNEL);
if (!cdev)
- return NULL;
+ return ERR_PTR(-ENOMEM);
result = get_idr(&thermal_cdev_idr, &thermal_idr_lock, &cdev->id);
if (result) {
kfree(cdev);
- return NULL;
+ return ERR_PTR(result);
}
strcpy(cdev->type, type);
@@ -462,7 +473,7 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
if (result) {
release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
kfree(cdev);
- return NULL;
+ return ERR_PTR(result);
}
/* sys I/F */
@@ -498,7 +509,7 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
unregister:
release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
device_unregister(&cdev->device);
- return NULL;
+ return ERR_PTR(result);
}
EXPORT_SYMBOL(thermal_cooling_device_register);
@@ -570,17 +581,17 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
int count;
if (strlen(type) >= THERMAL_NAME_LENGTH)
- return NULL;
+ return ERR_PTR(-EINVAL);
if (trips > THERMAL_MAX_TRIPS || trips < 0)
- return NULL;
+ return ERR_PTR(-EINVAL);
if (!ops || !ops->get_temp)
- return NULL;
+ return ERR_PTR(-EINVAL);
tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL);
if (!tz)
- return NULL;
+ return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&tz->cooling_devices);
idr_init(&tz->idr);
@@ -588,7 +599,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id);
if (result) {
kfree(tz);
- return NULL;
+ return ERR_PTR(result);
}
strcpy(tz->type, type);
@@ -601,7 +612,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
if (result) {
release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
kfree(tz);
- return NULL;
+ return ERR_PTR(result);
}
/* sys I/F */
@@ -643,7 +654,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
unregister:
release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
device_unregister(&tz->device);
- return NULL;
+ return ERR_PTR(result);
}
EXPORT_SYMBOL(thermal_zone_device_register);
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 2a77e9d42c6..e8a01f26454 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -57,29 +57,29 @@ struct uio_map {
};
#define to_map(map) container_of(map, struct uio_map, kobj)
-
-static ssize_t map_attr_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
+static ssize_t map_addr_show(struct uio_mem *mem, char *buf)
{
- struct uio_map *map = to_map(kobj);
- struct uio_mem *mem = map->mem;
-
- if (strncmp(attr->attr.name, "addr", 4) == 0)
- return sprintf(buf, "0x%lx\n", mem->addr);
-
- if (strncmp(attr->attr.name, "size", 4) == 0)
- return sprintf(buf, "0x%lx\n", mem->size);
+ return sprintf(buf, "0x%lx\n", mem->addr);
+}
- return -ENODEV;
+static ssize_t map_size_show(struct uio_mem *mem, char *buf)
+{
+ return sprintf(buf, "0x%lx\n", mem->size);
}
-static struct kobj_attribute attr_attribute =
- __ATTR(addr, S_IRUGO, map_attr_show, NULL);
-static struct kobj_attribute size_attribute =
- __ATTR(size, S_IRUGO, map_attr_show, NULL);
+struct uio_sysfs_entry {
+ struct attribute attr;
+ ssize_t (*show)(struct uio_mem *, char *);
+ ssize_t (*store)(struct uio_mem *, const char *, size_t);
+};
+
+static struct uio_sysfs_entry addr_attribute =
+ __ATTR(addr, S_IRUGO, map_addr_show, NULL);
+static struct uio_sysfs_entry size_attribute =
+ __ATTR(size, S_IRUGO, map_size_show, NULL);
static struct attribute *attrs[] = {
- &attr_attribute.attr,
+ &addr_attribute.attr,
&size_attribute.attr,
NULL, /* need to NULL terminate the list of attributes */
};
@@ -90,8 +90,28 @@ static void map_release(struct kobject *kobj)
kfree(map);
}
+static ssize_t map_type_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct uio_map *map = to_map(kobj);
+ struct uio_mem *mem = map->mem;
+ struct uio_sysfs_entry *entry;
+
+ entry = container_of(attr, struct uio_sysfs_entry, attr);
+
+ if (!entry->show)
+ return -EIO;
+
+ return entry->show(mem, buf);
+}
+
+static struct sysfs_ops uio_sysfs_ops = {
+ .show = map_type_show,
+};
+
static struct kobj_type map_attr_type = {
.release = map_release,
+ .sysfs_ops = &uio_sysfs_ops,
.default_attrs = attrs,
};
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index bcc42136c93..0147ea39340 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -496,13 +496,10 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
otherwise it is scheduled, and with high data rates data can get lost. */
tty->low_latency = 1;
- if (usb_autopm_get_interface(acm->control)) {
- mutex_unlock(&open_mutex);
- return -EIO;
- }
+ if (usb_autopm_get_interface(acm->control) < 0)
+ goto early_bail;
mutex_lock(&acm->mutex);
- mutex_unlock(&open_mutex);
if (acm->used++) {
usb_autopm_put_interface(acm->control);
goto done;
@@ -536,6 +533,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
done:
err_out:
mutex_unlock(&acm->mutex);
+ mutex_unlock(&open_mutex);
return rv;
full_bailout:
@@ -544,6 +542,8 @@ bail_out:
usb_autopm_put_interface(acm->control);
acm->used--;
mutex_unlock(&acm->mutex);
+early_bail:
+ mutex_unlock(&open_mutex);
return -EIO;
}
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index ad632f2d6f9..0647164d36d 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -428,6 +428,7 @@ static int usblp_open(struct inode *inode, struct file *file)
usblp->rcomplete = 0;
if (handle_bidir(usblp) < 0) {
+ usb_autopm_put_interface(intf);
usblp->used = 0;
file->private_data = NULL;
retval = -EIO;
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index 5c33cdb9cac..a2b0aa48b8e 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -87,12 +87,13 @@ config USB_DYNAMIC_MINORS
If you are unsure about this, say N here.
config USB_SUSPEND
- bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)"
- depends on USB && PM && EXPERIMENTAL
+ bool "USB selective suspend/resume and wakeup"
+ depends on USB && PM
help
If you say Y here, you can use driver calls or the sysfs
- "power/state" file to suspend or resume individual USB
- peripherals.
+ "power/level" file to suspend or resume individual USB
+ peripherals and to enable or disable autosuspend (see
+ Documentation/usb/power-management.txt for more details).
Also, USB "remote wakeup" signaling is supported, whereby some
USB devices (like keyboards and network adapters) can wake up
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index d42c561c75f..d9d1eb19f2a 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -30,21 +30,36 @@
static const struct usb_device_id usb_quirk_list[] = {
/* CBM - Flash disk */
{ USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME },
+
/* HP 5300/5370C scanner */
- { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
+ { USB_DEVICE(0x03f0, 0x0701), .driver_info =
+ USB_QUIRK_STRING_FETCH_255 },
- /* INTEL VALUE SSD */
- { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Creative SB Audigy 2 NX */
+ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
+
+ /* Philips PSC805 audio device */
+ { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
+
+ /* Roland SC-8820 */
+ { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },
+
+ /* Edirol SD-20 */
+ { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },
/* M-Systems Flash Disk Pioneers */
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
- /* Philips PSC805 audio device */
- { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Action Semiconductor flash disk */
+ { USB_DEVICE(0x10d6, 0x2200), .driver_info =
+ USB_QUIRK_STRING_FETCH_255 },
/* SKYMEDI USB_DRIVE */
{ USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* INTEL VALUE SSD */
+ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
+
{ } /* terminating entry must be last */
};
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 4e984060c98..1f0db51190c 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -99,8 +99,7 @@ struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev,
EXPORT_SYMBOL_GPL(usb_ifnum_to_if);
/**
- * usb_altnum_to_altsetting - get the altsetting structure with a given
- * alternate setting number.
+ * usb_altnum_to_altsetting - get the altsetting structure with a given alternate setting number.
* @intf: the interface containing the altsetting in question
* @altnum: the desired alternate setting number
*
@@ -234,7 +233,7 @@ static int ksuspend_usb_init(void)
* singlethreaded. Its job doesn't justify running on more
* than one CPU.
*/
- ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd");
+ ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd");
if (!ksuspend_usb_wq)
return -ENOMEM;
return 0;
@@ -442,8 +441,7 @@ EXPORT_SYMBOL_GPL(usb_put_intf);
*/
/**
- * usb_lock_device_for_reset - cautiously acquire the lock for a
- * usb device structure
+ * usb_lock_device_for_reset - cautiously acquire the lock for a usb device structure
* @udev: device that's being locked
* @iface: interface bound to the driver making the request (optional)
*
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index a70e255402b..e9987230814 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -1561,6 +1561,7 @@ done_set_intf:
memcpy(req->buf, buf, n);
req->complete = rndis_response_complete;
rndis_free_response(dev->rndis_config, buf);
+ value = n;
}
/* else stalls ... spec says to avoid that */
}
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 9fdabc8fcac..2c32bd08ee7 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -92,7 +92,6 @@ struct printer_dev {
u8 *current_rx_buf;
u8 printer_status;
u8 reset_printer;
- struct class_device *printer_class_dev;
struct cdev printer_cdev;
struct device *pdev;
u8 printer_cdev_open;
@@ -1299,7 +1298,7 @@ printer_unbind(struct usb_gadget *gadget)
printer_req_free(dev->in_ep, req);
}
- if (dev->current_rx_req != NULL);
+ if (dev->current_rx_req != NULL)
printer_req_free(dev->out_ep, dev->current_rx_req);
while (!list_empty(&dev->rx_reqs)) {
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 4402d6f042d..096c41cc40d 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -103,6 +103,12 @@ static const char ep0name [] = "ep0";
#error "Can't configure both IXP and PXA"
#endif
+/* IXP doesn't yet support <linux/clk.h> */
+#define clk_get(dev,name) NULL
+#define clk_enable(clk) do { } while (0)
+#define clk_disable(clk) do { } while (0)
+#define clk_put(clk) do { } while (0)
+
#endif
#include "pxa2xx_udc.h"
@@ -934,20 +940,31 @@ static void udc_disable(struct pxa2xx_udc *);
/* We disable the UDC -- and its 48 MHz clock -- whenever it's not
* in active use.
*/
-static int pullup(struct pxa2xx_udc *udc, int is_active)
+static int pullup(struct pxa2xx_udc *udc)
{
- is_active = is_active && udc->vbus && udc->pullup;
+ int is_active = udc->vbus && udc->pullup && !udc->suspended;
DMSG("%s\n", is_active ? "active" : "inactive");
- if (is_active)
- udc_enable(udc);
- else {
- if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
- DMSG("disconnect %s\n", udc->driver
- ? udc->driver->driver.name
- : "(no driver)");
- stop_activity(udc, udc->driver);
+ if (is_active) {
+ if (!udc->active) {
+ udc->active = 1;
+ /* Enable clock for USB device */
+ clk_enable(udc->clk);
+ udc_enable(udc);
}
- udc_disable(udc);
+ } else {
+ if (udc->active) {
+ if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
+ DMSG("disconnect %s\n", udc->driver
+ ? udc->driver->driver.name
+ : "(no driver)");
+ stop_activity(udc, udc->driver);
+ }
+ udc_disable(udc);
+ /* Disable clock for USB device */
+ clk_disable(udc->clk);
+ udc->active = 0;
+ }
+
}
return 0;
}
@@ -958,9 +975,9 @@ static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
struct pxa2xx_udc *udc;
udc = container_of(_gadget, struct pxa2xx_udc, gadget);
- udc->vbus = is_active = (is_active != 0);
+ udc->vbus = (is_active != 0);
DMSG("vbus %s\n", is_active ? "supplied" : "inactive");
- pullup(udc, is_active);
+ pullup(udc);
return 0;
}
@@ -975,9 +992,8 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active)
if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
return -EOPNOTSUPP;
- is_active = (is_active != 0);
- udc->pullup = is_active;
- pullup(udc, is_active);
+ udc->pullup = (is_active != 0);
+ pullup(udc);
return 0;
}
@@ -997,7 +1013,7 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = {
#ifdef CONFIG_USB_GADGET_DEBUG_FS
static int
-udc_seq_show(struct seq_file *m, void *d)
+udc_seq_show(struct seq_file *m, void *_d)
{
struct pxa2xx_udc *dev = m->private;
unsigned long flags;
@@ -1146,11 +1162,6 @@ static void udc_disable(struct pxa2xx_udc *dev)
udc_clear_mask_UDCCR(UDCCR_UDE);
-#ifdef CONFIG_ARCH_PXA
- /* Disable clock for USB device */
- clk_disable(dev->clk);
-#endif
-
ep0_idle (dev);
dev->gadget.speed = USB_SPEED_UNKNOWN;
}
@@ -1191,11 +1202,6 @@ static void udc_enable (struct pxa2xx_udc *dev)
{
udc_clear_mask_UDCCR(UDCCR_UDE);
-#ifdef CONFIG_ARCH_PXA
- /* Enable clock for USB device */
- clk_enable(dev->clk);
-#endif
-
/* try to clear these bits before we enable the udc */
udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR);
@@ -1286,7 +1292,7 @@ fail:
* for set_configuration as well as eventual disconnect.
*/
DMSG("registered gadget driver '%s'\n", driver->driver.name);
- pullup(dev, 1);
+ pullup(dev);
dump_state(dev);
return 0;
}
@@ -1329,7 +1335,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
return -EINVAL;
local_irq_disable();
- pullup(dev, 0);
+ dev->pullup = 0;
+ pullup(dev);
stop_activity(dev, driver);
local_irq_enable();
@@ -2131,13 +2138,11 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
if (irq < 0)
return -ENODEV;
-#ifdef CONFIG_ARCH_PXA
dev->clk = clk_get(&pdev->dev, "UDCCLK");
if (IS_ERR(dev->clk)) {
retval = PTR_ERR(dev->clk);
goto err_clk;
}
-#endif
pr_debug("%s: IRQ %d%s%s\n", driver_name, irq,
dev->has_cfr ? "" : " (!cfr)",
@@ -2250,10 +2255,8 @@ lubbock_fail0:
if (dev->mach->gpio_vbus)
gpio_free(dev->mach->gpio_vbus);
err_gpio_vbus:
-#ifdef CONFIG_ARCH_PXA
clk_put(dev->clk);
err_clk:
-#endif
return retval;
}
@@ -2269,7 +2272,9 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
if (dev->driver)
return -EBUSY;
- udc_disable(dev);
+ dev->pullup = 0;
+ pullup(dev);
+
remove_debug_files(dev);
if (dev->got_irq) {
@@ -2289,9 +2294,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
if (dev->mach->gpio_pullup)
gpio_free(dev->mach->gpio_pullup);
-#ifdef CONFIG_ARCH_PXA
clk_put(dev->clk);
-#endif
platform_set_drvdata(pdev, NULL);
the_controller = NULL;
@@ -2317,10 +2320,15 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
{
struct pxa2xx_udc *udc = platform_get_drvdata(dev);
+ unsigned long flags;
if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
WARN("USB host won't detect disconnect!\n");
- pullup(udc, 0);
+ udc->suspended = 1;
+
+ local_irq_save(flags);
+ pullup(udc);
+ local_irq_restore(flags);
return 0;
}
@@ -2328,8 +2336,12 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
static int pxa2xx_udc_resume(struct platform_device *dev)
{
struct pxa2xx_udc *udc = platform_get_drvdata(dev);
+ unsigned long flags;
- pullup(udc, 1);
+ udc->suspended = 0;
+ local_irq_save(flags);
+ pullup(udc);
+ local_irq_restore(flags);
return 0;
}
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
index b67e3ff5e4e..e2c19e88c87 100644
--- a/drivers/usb/gadget/pxa2xx_udc.h
+++ b/drivers/usb/gadget/pxa2xx_udc.h
@@ -119,7 +119,9 @@ struct pxa2xx_udc {
has_cfr : 1,
req_pending : 1,
req_std : 1,
- req_config : 1;
+ req_config : 1,
+ suspended : 1,
+ active : 1;
#define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200))
struct timer_list timer;
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index d97b16b52ef..bf8be2a41a4 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -69,10 +69,9 @@ config USB_EHCI_BIG_ENDIAN_DESC
default y
config USB_EHCI_FSL
- bool
- depends on USB_EHCI_HCD
+ bool "Support for Freescale on-chip EHCI USB controller"
+ depends on USB_EHCI_HCD && FSL_SOC
select USB_EHCI_ROOT_HUB_TT
- default y if MPC834x || PPC_MPC831x
---help---
Variation of ARC USB block used in some Freescale chips.
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 4caa6a8b9a3..b8ad55aff84 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -862,18 +862,18 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
/* reschedule QH iff another request is queued */
if (!list_empty (&qh->qtd_list)
&& HC_IS_RUNNING (hcd->state)) {
- int schedule_status;
-
- schedule_status = qh_schedule (ehci, qh);
- spin_unlock_irqrestore (&ehci->lock, flags);
-
- if (schedule_status != 0) {
- // shouldn't happen often, but ...
- // FIXME kill those tds' urbs
- err ("can't reschedule qh %p, err %d",
- qh, schedule_status);
- }
- return status;
+ rc = qh_schedule(ehci, qh);
+
+ /* An error here likely indicates handshake failure
+ * or no space left in the schedule. Neither fault
+ * should happen often ...
+ *
+ * FIXME kill the now-dysfunctional queued urbs
+ */
+ if (rc != 0)
+ ehci_err(ehci,
+ "can't reschedule qh %p, err %d",
+ qh, rc);
}
break;
@@ -1014,7 +1014,7 @@ MODULE_LICENSE ("GPL");
#endif
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
- !defined(PS3_SYSTEM_BUS_DRIVER)
+ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
#error "missing bus glue for ehci-hcd"
#endif
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 776a97f3391..2e49de820b1 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -319,10 +319,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
if (likely (last->urb != urb)) {
ehci_urb_done(ehci, last->urb, last_status);
count++;
+ last_status = -EINPROGRESS;
}
ehci_qtd_free (ehci, last);
last = NULL;
- last_status = -EINPROGRESS;
}
/* ignore urbs submitted during completions we reported */
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 0130fd8571e..d7071c85575 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -911,8 +911,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
buf[0] = 0;
for (i = 0; i < ports; i++) {
- u32 status = isp116x->rhport[i] =
- isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1);
+ u32 status = isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1);
if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
| RH_PS_OCIC | RH_PS_PRSC)) {
@@ -1031,7 +1030,9 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
DBG("GetPortStatus\n");
if (!wIndex || wIndex > ports)
goto error;
- tmp = isp116x->rhport[--wIndex];
+ spin_lock_irqsave(&isp116x->lock, flags);
+ tmp = isp116x_read_reg32(isp116x, (--wIndex) ? HCRHPORT2 : HCRHPORT1);
+ spin_unlock_irqrestore(&isp116x->lock, flags);
*(__le32 *) buf = cpu_to_le32(tmp);
DBG("GetPortStatus: port[%d] %08x\n", wIndex + 1, tmp);
break;
@@ -1080,8 +1081,6 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
spin_lock_irqsave(&isp116x->lock, flags);
isp116x_write_reg32(isp116x, wIndex
? HCRHPORT2 : HCRHPORT1, tmp);
- isp116x->rhport[wIndex] =
- isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1);
spin_unlock_irqrestore(&isp116x->lock, flags);
break;
case SetPortFeature:
@@ -1095,24 +1094,22 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
spin_lock_irqsave(&isp116x->lock, flags);
isp116x_write_reg32(isp116x, wIndex
? HCRHPORT2 : HCRHPORT1, RH_PS_PSS);
+ spin_unlock_irqrestore(&isp116x->lock, flags);
break;
case USB_PORT_FEAT_POWER:
DBG("USB_PORT_FEAT_POWER\n");
spin_lock_irqsave(&isp116x->lock, flags);
isp116x_write_reg32(isp116x, wIndex
? HCRHPORT2 : HCRHPORT1, RH_PS_PPS);
+ spin_unlock_irqrestore(&isp116x->lock, flags);
break;
case USB_PORT_FEAT_RESET:
DBG("USB_PORT_FEAT_RESET\n");
root_port_reset(isp116x, wIndex);
- spin_lock_irqsave(&isp116x->lock, flags);
break;
default:
goto error;
}
- isp116x->rhport[wIndex] =
- isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1);
- spin_unlock_irqrestore(&isp116x->lock, flags);
break;
default:
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h
index b91e2edd9c5..595b90a9984 100644
--- a/drivers/usb/host/isp116x.h
+++ b/drivers/usb/host/isp116x.h
@@ -270,7 +270,6 @@ struct isp116x {
u32 rhdesca;
u32 rhdescb;
u32 rhstatus;
- u32 rhport[2];
/* async schedule: control, bulk */
struct list_head async;
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index ba370c56172..59be276ccd9 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1766,6 +1766,7 @@ sl811h_suspend(struct platform_device *dev, pm_message_t state)
retval = sl811h_bus_suspend(hcd);
break;
case PM_EVENT_SUSPEND:
+ case PM_EVENT_HIBERNATE:
case PM_EVENT_PRETHAW: /* explicitly discard hw state */
port_power(sl811, 0);
break;
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index ac283b09a63..3033d694520 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -3213,15 +3213,20 @@ static int u132_suspend(struct platform_device *pdev, pm_message_t state)
dev_err(&u132->platform_dev->dev, "device is being removed\n");
return -ESHUTDOWN;
} else {
- int retval = 0;
- if (state.event == PM_EVENT_FREEZE) {
+ int retval = 0, ports;
+
+ switch (state.event) {
+ case PM_EVENT_FREEZE:
retval = u132_bus_suspend(hcd);
- } else if (state.event == PM_EVENT_SUSPEND) {
- int ports = MAX_U132_PORTS;
+ break;
+ case PM_EVENT_SUSPEND:
+ case PM_EVENT_HIBERNATE:
+ ports = MAX_U132_PORTS;
while (ports-- > 0) {
port_power(u132, ports, 0);
}
- }
+ break;
+ }
if (retval == 0)
pdev->dev.power.power_state = state;
return retval;
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 8208496dfc6..c730d20eec6 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -61,6 +61,7 @@
#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
+#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006
#define USB_VENDOR_ID_MICROCHIP 0x04d8
#define USB_DEVICE_ID_PICDEM 0x000c
@@ -92,6 +93,7 @@ static struct usb_device_id ld_usb_table [] = {
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
{ USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) },
+ { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, ld_usb_table);
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c
index 67e2fc20eee..03368edf3f2 100644
--- a/drivers/usb/misc/trancevibrator.c
+++ b/drivers/usb/misc/trancevibrator.c
@@ -59,13 +59,14 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr,
{
struct usb_interface *intf = to_usb_interface(dev);
struct trancevibrator *tv = usb_get_intfdata(intf);
- int temp, retval;
+ int temp, retval, old;
temp = simple_strtoul(buf, NULL, 10);
if (temp > 255)
temp = 255;
else if (temp < 0)
temp = 0;
+ old = tv->speed;
tv->speed = temp;
dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed);
@@ -77,6 +78,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr,
tv->speed, /* speed value */
0, NULL, 0, USB_CTRL_GET_TIMEOUT);
if (retval) {
+ tv->speed = old;
dev_dbg(&tv->udev->dev, "retval = %d\n", retval);
return retval;
}
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 90dcc625f70..91dc433dbcf 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -92,6 +92,7 @@ struct ftdi_sio_quirk {
};
static int ftdi_jtag_probe (struct usb_serial *serial);
+static int ftdi_mtxorb_hack_setup (struct usb_serial *serial);
static void ftdi_USB_UIRT_setup (struct ftdi_private *priv);
static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv);
@@ -99,6 +100,10 @@ static struct ftdi_sio_quirk ftdi_jtag_quirk = {
.probe = ftdi_jtag_probe,
};
+static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = {
+ .probe = ftdi_mtxorb_hack_setup,
+};
+
static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
.port_probe = ftdi_USB_UIRT_setup,
};
@@ -161,6 +166,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
+ { USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
@@ -274,6 +281,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) },
{ USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
{ USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
@@ -393,8 +401,8 @@ static const char *ftdi_chip_name[] = {
#define FTDI_STATUS_B1_MASK (FTDI_RS_BI)
/* End TIOCMIWAIT */
-#define FTDI_IMPL_ASYNC_FLAGS = ( ASYNC_SPD_HI | ASYNC_SPD_VHI \
- ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP )
+#define FTDI_IMPL_ASYNC_FLAGS = (ASYNC_SPD_HI | ASYNC_SPD_VHI \
+ | ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP)
/* function prototypes for a FTDI serial converter */
static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id);
@@ -1088,6 +1096,23 @@ static int ftdi_jtag_probe(struct usb_serial *serial)
return 0;
}
+/*
+ * The Matrix Orbital VK204-25-USB has an invalid IN endpoint.
+ * We have to correct it if we want to read from it.
+ */
+static int ftdi_mtxorb_hack_setup(struct usb_serial *serial)
+{
+ struct usb_host_endpoint *ep = serial->dev->ep_in[1];
+ struct usb_endpoint_descriptor *ep_desc = &ep->desc;
+
+ if (ep->enabled && ep_desc->wMaxPacketSize == 0) {
+ ep_desc->wMaxPacketSize = 0x40;
+ info("Fixing invalid wMaxPacketSize on read pipe");
+ }
+
+ return 0;
+}
+
/* ftdi_shutdown is called from usbserial:usb_serial_disconnect
* it is called when the usb device is disconnected
*
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 6eee2ab914e..e1eb742abcd 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -102,6 +102,13 @@
* (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */
#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */
+/*
+ * The following are the values for the Matrix Orbital VK204-25-USB
+ * display, which use the FT232RL.
+ */
+#define MTXORB_VK_VID 0x1b3d
+#define MTXORB_VK_PID 0x0158
+
/* Interbiometrics USB I/O Board */
/* Developed for Interbiometrics by Rudolf Gugler */
#define INTERBIOMETRICS_VID 0x1209
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 869ecd374cb..aeeb9cb2099 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -110,11 +110,20 @@
/* vendor id and device id defines */
+/* The native mos7840/7820 component */
#define USB_VENDOR_ID_MOSCHIP 0x9710
#define MOSCHIP_DEVICE_ID_7840 0x7840
#define MOSCHIP_DEVICE_ID_7820 0x7820
+/* The native component can have its vendor/device id's overridden
+ * in vendor-specific implementations. Such devices can be handled
+ * by making a change here, in moschip_port_id_table, and in
+ * moschip_id_table_combined
+ */
+#define USB_VENDOR_ID_BANDB 0x0856
+#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44
+#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42
-/* Interrupt Rotinue Defines */
+/* Interrupt Routine Defines */
#define SERIAL_IIR_RLS 0x06
#define SERIAL_IIR_MS 0x00
@@ -159,12 +168,16 @@
static struct usb_device_id moschip_port_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
{} /* terminating entry */
};
static __devinitdata struct usb_device_id moschip_id_table_combined[] = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
{} /* terminating entry */
};
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 5e8bf1bc1e5..828a4377ec6 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -113,14 +113,22 @@ static int option_send_setup(struct usb_serial_port *port);
#define NOVATELWIRELESS_VENDOR_ID 0x1410
#define DELL_VENDOR_ID 0x413C
+#define KYOCERA_VENDOR_ID 0x0c88
+#define KYOCERA_PRODUCT_KPC680 0x180a
+
#define ANYDATA_VENDOR_ID 0x16d5
#define ANYDATA_PRODUCT_ADU_E100A 0x6501
#define ANYDATA_PRODUCT_ADU_500A 0x6502
+#define AXESSTEL_VENDOR_ID 0x1726
+#define AXESSTEL_PRODUCT_MV110H 0x1000
+
#define BANDRICH_VENDOR_ID 0x1A8D
#define BANDRICH_PRODUCT_C100_1 0x1002
#define BANDRICH_PRODUCT_C100_2 0x1003
+#define QUALCOMM_VENDOR_ID 0x05C6
+
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -174,18 +182,24 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x5010) }, /* Novatel U727 */
{ 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(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
+ { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
+ { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
+ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
@@ -247,10 +261,10 @@ static int debug;
struct option_port_private {
/* Input endpoints and buffer for this port */
struct urb *in_urbs[N_IN_URB];
- char in_buffer[N_IN_URB][IN_BUFLEN];
+ u8 *in_buffer[N_IN_URB];
/* Output endpoints and buffer for this port */
struct urb *out_urbs[N_OUT_URB];
- char out_buffer[N_OUT_URB][OUT_BUFLEN];
+ u8 *out_buffer[N_OUT_URB];
unsigned long out_busy; /* Bit vector of URBs in use */
/* Settings for the port */
@@ -737,9 +751,10 @@ static int option_send_setup(struct usb_serial_port *port)
static int option_startup(struct usb_serial *serial)
{
- int i, err;
+ int i, j, err;
struct usb_serial_port *port;
struct option_port_private *portdata;
+ u8 *buffer;
dbg("%s", __FUNCTION__);
@@ -753,6 +768,20 @@ static int option_startup(struct usb_serial *serial)
return (1);
}
+ for (j = 0; j < N_IN_URB; j++) {
+ buffer = (u8 *)__get_free_page(GFP_KERNEL);
+ if (!buffer)
+ goto bail_out_error;
+ portdata->in_buffer[j] = buffer;
+ }
+
+ for (j = 0; j < N_OUT_URB; j++) {
+ buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
+ if (!buffer)
+ goto bail_out_error2;
+ portdata->out_buffer[j] = buffer;
+ }
+
usb_set_serial_port_data(port, portdata);
if (! port->interrupt_in_urb)
@@ -766,6 +795,16 @@ static int option_startup(struct usb_serial *serial)
option_setup_urbs(serial);
return (0);
+
+bail_out_error2:
+ for (j = 0; j < N_OUT_URB; j++)
+ kfree(portdata->out_buffer[j]);
+bail_out_error:
+ for (j = 0; j < N_IN_URB; j++)
+ if (portdata->in_buffer[j])
+ free_page((unsigned long)portdata->in_buffer[j]);
+ kfree(portdata);
+ return 1;
}
static void option_shutdown(struct usb_serial *serial)
@@ -794,12 +833,14 @@ static void option_shutdown(struct usb_serial *serial)
for (j = 0; j < N_IN_URB; j++) {
if (portdata->in_urbs[j]) {
usb_free_urb(portdata->in_urbs[j]);
+ free_page((unsigned long)portdata->in_buffer[j]);
portdata->in_urbs[j] = NULL;
}
}
for (j = 0; j < N_OUT_URB; j++) {
if (portdata->out_urbs[j]) {
usb_free_urb(portdata->out_urbs[j]);
+ kfree(portdata->out_buffer[j]);
portdata->out_urbs[j] = NULL;
}
}
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 4c925e3e8a6..e3d44ae8d44 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -178,7 +178,6 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */
{ USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */
- { USB_DEVICE(0x05C6, 0x6613), .driver_info = DEVICE_1_PORT }, /* Onda H600/ZTE MF330 */
{ USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
{ }
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index a41ce21c069..b9b8ede61fb 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -150,13 +150,14 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
/* Copy a buffer of length buflen to/from the srb's transfer buffer.
* Update the **sgptr and *offset variables so that the next copy will
- * pick up from where this one left off. */
-
+ * pick up from where this one left off.
+ */
unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
unsigned int *offset, enum xfer_buf_dir dir)
{
unsigned int cnt;
+ struct scatterlist *sg = *sgptr;
/* We have to go through the list one entry
* at a time. Each s-g entry contains some number of pages, and
@@ -164,22 +165,22 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
* in kernel-addressable memory then kmap() will return its address.
* If the page is not directly accessible -- such as a user buffer
* located in high memory -- then kmap() will map it to a temporary
- * position in the kernel's virtual address space. */
- struct scatterlist *sg = *sgptr;
+ * position in the kernel's virtual address space.
+ */
if (!sg)
sg = scsi_sglist(srb);
/* This loop handles a single s-g list entry, which may
- * include multiple pages. Find the initial page structure
- * and the starting offset within the page, and update
- * the *offset and **sgptr values for the next loop. */
+ * include multiple pages. Find the initial page structure
+ * and the starting offset within the page, and update
+ * the *offset and **sgptr values for the next loop.
+ */
cnt = 0;
- while (cnt < buflen) {
+ while (cnt < buflen && sg) {
struct page *page = sg_page(sg) +
((sg->offset + *offset) >> PAGE_SHIFT);
- unsigned int poff =
- (sg->offset + *offset) & (PAGE_SIZE-1);
+ unsigned int poff = (sg->offset + *offset) & (PAGE_SIZE-1);
unsigned int sglen = sg->length - *offset;
if (sglen > buflen - cnt) {
@@ -222,14 +223,16 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
}
/* Store the contents of buffer into srb's transfer buffer and set the
- * SCSI residue. */
+ * SCSI residue.
+ */
void usb_stor_set_xfer_buf(unsigned char *buffer,
unsigned int buflen, struct scsi_cmnd *srb)
{
unsigned int offset = 0;
struct scatterlist *sg = NULL;
- usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
+ buflen = min(buflen, scsi_bufflen(srb));
+ buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
TO_XFER_BUF);
if (buflen < scsi_bufflen(srb))
scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index d9f4912f873..5780ed15f1a 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -891,17 +891,6 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
if (result > 0)
return us->iobuf[0];
- /*
- * Some devices (i.e. Iomega Zip100) need this -- apparently
- * the bulk pipes get STALLed when the GetMaxLUN request is
- * processed. This is, in theory, harmless to all other devices
- * (regardless of if they stall or not).
- */
- if (result == -EPIPE) {
- usb_stor_clear_halt(us, us->recv_bulk_pipe);
- usb_stor_clear_halt(us, us->send_bulk_pipe);
- }
-
/*
* Some devices don't like GetMaxLUN. They may STALL the control
* pipe, they may return a zero-length result, they may do nothing at
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index fe12737e0e2..99679a8cfa0 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -357,7 +357,7 @@ UNUSUAL_DEV( 0x04b0, 0x040f, 0x0100, 0x0200,
US_FL_FIX_CAPACITY),
/* Reported by Emil Larsson <emil@swip.net> */
-UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101,
+UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0110,
"NIKON",
"NIKON DSC D80",
US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -759,6 +759,18 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210,
"Digital Camera EX-20 DSC",
US_SC_8070, US_PR_DEVICE, NULL, 0 ),
+/* Reported by Andre Welter <a.r.welter@gmx.de>
+ * This antique device predates the release of the Bulk-only Transport
+ * spec, and if it gets a Get-Max-LUN then it requires the host to do a
+ * Clear-Halt on the bulk endpoints. The SINGLE_LUN flag will prevent
+ * us from sending the request.
+ */
+UNUSUAL_DEV( 0x059b, 0x0001, 0x0100, 0x0100,
+ "Iomega",
+ "ZIP 100",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_SINGLE_LUN ),
+
/* Reported by <Hendryk.Pfeiffer@gmx.de> */
UNUSUAL_DEV( 0x059f, 0x0643, 0x0000, 0x0000,
"LaCie",
@@ -1412,6 +1424,17 @@ UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64),
+/* Patch by Leonid Petrov mail at lpetrov.net
+ * Reported by Robert Spitzenpfeil <robert@spitzenpfeil.org>
+ * http://www.qbik.ch/usb/devices/showdev.php?id=1705
+ * Updated to 103 device by MJ Ray mjr at phonecoop.coop
+ */
+UNUSUAL_DEV( 0x0f19, 0x0103, 0x0100, 0x0100,
+ "Oracom Co., Ltd",
+ "ORC-200M",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
/* David Kuehling <dvdkhlng@gmx.de>:
* for MP3-Player AVOX WSX-300ER (bought in Japan). Reports lots of SCSI
* errors when trying to write.
@@ -1477,6 +1500,15 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110,
US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
0 ),
+/* Reported by Fabio Venturi <f.venturi@tdnet.it>
+ * The device reports a vendor-specific bDeviceClass.
+ */
+UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100,
+ "Actions Semiconductor",
+ "Mtp device",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 0),
+
/* Reported by Kevin Lloyd <linux@sierrawireless.com>
* Entry is needed for the initializer function override,
* which instructs the device to load as a modem
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index d775eb6590b..62f9c6e387c 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -1913,61 +1913,6 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
par->mmaped = 1;
return 0;
}
-
-static struct {
- u32 yoffset;
- u8 r[2][256];
- u8 g[2][256];
- u8 b[2][256];
-} atyfb_save;
-
-static void atyfb_save_palette(struct atyfb_par *par, int enter)
-{
- int i, tmp;
-
- for (i = 0; i < 256; i++) {
- tmp = aty_ld_8(DAC_CNTL, par) & 0xfc;
- if (M64_HAS(EXTRA_BRIGHT))
- tmp |= 0x2;
- aty_st_8(DAC_CNTL, tmp, par);
- aty_st_8(DAC_MASK, 0xff, par);
-
- aty_st_8(DAC_R_INDEX, i, par);
- atyfb_save.r[enter][i] = aty_ld_8(DAC_DATA, par);
- atyfb_save.g[enter][i] = aty_ld_8(DAC_DATA, par);
- atyfb_save.b[enter][i] = aty_ld_8(DAC_DATA, par);
- aty_st_8(DAC_W_INDEX, i, par);
- aty_st_8(DAC_DATA, atyfb_save.r[1 - enter][i], par);
- aty_st_8(DAC_DATA, atyfb_save.g[1 - enter][i], par);
- aty_st_8(DAC_DATA, atyfb_save.b[1 - enter][i], par);
- }
-}
-
-static void atyfb_palette(int enter)
-{
- struct atyfb_par *par;
- struct fb_info *info;
- int i;
-
- for (i = 0; i < FB_MAX; i++) {
- info = registered_fb[i];
- if (info && info->fbops == &atyfb_ops) {
- par = (struct atyfb_par *) info->par;
-
- atyfb_save_palette(par, enter);
- if (enter) {
- atyfb_save.yoffset = info->var.yoffset;
- info->var.yoffset = 0;
- set_off_pitch(par, info);
- } else {
- info->var.yoffset = atyfb_save.yoffset;
- set_off_pitch(par, info);
- }
- aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
- break;
- }
- }
-}
#endif /* __sparc__ */
@@ -2670,10 +2615,6 @@ static int __devinit aty_init(struct fb_info *info)
goto aty_init_exit;
}
-#ifdef __sparc__
- atyfb_save_palette(par, 0);
-#endif
-
#ifdef CONFIG_FB_ATY_CT
if (!noaccel && M64_HAS(INTEGRATED))
aty_init_cursor(info);
@@ -2900,8 +2841,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
#ifdef __sparc__
-extern void (*prom_palette) (int);
-
static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
struct fb_info *info, unsigned long addr)
{
@@ -3536,9 +3475,6 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
goto err_release_io;
#ifdef __sparc__
- if (!prom_palette)
- prom_palette = atyfb_palette;
-
/*
* Add /dev/fb mmap values.
*/
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 41f6dbf61be..fdc9f43ec30 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/fb.h>
#include <linux/mm.h>
+#include <linux/uaccess.h>
#include <asm/io.h>
#include <asm/prom.h>
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 6796ba62c3c..777389c4098 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -459,7 +459,7 @@ static int chipsfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
if (state.event == pdev->dev.power.power_state.event)
return 0;
- if (state.event != PM_EVENT_SUSPEND)
+ if (!(state.event & PM_EVENT_SLEEP))
goto done;
acquire_console_sem();
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index 756c0ce8591..392a8be6aa7 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -403,7 +403,7 @@ static int __init hitfb_probe(struct platform_device *dev)
return 0;
}
-static int __devexit hitfb_remove(struct platform_device *dev)
+static int __exit hitfb_remove(struct platform_device *dev)
{
return unregister_framebuffer(&fb_info);
}
@@ -439,7 +439,7 @@ static int hitfb_resume(struct platform_device *dev)
static struct platform_driver hitfb_driver = {
.probe = hitfb_probe,
- .remove = __devexit_p(hitfb_remove),
+ .remove = __exit_p(hitfb_remove),
#ifdef CONFIG_PM
.suspend = hitfb_suspend,
.resume = hitfb_resume,
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 74517b1b26a..596652d2831 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1066,7 +1066,7 @@ static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t mesg)
acquire_console_sem();
par->pm_state = mesg.event;
- if (mesg.event == PM_EVENT_SUSPEND) {
+ if (mesg.event & PM_EVENT_SLEEP) {
fb_set_suspend(info, 1);
nvidiafb_blank(FB_BLANK_POWERDOWN, info);
nvidia_write_regs(par, &par->SavedReg);
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 6a3d0b57489..8c863a7f654 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -1,16 +1,12 @@
-/* drivers/video/pvr2fb.c
+/*
+ * drivers/video/pvr2fb.c
*
* Frame buffer and fbcon support for the NEC PowerVR2 found within the Sega
* Dreamcast.
*
* Copyright (c) 2001 M. R. Brown <mrbrown@0xd6.org>
- * Copyright (c) 2001, 2002, 2003, 2004, 2005 Paul Mundt <lethal@linux-sh.org>
- *
- * This file is part of the LinuxDC project (linuxdc.sourceforge.net).
+ * Copyright (c) 2001 - 2008 Paul Mundt <lethal@linux-sh.org>
*
- */
-
-/*
* This driver is mostly based on the excellent amifb and vfb sources. It uses
* an odd scheme for converting hardware values to/from framebuffer values,
* here are some hacked-up formulas:
@@ -490,7 +486,7 @@ static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
} else {
var->sync &= ~FB_SYNC_BROADCAST;
var->vmode &= ~FB_VMODE_INTERLACED;
- var->vmode |= pvr2_var.vmode;
+ var->vmode |= FB_VMODE_NONINTERLACED;
}
if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_TEST) {
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 10f912df2da..97facb121c7 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1046,7 +1046,7 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data)
switch (val) {
case CPUFREQ_ADJUST:
case CPUFREQ_INCOMPATIBLE:
- printk(KERN_DEBUG "min dma period: %d ps, "
+ pr_debug("min dma period: %d ps, "
"new clock %d kHz\n", pxafb_display_dma_period(var),
policy->max);
// TODO: fill in min/max values
@@ -1361,7 +1361,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
}
#endif
-int __init pxafb_probe(struct platform_device *dev)
+static int __init pxafb_probe(struct platform_device *dev)
{
struct pxafb_info *fbi;
struct pxafb_mach_info *inf;
@@ -1486,7 +1486,7 @@ static struct platform_driver pxafb_driver = {
};
#ifndef MODULE
-int __devinit pxafb_setup(char *options)
+static int __devinit pxafb_setup(char *options)
{
# ifdef CONFIG_FB_PXA_PARAMETERS
if (options)
@@ -1501,7 +1501,7 @@ MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)");
# endif
#endif
-int __devinit pxafb_init(void)
+static int __devinit pxafb_init(void)
{
#ifndef MODULE
char *option = NULL;
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 963a454b707..4deaac05b93 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -9,6 +9,7 @@
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/mm.h>
+#include <linux/uaccess.h>
#include <asm/oplib.h>
#include <asm/fbio.h>
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index e83dfba7e63..742b5c656d6 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -237,12 +237,14 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var,
/* check we can fit these values into the registers */
- if (var->hsync_len > 255 || var->vsync_len > 255)
+ if (var->hsync_len > 255 || var->vsync_len > 63)
return -EINVAL;
- if ((var->xres + var->right_margin) >= 4096)
+ /* hdisplay end and hsync start */
+ if ((var->xres + var->right_margin) > 4096)
return -EINVAL;
+ /* vdisplay end and vsync start */
if ((var->yres + var->lower_margin) > 2048)
return -EINVAL;
@@ -281,19 +283,21 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var,
var->blue.length = var->bits_per_pixel;
var->blue.offset = 0;
var->transp.length = 0;
+ var->transp.offset = 0;
break;
case 16:
if (sm->pdata->flags & SM501_FBPD_SWAP_FB_ENDIAN) {
- var->red.offset = 11;
- var->green.offset = 5;
- var->blue.offset = 0;
- } else {
var->blue.offset = 11;
var->green.offset = 5;
var->red.offset = 0;
+ } else {
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
}
+ var->transp.offset = 0;
var->red.length = 5;
var->green.length = 6;
@@ -397,7 +401,7 @@ static int sm501fb_set_par_common(struct fb_info *info,
break;
case 16:
- info->fix.visual = FB_VISUAL_DIRECTCOLOR;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
break;
case 32:
@@ -613,6 +617,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
case 16:
control |= SM501_DC_CRT_CONTROL_16BPP;
+ sm501fb_setup_gamma(fbi, SM501_DC_CRT_PALETTE);
break;
case 32:
@@ -750,6 +755,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
case 16:
control |= SM501_DC_PANEL_CONTROL_16BPP;
+ sm501fb_setup_gamma(fbi, SM501_DC_PANEL_PALETTE);
break;
case 32:
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 70fb4ee2b42..919ce75db9e 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -564,19 +564,46 @@ static inline void write3CE(int reg, unsigned char val)
t_outb(val, 0x3CF);
}
-static inline void enable_mmio(void)
+static void enable_mmio(void)
{
+ unsigned char tmp;
+
/* Goto New Mode */
outb(0x0B, 0x3C4);
inb(0x3C5);
/* Unprotect registers */
outb(NewMode1, 0x3C4);
+ tmp = inb(0x3C5);
outb(0x80, 0x3C5);
/* Enable MMIO */
outb(PCIReg, 0x3D4);
outb(inb(0x3D5) | 0x01, 0x3D5);
+
+ t_outb(NewMode1, 0x3C4);
+ t_outb(tmp, 0x3C5);
+}
+
+static void disable_mmio(void)
+{
+ unsigned char tmp;
+
+ /* Goto New Mode */
+ t_outb(0x0B, 0x3C4);
+ t_inb(0x3C5);
+
+ /* Unprotect registers */
+ t_outb(NewMode1, 0x3C4);
+ tmp = t_inb(0x3C5);
+ t_outb(0x80, 0x3C5);
+
+ /* Disable MMIO */
+ t_outb(PCIReg, 0x3D4);
+ t_outb(t_inb(0x3D5) & ~0x01, 0x3D5);
+
+ outb(NewMode1, 0x3C4);
+ outb(tmp, 0x3C5);
}
#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
@@ -1239,9 +1266,9 @@ static int __devinit trident_pci_probe(struct pci_dev * dev,
default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
if (!default_par.io_virt) {
- release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
debug("ioremap failed\n");
- return -1;
+ err = -1;
+ goto out_unmap1;
}
enable_mmio();
@@ -1252,25 +1279,21 @@ static int __devinit trident_pci_probe(struct pci_dev * dev,
if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) {
debug("request_mem_region failed!\n");
+ disable_mmio();
err = -1;
- goto out_unmap;
+ goto out_unmap1;
}
fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start,
tridentfb_fix.smem_len);
if (!fb_info.screen_base) {
- release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
debug("ioremap failed\n");
err = -1;
- goto out_unmap;
+ goto out_unmap2;
}
output("%s board found\n", pci_name(dev));
-#if 0
- output("Trident board found : mem = %X, io = %X, mem_v = %X, io_v = %X\n",
- tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt);
-#endif
displaytype = get_displaytype();
if (flatpanel)
@@ -1288,9 +1311,12 @@ static int __devinit trident_pci_probe(struct pci_dev * dev,
if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) {
err = -EINVAL;
- goto out_unmap;
+ goto out_unmap2;
}
- fb_alloc_cmap(&fb_info.cmap, 256, 0);
+ err = fb_alloc_cmap(&fb_info.cmap, 256, 0);
+ if (err < 0)
+ goto out_unmap2;
+
if (defaultaccel && acc)
default_var.accel_flags |= FB_ACCELF_TEXT;
else
@@ -1300,19 +1326,24 @@ static int __devinit trident_pci_probe(struct pci_dev * dev,
fb_info.device = &dev->dev;
if (register_framebuffer(&fb_info) < 0) {
printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n");
+ fb_dealloc_cmap(&fb_info.cmap);
err = -EINVAL;
- goto out_unmap;
+ goto out_unmap2;
}
output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
fb_info.node, fb_info.fix.id, default_var.xres,
default_var.yres, default_var.bits_per_pixel);
return 0;
-out_unmap:
- if (default_par.io_virt)
- iounmap(default_par.io_virt);
+out_unmap2:
if (fb_info.screen_base)
iounmap(fb_info.screen_base);
+ release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
+ disable_mmio();
+out_unmap1:
+ if (default_par.io_virt)
+ iounmap(default_par.io_virt);
+ release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
return err;
}
@@ -1323,7 +1354,7 @@ static void __devexit trident_pci_remove(struct pci_dev *dev)
iounmap(par->io_virt);
iounmap(fb_info.screen_base);
release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
- release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
+ release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
}
/* List of boards that we are trying to support */
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index be27b9c1ed7..93361656316 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -44,7 +44,7 @@ static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
static int mtrr __devinitdata = 3; /* enable mtrr by default */
static int blank = 1; /* enable blanking by default */
-static int ypan __devinitdata = 1; /* 0: scroll, 1: ypan, 2: ywrap */
+static int ypan = 1; /* 0: scroll, 1: ypan, 2: ywrap */
static int pmi_setpal __devinitdata = 1; /* use PMI for palette changes */
static int nocrtc __devinitdata; /* ignore CRTC settings */
static int noedid __devinitdata; /* don't try DDC transfers */
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 688e435b4d9..10211e49300 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -17,6 +17,7 @@
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/err.h>
#include <linux/delay.h>
#include <linux/ds1wm.h>
@@ -102,12 +103,12 @@ struct ds1wm_data {
static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg,
u8 val)
{
- __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift));
+ __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift));
}
static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg)
{
- return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift));
+ return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift));
}
@@ -149,8 +150,8 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
timeleft = wait_for_completion_timeout(&reset_done, DS1WM_TIMEOUT);
ds1wm_data->reset_complete = NULL;
if (!timeleft) {
- dev_dbg(&ds1wm_data->pdev->dev, "reset failed\n");
- return 1;
+ dev_err(&ds1wm_data->pdev->dev, "reset failed\n");
+ return 1;
}
/* Wait for the end of the reset. According to the specs, the time
@@ -167,11 +168,11 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
(ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0));
if (!ds1wm_data->slave_present) {
- dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n");
- return 1;
- }
+ dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n");
+ return 1;
+ }
- return 0;
+ return 0;
}
static int ds1wm_write(struct ds1wm_data *ds1wm_data, u8 data)
@@ -334,7 +335,7 @@ static int ds1wm_probe(struct platform_device *pdev)
if (!pdev)
return -ENODEV;
- ds1wm_data = kzalloc(sizeof (*ds1wm_data), GFP_KERNEL);
+ ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL);
if (!ds1wm_data)
return -ENOMEM;
@@ -374,8 +375,8 @@ static int ds1wm_probe(struct platform_device *pdev)
goto err1;
ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm");
- if (!ds1wm_data->clk) {
- ret = -ENOENT;
+ if (IS_ERR(ds1wm_data->clk)) {
+ ret = PTR_ERR(ds1wm_data->clk);
goto err2;
}
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index afcdc69e37d..254d115cafa 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -402,6 +402,18 @@ config IT8712F_WDT
To compile this driver as a module, choose M here: the
module will be called it8712f_wdt.
+config HP_WATCHDOG
+ tristate "HP Proliant iLO 2 Hardware Watchdog Timer"
+ depends on X86
+ help
+ A software monitoring watchdog and NMI sourcing driver. This driver
+ will detect lockups and provide stack trace. Also, when an NMI
+ occurs this driver will make the necessary BIOS calls to log
+ the cause of the NMI. This is a driver that will only load on a
+ HP ProLiant system with a minimum of iLO2 support.
+ To compile this driver as a module, choose M here: the
+ module will be called hpwdt.
+
config SC1200_WDT
tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
depends on X86
@@ -633,6 +645,19 @@ config WDT_RM9K_GPI
To compile this driver as a module, choose M here: the
module will be called rm9k_wdt.
+config SIBYTE_WDOG
+ tristate "Sibyte SoC hardware watchdog"
+ depends on CPU_SB1
+ help
+ Watchdog driver for the built in watchdog hardware in Sibyte
+ SoC processors. There are apparently two watchdog timers
+ on such processors; this driver supports only the first one,
+ because currently Linux only supports exporting one watchdog
+ to userspace.
+
+ To compile this driver as a loadable module, choose M here.
+ The module will be called sb_wdog.
+
config AR7_WDT
tristate "TI AR7 Watchdog Timer"
depends on AR7
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index ebc21146d40..f3fb170fe5c 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o
obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o
+obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o
obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
obj-$(CONFIG_PC87413_WDT) += pc87413_wdt.o
@@ -92,6 +93,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
obj-$(CONFIG_INDYDOG) += indydog.o
obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
+obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index 472be10f068..1237113dc14 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -29,6 +29,7 @@
#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
#define stampit() stamp("here i am")
+#define pr_init(fmt, args...) ({ static const __initdata char __fmt[] = fmt; printk(__fmt, ## args); })
#define WATCHDOG_NAME "bfin-wdt"
#define PFX WATCHDOG_NAME ": "
@@ -445,19 +446,19 @@ static int __init bfin_wdt_init(void)
ret = register_reboot_notifier(&bfin_wdt_notifier);
if (ret) {
- printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret);
+ pr_init(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret);
return ret;
}
ret = misc_register(&bfin_wdt_miscdev);
if (ret) {
- printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ pr_init(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
WATCHDOG_MINOR, ret);
unregister_reboot_notifier(&bfin_wdt_notifier);
return ret;
}
- printk(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n",
+ pr_init(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n",
timeout, nowayout);
return 0;
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
new file mode 100644
index 00000000000..a2e174b09fe
--- /dev/null
+++ b/drivers/watchdog/hpwdt.c
@@ -0,0 +1,926 @@
+/*
+ * HP WatchDog Driver
+ * based on
+ *
+ * SoftDog 0.05: A Software Watchdog Device
+ *
+ * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
+ * Thomas Mingarelli <thomas.mingarelli@hp.com>
+ *
+ * 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 published by the Free Software Foundation
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/kdebug.h>
+#include <linux/moduleparam.h>
+#include <linux/notifier.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+#include <linux/dmi.h>
+#include <linux/efi.h>
+#include <linux/string.h>
+#include <linux/bootmem.h>
+#include <linux/slab.h>
+#include <asm/dmi.h>
+#include <asm/desc.h>
+#include <asm/kdebug.h>
+
+#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */
+#define CRU_BIOS_SIGNATURE_VALUE 0x55524324
+#define PCI_BIOS32_PARAGRAPH_LEN 16
+#define PCI_ROM_BASE1 0x000F0000
+#define ROM_SIZE 0x10000
+
+struct bios32_service_dir {
+ u32 signature;
+ u32 entry_point;
+ u8 revision;
+ u8 length;
+ u8 checksum;
+ u8 reserved[5];
+};
+
+/*
+ * smbios_entry_point - defines SMBIOS entry point structure
+ *
+ * anchor[4] - anchor string (_SM_)
+ * checksum - checksum of the entry point structure
+ * length - length of the entry point structure
+ * major_ver - major version (02h for revision 2.1)
+ * minor_ver - minor version (01h for revision 2.1)
+ * max_struct_size - size of the largest SMBIOS structure
+ * revision - entry point structure revision implemented
+ * formatted_area[5] - reserved
+ * intermediate_anchor[5] - intermediate anchor string (_DMI_)
+ * intermediate_checksum - intermediate checksum
+ * table_length - structure table length
+ * table_address - structure table address
+ * table_num_structs - number of SMBIOS structures present
+ * bcd_revision - BCD revision
+ */
+struct smbios_entry_point {
+ u8 anchor[4];
+ u8 checksum;
+ u8 length;
+ u8 major_ver;
+ u8 minor_ver;
+ u16 max_struct_size;
+ u8 revision;
+ u8 formatted_area[5];
+ u8 intermediate_anchor[5];
+ u8 intermediate_checksum;
+ u16 table_length;
+ u64 table_address;
+ u16 table_num_structs;
+ u8 bcd_revision;
+};
+
+/* type 212 */
+struct smbios_cru64_info {
+ u8 type;
+ u8 byte_length;
+ u16 handle;
+ u32 signature;
+ u64 physical_address;
+ u32 double_length;
+ u32 double_offset;
+};
+#define SMBIOS_CRU64_INFORMATION 212
+
+struct cmn_registers {
+ union {
+ struct {
+ u8 ral;
+ u8 rah;
+ u16 rea2;
+ };
+ u32 reax;
+ } u1;
+ union {
+ struct {
+ u8 rbl;
+ u8 rbh;
+ u8 reb2l;
+ u8 reb2h;
+ };
+ u32 rebx;
+ } u2;
+ union {
+ struct {
+ u8 rcl;
+ u8 rch;
+ u16 rec2;
+ };
+ u32 recx;
+ } u3;
+ union {
+ struct {
+ u8 rdl;
+ u8 rdh;
+ u16 red2;
+ };
+ u32 redx;
+ } u4;
+
+ u32 resi;
+ u32 redi;
+ u16 rds;
+ u16 res;
+ u32 reflags;
+} __attribute__((packed));
+
+#define DEFAULT_MARGIN 30
+static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */
+static unsigned int reload; /* the computed soft_margin */
+static int nowayout = WATCHDOG_NOWAYOUT;
+static char expect_release;
+static unsigned long hpwdt_is_open;
+
+static void __iomem *pci_mem_addr; /* the PCI-memory address */
+static unsigned long __iomem *hpwdt_timer_reg;
+static unsigned long __iomem *hpwdt_timer_con;
+
+static DEFINE_SPINLOCK(rom_lock);
+
+static void *cru_rom_addr;
+
+static struct cmn_registers cmn_regs;
+
+static struct pci_device_id hpwdt_devices[] = {
+ {
+ .vendor = PCI_VENDOR_ID_COMPAQ,
+ .device = 0xB203,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
+ {0}, /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, hpwdt_devices);
+
+/*
+ * bios_checksum
+ */
+static int __devinit bios_checksum(const char __iomem *ptr, int len)
+{
+ char sum = 0;
+ int i;
+
+ /*
+ * calculate checksum of size bytes. This should add up
+ * to zero if we have a valid header.
+ */
+ for (i = 0; i < len; i++)
+ sum += ptr[i];
+
+ return ((sum == 0) && (len > 0));
+}
+
+#ifndef CONFIG_X86_64
+/* --32 Bit Bios------------------------------------------------------------ */
+
+#define HPWDT_ARCH 32
+
+asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
+ unsigned long *pRomEntry)
+{
+ asm("pushl %ebp \n\t"
+ "movl %esp, %ebp \n\t"
+ "pusha \n\t"
+ "pushf \n\t"
+ "push %es \n\t"
+ "push %ds \n\t"
+ "pop %es \n\t"
+ "movl 8(%ebp),%eax \n\t"
+ "movl 4(%eax),%ebx \n\t"
+ "movl 8(%eax),%ecx \n\t"
+ "movl 12(%eax),%edx \n\t"
+ "movl 16(%eax),%esi \n\t"
+ "movl 20(%eax),%edi \n\t"
+ "movl (%eax),%eax \n\t"
+ "push %cs \n\t"
+ "call *12(%ebp) \n\t"
+ "pushf \n\t"
+ "pushl %eax \n\t"
+ "movl 8(%ebp),%eax \n\t"
+ "movl %ebx,4(%eax) \n\t"
+ "movl %ecx,8(%eax) \n\t"
+ "movl %edx,12(%eax) \n\t"
+ "movl %esi,16(%eax) \n\t"
+ "movl %edi,20(%eax) \n\t"
+ "movw %ds,24(%eax) \n\t"
+ "movw %es,26(%eax) \n\t"
+ "popl %ebx \n\t"
+ "movl %ebx,(%eax) \n\t"
+ "popl %ebx \n\t"
+ "movl %ebx,28(%eax) \n\t"
+ "pop %es \n\t"
+ "popf \n\t"
+ "popa \n\t"
+ "leave \n\t" "ret");
+}
+
+/*
+ * cru_detect
+ *
+ * Routine Description:
+ * This function uses the 32-bit BIOS Service Directory record to
+ * search for a $CRU record.
+ *
+ * Return Value:
+ * 0 : SUCCESS
+ * <0 : FAILURE
+ */
+static int __devinit cru_detect(unsigned long map_entry,
+ unsigned long map_offset)
+{
+ void *bios32_map;
+ unsigned long *bios32_entrypoint;
+ unsigned long cru_physical_address;
+ unsigned long cru_length;
+ unsigned long physical_bios_base = 0;
+ unsigned long physical_bios_offset = 0;
+ int retval = -ENODEV;
+
+ bios32_map = ioremap(map_entry, (2 * PAGE_SIZE));
+
+ if (bios32_map == NULL)
+ return -ENODEV;
+
+ bios32_entrypoint = bios32_map + map_offset;
+
+ cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;
+
+ asminline_call(&cmn_regs, bios32_entrypoint);
+
+ if (cmn_regs.u1.ral != 0) {
+ printk(KERN_WARNING
+ "hpwdt: Call succeeded but with an error: 0x%x\n",
+ cmn_regs.u1.ral);
+ } else {
+ physical_bios_base = cmn_regs.u2.rebx;
+ physical_bios_offset = cmn_regs.u4.redx;
+ cru_length = cmn_regs.u3.recx;
+ cru_physical_address =
+ physical_bios_base + physical_bios_offset;
+
+ /* If the values look OK, then map it in. */
+ if ((physical_bios_base + physical_bios_offset)) {
+ cru_rom_addr =
+ ioremap(cru_physical_address, cru_length);
+ if (cru_rom_addr)
+ retval = 0;
+ }
+
+ printk(KERN_DEBUG "hpwdt: CRU Base Address: 0x%lx\n",
+ physical_bios_base);
+ printk(KERN_DEBUG "hpwdt: CRU Offset Address: 0x%lx\n",
+ physical_bios_offset);
+ printk(KERN_DEBUG "hpwdt: CRU Length: 0x%lx\n",
+ cru_length);
+ printk(KERN_DEBUG "hpwdt: CRU Mapped Address: 0x%x\n",
+ (unsigned int)&cru_rom_addr);
+ }
+ iounmap(bios32_map);
+ return retval;
+}
+
+/*
+ * bios32_present
+ *
+ * Routine Description:
+ * This function finds the 32-bit BIOS Service Directory
+ *
+ * Return Value:
+ * 0 : SUCCESS
+ * <0 : FAILURE
+ */
+static int __devinit bios32_present(const char __iomem *p)
+{
+ struct bios32_service_dir *bios_32_ptr;
+ int length;
+ unsigned long map_entry, map_offset;
+
+ bios_32_ptr = (struct bios32_service_dir *) p;
+
+ /*
+ * Search for signature by checking equal to the swizzled value
+ * instead of calling another routine to perform a strcmp.
+ */
+ if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) {
+ length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN;
+ if (bios_checksum(p, length)) {
+ /*
+ * According to the spec, we're looking for the
+ * first 4KB-aligned address below the entrypoint
+ * listed in the header. The Service Directory code
+ * is guaranteed to occupy no more than 2 4KB pages.
+ */
+ map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1);
+ map_offset = bios_32_ptr->entry_point - map_entry;
+
+ return cru_detect(map_entry, map_offset);
+ }
+ }
+ return -ENODEV;
+}
+
+static int __devinit detect_cru_service(void)
+{
+ char __iomem *p, *q;
+ int rc = -1;
+
+ /*
+ * Search from 0x0f0000 through 0x0fffff, inclusive.
+ */
+ p = ioremap(PCI_ROM_BASE1, ROM_SIZE);
+ if (p == NULL)
+ return -ENOMEM;
+
+ for (q = p; q < p + ROM_SIZE; q += 16) {
+ rc = bios32_present(q);
+ if (!rc)
+ break;
+ }
+ iounmap(p);
+ return rc;
+}
+
+#else
+/* --64 Bit Bios------------------------------------------------------------ */
+
+#define HPWDT_ARCH 64
+
+asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
+ unsigned long *pRomEntry)
+{
+ asm("pushq %rbp \n\t"
+ "movq %rsp, %rbp \n\t"
+ "pushq %rax \n\t"
+ "pushq %rbx \n\t"
+ "pushq %rdx \n\t"
+ "pushq %r12 \n\t"
+ "pushq %r9 \n\t"
+ "movq %rsi, %r12 \n\t"
+ "movq %rdi, %r9 \n\t"
+ "movl 4(%r9),%ebx \n\t"
+ "movl 8(%r9),%ecx \n\t"
+ "movl 12(%r9),%edx \n\t"
+ "movl 16(%r9),%esi \n\t"
+ "movl 20(%r9),%edi \n\t"
+ "movl (%r9),%eax \n\t"
+ "call *%r12 \n\t"
+ "pushfq \n\t"
+ "popq %r12 \n\t"
+ "popfq \n\t"
+ "movl %eax, (%r9) \n\t"
+ "movl %ebx, 4(%r9) \n\t"
+ "movl %ecx, 8(%r9) \n\t"
+ "movl %edx, 12(%r9) \n\t"
+ "movl %esi, 16(%r9) \n\t"
+ "movl %edi, 20(%r9) \n\t"
+ "movq %r12, %rax \n\t"
+ "movl %eax, 28(%r9) \n\t"
+ "popq %r9 \n\t"
+ "popq %r12 \n\t"
+ "popq %rdx \n\t"
+ "popq %rbx \n\t"
+ "popq %rax \n\t"
+ "leave \n\t" "ret");
+}
+
+/*
+ * dmi_find_cru
+ *
+ * Routine Description:
+ * This function checks wether or not a SMBIOS/DMI record is
+ * the 64bit CRU info or not
+ *
+ * Return Value:
+ * 0 : SUCCESS - if record found
+ * <0 : FAILURE - if record not found
+ */
+static void __devinit dmi_find_cru(const struct dmi_header *dm)
+{
+ struct smbios_cru64_info *smbios_cru64_ptr;
+ unsigned long cru_physical_address;
+
+ if (dm->type == SMBIOS_CRU64_INFORMATION) {
+ smbios_cru64_ptr = (struct smbios_cru64_info *) dm;
+ if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) {
+ cru_physical_address =
+ smbios_cru64_ptr->physical_address +
+ smbios_cru64_ptr->double_offset;
+ cru_rom_addr = ioremap(cru_physical_address,
+ smbios_cru64_ptr->double_length);
+ }
+ }
+}
+
+/*
+ * dmi_table
+ *
+ * Routine Description:
+ * Decode the SMBIOS/DMI table and check if we have a 64bit CRU record
+ * or not.
+ *
+ * We have to be cautious here. We have seen BIOSes with DMI pointers
+ * pointing to completely the wrong place for example
+ */
+static void __devinit dmi_table(u8 *buf, int len, int num,
+ void (*decode)(const struct dmi_header *))
+{
+ u8 *data = buf;
+ int i = 0;
+
+ /*
+ * Stop when we see all the items the table claimed to have
+ * OR we run off the end of the table (also happens)
+ */
+ while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
+ const struct dmi_header *dm = (const struct dmi_header *)data;
+
+ /*
+ * We want to know the total length (formated area and strings)
+ * before decoding to make sure we won't run off the table in
+ * dmi_decode or dmi_string
+ */
+ data += dm->length;
+ while ((data - buf < len - 1) && (data[0] || data[1]))
+ data++;
+ if (data - buf < len - 1)
+ decode(dm);
+ data += 2;
+ i++;
+ }
+}
+
+/*
+ * smbios_present
+ *
+ * Routine Description:
+ * This function parses the SMBIOS entry point table to retrieve
+ * the 64 bit CRU Service.
+ *
+ * Return Value:
+ * 0 : SUCCESS
+ * <0 : FAILURE
+ */
+static int __devinit smbios_present(const char __iomem *p)
+{
+ struct smbios_entry_point *eps =
+ (struct smbios_entry_point *) p;
+ int length;
+ u8 *buf;
+
+ /* check if we have indeed the SMBIOS table entry point */
+ if ((strncmp((char *)eps->anchor, "_SM_",
+ sizeof(eps->anchor))) == 0) {
+ length = eps->length;
+
+ /* SMBIOS v2.1 implementation might use 0x1e */
+ if ((length == 0x1e) &&
+ (eps->major_ver == 2) &&
+ (eps->minor_ver == 1))
+ length = 0x1f;
+
+ /*
+ * Now we will check:
+ * - SMBIOS checksum must be 0
+ * - intermediate anchor should be _DMI_
+ * - intermediate checksum should be 0
+ */
+ if ((bios_checksum(p, length)) &&
+ (strncmp((char *)eps->intermediate_anchor, "_DMI_",
+ sizeof(eps->intermediate_anchor)) == 0) &&
+ (bios_checksum(p+0x10, 15))) {
+ buf = ioremap(eps->table_address, eps->table_length);
+ if (buf == NULL)
+ return -ENODEV;
+
+
+ /* Scan the DMI table for the 64 bit CRU service */
+ dmi_table(buf, eps->table_length,
+ eps->table_num_structs, dmi_find_cru);
+
+ iounmap(buf);
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+static int __devinit smbios_scan_machine(void)
+{
+ char __iomem *p, *q;
+ int rc;
+
+ if (efi_enabled) {
+ if (efi.smbios == EFI_INVALID_TABLE_ADDR)
+ return -ENODEV;
+
+ p = ioremap(efi.smbios, 32);
+ if (p == NULL)
+ return -ENOMEM;
+
+ rc = smbios_present(p);
+ iounmap(p);
+ } else {
+ /*
+ * Search from 0x0f0000 through 0x0fffff, inclusive.
+ */
+ p = ioremap(PCI_ROM_BASE1, ROM_SIZE);
+ if (p == NULL)
+ return -ENOMEM;
+
+ for (q = p; q < p + ROM_SIZE; q += 16) {
+ rc = smbios_present(q);
+ if (!rc) {
+ break;
+ }
+ }
+ iounmap(p);
+ }
+}
+
+static int __devinit detect_cru_service(void)
+{
+ cru_rom_addr = NULL;
+
+ smbios_scan_machine(); /* will become dmi_walk(dmi_find_cru); */
+
+ /* if cru_rom_addr has been set then we found a CRU service */
+ return ((cru_rom_addr != NULL)? 0: -ENODEV);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#endif
+
+/*
+ * NMI Handler
+ */
+static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
+ void *data)
+{
+ static unsigned long rom_pl;
+ static int die_nmi_called;
+
+ if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI)
+ return NOTIFY_OK;
+
+ spin_lock_irqsave(&rom_lock, rom_pl);
+ if (!die_nmi_called)
+ asminline_call(&cmn_regs, cru_rom_addr);
+ die_nmi_called = 1;
+ spin_unlock_irqrestore(&rom_lock, rom_pl);
+ if (cmn_regs.u1.ral == 0) {
+ printk(KERN_WARNING "hpwdt: An NMI occurred, "
+ "but unable to determine source.\n");
+ } else {
+ panic("An NMI occurred, please see the Integrated "
+ "Management Log for details.\n");
+ }
+
+ return NOTIFY_STOP;
+}
+
+/*
+ * Watchdog operations
+ */
+static void hpwdt_start(void)
+{
+ reload = (soft_margin * 1000) / 128;
+ iowrite16(reload, hpwdt_timer_reg);
+ iowrite16(0x85, hpwdt_timer_con);
+}
+
+static void hpwdt_stop(void)
+{
+ unsigned long data;
+
+ data = ioread16(hpwdt_timer_con);
+ data &= 0xFE;
+ iowrite16(data, hpwdt_timer_con);
+}
+
+static void hpwdt_ping(void)
+{
+ iowrite16(reload, hpwdt_timer_reg);
+}
+
+static int hpwdt_change_timer(int new_margin)
+{
+ /* Arbitrary, can't find the card's limits */
+ if (new_margin < 30 || new_margin > 600) {
+ printk(KERN_WARNING
+ "hpwdt: New value passed in is invalid: %d seconds.\n",
+ new_margin);
+ return -EINVAL;
+ }
+
+ soft_margin = new_margin;
+ printk(KERN_DEBUG
+ "hpwdt: New timer passed in is %d seconds.\n",
+ new_margin);
+ reload = (soft_margin * 1000) / 128;
+
+ return 0;
+}
+
+/*
+ * /dev/watchdog handling
+ */
+static int hpwdt_open(struct inode *inode, struct file *file)
+{
+ /* /dev/watchdog can only be opened once */
+ if (test_and_set_bit(0, &hpwdt_is_open))
+ return -EBUSY;
+
+ /* Start the watchdog */
+ hpwdt_start();
+ hpwdt_ping();
+
+ return nonseekable_open(inode, file);
+}
+
+static int hpwdt_release(struct inode *inode, struct file *file)
+{
+ /* Stop the watchdog */
+ if (expect_release == 42) {
+ hpwdt_stop();
+ } else {
+ printk(KERN_CRIT
+ "hpwdt: Unexpected close, not stopping watchdog!\n");
+ hpwdt_ping();
+ }
+
+ expect_release = 0;
+
+ /* /dev/watchdog is being closed, make sure it can be re-opened */
+ clear_bit(0, &hpwdt_is_open);
+
+ return 0;
+}
+
+static ssize_t hpwdt_write(struct file *file, const char __user *data,
+ size_t len, loff_t *ppos)
+{
+ /* See if we got the magic character 'V' and reload the timer */
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ /* note: just in case someone wrote the magic character
+ * five months ago... */
+ expect_release = 0;
+
+ /* scan to see whether or not we got the magic char. */
+ for (i = 0; i != len; i++) {
+ char c;
+ if (get_user(c, data+i))
+ return -EFAULT;
+ if (c == 'V')
+ expect_release = 42;
+ }
+ }
+
+ /* someone wrote to us, we should reload the timer */
+ hpwdt_ping();
+ }
+
+ return len;
+}
+
+static struct watchdog_info ident = {
+ .options = WDIOF_SETTIMEOUT |
+ WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+ .identity = "HP iLO2 HW Watchdog Timer",
+};
+
+static long hpwdt_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int new_margin;
+ int ret = -ENOTTY;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ ret = 0;
+ if (copy_to_user(argp, &ident, sizeof(ident)))
+ ret = -EFAULT;
+ break;
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ ret = put_user(0, p);
+ break;
+
+ case WDIOC_KEEPALIVE:
+ hpwdt_ping();
+ ret = 0;
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ ret = get_user(new_margin, p);
+ if (ret)
+ break;
+
+ ret = hpwdt_change_timer(new_margin);
+ if (ret)
+ break;
+
+ hpwdt_ping();
+ /* Fall */
+ case WDIOC_GETTIMEOUT:
+ ret = put_user(soft_margin, p);
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Kernel interfaces
+ */
+static struct file_operations hpwdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = hpwdt_write,
+ .unlocked_ioctl = hpwdt_ioctl,
+ .open = hpwdt_open,
+ .release = hpwdt_release,
+};
+
+static struct miscdevice hpwdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &hpwdt_fops,
+};
+
+static struct notifier_block die_notifier = {
+ .notifier_call = hpwdt_pretimeout,
+ .priority = 0x7FFFFFFF,
+};
+
+/*
+ * Init & Exit
+ */
+
+static int __devinit hpwdt_init_one(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ int retval;
+
+ /*
+ * First let's find out if we are on an iLO2 server. We will
+ * not run on a legacy ASM box.
+ */
+ if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) {
+ dev_warn(&dev->dev,
+ "This server does not have an iLO2 ASIC.\n");
+ return -ENODEV;
+ }
+
+ if (pci_enable_device(dev)) {
+ dev_warn(&dev->dev,
+ "Not possible to enable PCI Device: 0x%x:0x%x.\n",
+ ent->vendor, ent->device);
+ return -ENODEV;
+ }
+
+ pci_mem_addr = pci_iomap(dev, 1, 0x80);
+ if (!pci_mem_addr) {
+ dev_warn(&dev->dev,
+ "Unable to detect the iLO2 server memory.\n");
+ retval = -ENOMEM;
+ goto error_pci_iomap;
+ }
+ hpwdt_timer_reg = pci_mem_addr + 0x70;
+ hpwdt_timer_con = pci_mem_addr + 0x72;
+
+ /* Make sure that we have a valid soft_margin */
+ if (hpwdt_change_timer(soft_margin))
+ hpwdt_change_timer(DEFAULT_MARGIN);
+
+ /*
+ * We need to map the ROM to get the CRU service.
+ * For 32 bit Operating Systems we need to go through the 32 Bit
+ * BIOS Service Directory
+ * For 64 bit Operating Systems we get that service through SMBIOS.
+ */
+ retval = detect_cru_service();
+ if (retval < 0) {
+ dev_warn(&dev->dev,
+ "Unable to detect the %d Bit CRU Service.\n",
+ HPWDT_ARCH);
+ goto error_get_cru;
+ }
+
+ /*
+ * We know this is the only CRU call we need to make so lets keep as
+ * few instructions as possible once the NMI comes in.
+ */
+ cmn_regs.u1.rah = 0x0D;
+ cmn_regs.u1.ral = 0x02;
+
+ retval = register_die_notifier(&die_notifier);
+ if (retval != 0) {
+ dev_warn(&dev->dev,
+ "Unable to register a die notifier (err=%d).\n",
+ retval);
+ goto error_die_notifier;
+ }
+
+ retval = misc_register(&hpwdt_miscdev);
+ if (retval < 0) {
+ dev_warn(&dev->dev,
+ "Unable to register miscdev on minor=%d (err=%d).\n",
+ WATCHDOG_MINOR, retval);
+ goto error_misc_register;
+ }
+
+ printk(KERN_INFO
+ "hp Watchdog Timer Driver: 1.00"
+ ", timer margin: %d seconds( nowayout=%d).\n",
+ soft_margin, nowayout);
+
+ return 0;
+
+error_misc_register:
+ unregister_die_notifier(&die_notifier);
+error_die_notifier:
+ if (cru_rom_addr)
+ iounmap(cru_rom_addr);
+error_get_cru:
+ pci_iounmap(dev, pci_mem_addr);
+error_pci_iomap:
+ pci_disable_device(dev);
+ return retval;
+}
+
+static void __devexit hpwdt_exit(struct pci_dev *dev)
+{
+ if (!nowayout)
+ hpwdt_stop();
+
+ misc_deregister(&hpwdt_miscdev);
+ unregister_die_notifier(&die_notifier);
+
+ if (cru_rom_addr)
+ iounmap(cru_rom_addr);
+ pci_iounmap(dev, pci_mem_addr);
+ pci_disable_device(dev);
+}
+
+static struct pci_driver hpwdt_driver = {
+ .name = "hpwdt",
+ .id_table = hpwdt_devices,
+ .probe = hpwdt_init_one,
+ .remove = __devexit_p(hpwdt_exit),
+};
+
+static void __exit hpwdt_cleanup(void)
+{
+ pci_unregister_driver(&hpwdt_driver);
+}
+
+static int __init hpwdt_init(void)
+{
+ return pci_register_driver(&hpwdt_driver);
+}
+
+MODULE_AUTHOR("Tom Mingarelli");
+MODULE_DESCRIPTION("hp watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
+module_param(soft_margin, int, 0);
+MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds");
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+module_init(hpwdt_init);
+module_exit(hpwdt_cleanup);
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index 98451747d3c..789831b3fa0 100644
--- a/drivers/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
@@ -45,10 +45,13 @@
#include <linux/completion.h>
#include <linux/jiffies.h>
#include <linux/watchdog.h>
+#include <linux/platform_device.h>
+
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/mach-au1x00/au1000.h>
+#include <asm/gpio.h>
#define MTX1_WDT_INTERVAL (5 * HZ)
@@ -61,6 +64,7 @@ static struct {
volatile int queue;
int default_ticks;
unsigned long inuse;
+ unsigned gpio;
} mtx1_wdt_device;
static void mtx1_wdt_trigger(unsigned long unused)
@@ -73,7 +77,8 @@ static void mtx1_wdt_trigger(unsigned long unused)
* toggle GPIO2_15
*/
tmp = au_readl(GPIO2_DIR);
- tmp = (tmp & ~(1<<15)) | ((~tmp) & (1<<15));
+ tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) |
+ ((~tmp) & (1 << mtx1_wdt_device.gpio));
au_writel (tmp, GPIO2_DIR);
if (mtx1_wdt_device.queue && ticks)
@@ -93,7 +98,7 @@ static void mtx1_wdt_start(void)
{
if (!mtx1_wdt_device.queue) {
mtx1_wdt_device.queue = 1;
- au_writel (au_readl(GPIO2_DIR) | (u32)(1<<15), GPIO2_DIR);
+ gpio_set_value(mtx1_wdt_device.gpio, 1);
mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
}
mtx1_wdt_device.running++;
@@ -103,7 +108,7 @@ static int mtx1_wdt_stop(void)
{
if (mtx1_wdt_device.queue) {
mtx1_wdt_device.queue = 0;
- au_writel (au_readl(GPIO2_DIR) & ~((u32)(1<<15)), GPIO2_DIR);
+ gpio_set_value(mtx1_wdt_device.gpio, 0);
}
ticks = mtx1_wdt_device.default_ticks;
@@ -197,10 +202,12 @@ static struct miscdevice mtx1_wdt_misc = {
};
-static int __init mtx1_wdt_init(void)
+static int mtx1_wdt_probe(struct platform_device *pdev)
{
int ret;
+ mtx1_wdt_device.gpio = pdev->resource[0].start;
+
if ((ret = misc_register(&mtx1_wdt_misc)) < 0) {
printk(KERN_ERR " mtx-1_wdt : failed to register\n");
return ret;
@@ -222,13 +229,30 @@ static int __init mtx1_wdt_init(void)
return 0;
}
-static void __exit mtx1_wdt_exit(void)
+static int mtx1_wdt_remove(struct platform_device *pdev)
{
if (mtx1_wdt_device.queue) {
mtx1_wdt_device.queue = 0;
wait_for_completion(&mtx1_wdt_device.stop);
}
misc_deregister(&mtx1_wdt_misc);
+ return 0;
+}
+
+static struct platform_driver mtx1_wdt = {
+ .probe = mtx1_wdt_probe,
+ .remove = mtx1_wdt_remove,
+ .driver.name = "mtx1-wdt",
+};
+
+static int __init mtx1_wdt_init(void)
+{
+ return platform_driver_register(&mtx1_wdt);
+}
+
+static void __exit mtx1_wdt_exit(void)
+{
+ platform_driver_unregister(&mtx1_wdt);
}
module_init(mtx1_wdt_init);
@@ -237,3 +261,4 @@ module_exit(mtx1_wdt_exit);
MODULE_AUTHOR("Michael Stickel, Florian Fainelli");
MODULE_DESCRIPTION("Driver for the MTX-1 watchdog");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
new file mode 100644
index 00000000000..b9443143369
--- /dev/null
+++ b/drivers/watchdog/sb_wdog.c
@@ -0,0 +1,353 @@
+/*
+ * Watchdog driver for SiByte SB1 SoCs
+ *
+ * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp <andy.sharp@onstor.com>
+ *
+ * This driver is intended to make the second of two hardware watchdogs
+ * on the Sibyte 12XX and 11XX SoCs available to the user. There are two
+ * such devices available on the SoC, but it seems that there isn't an
+ * enumeration class for watchdogs in Linux like there is for RTCs.
+ * The second is used rather than the first because it uses IRQ 1,
+ * thereby avoiding all that IRQ 0 problematic nonsense.
+ *
+ * I have not tried this driver on a 1480 processor; it might work
+ * just well enough to really screw things up.
+ *
+ * It is a simple timer, and there is an interrupt that is raised the
+ * first time the timer expires. The second time it expires, the chip
+ * is reset and there is no way to redirect that NMI. Which could
+ * be problematic in some cases where this chip is sitting on the HT
+ * bus and has just taken responsibility for providing a cache block.
+ * Since the reset can't be redirected to the external reset pin, it is
+ * possible that other HT connected processors might hang and not reset.
+ * For Linux, a soft reset would probably be even worse than a hard reset.
+ * There you have it.
+ *
+ * The timer takes 23 bits of a 64 bit register (?) as a count value,
+ * and decrements the count every microsecond, for a max value of
+ * 0x7fffff usec or about 8.3ish seconds.
+ *
+ * This watchdog borrows some user semantics from the softdog driver,
+ * in that if you close the fd, it leaves the watchdog running, unless
+ * you previously wrote a 'V' to the fd, in which case it disables
+ * the watchdog when you close the fd like some other drivers.
+ *
+ * Based on various other watchdog drivers, which are probably all
+ * loosely based on something Alan Cox wrote years ago.
+ *
+ * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ * http://www.redhat.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 1 or 2 as published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/reboot.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/interrupt.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+
+/*
+ * set the initial count value of a timer
+ *
+ * wdog is the iomem address of the cfg register
+ */
+void sbwdog_set(char __iomem *wdog, unsigned long t)
+{
+ __raw_writeb(0, wdog - 0x10);
+ __raw_writeq(t & 0x7fffffUL, wdog);
+}
+
+/*
+ * cause the timer to [re]load it's initial count and start counting
+ * all over again
+ *
+ * wdog is the iomem address of the cfg register
+ */
+void sbwdog_pet(char __iomem *wdog)
+{
+ __raw_writeb(__raw_readb(wdog) | 1, wdog);
+}
+
+static unsigned long sbwdog_gate; /* keeps it to one thread only */
+static char __iomem *kern_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_0));
+static char __iomem *user_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_1));
+static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */
+static int expect_close;
+
+static struct watchdog_info ident = {
+ .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .identity = "SiByte Watchdog",
+};
+
+/*
+ * Allow only a single thread to walk the dog
+ */
+static int sbwdog_open(struct inode *inode, struct file *file)
+{
+ nonseekable_open(inode, file);
+ if (test_and_set_bit(0, &sbwdog_gate)) {
+ return -EBUSY;
+ }
+ __module_get(THIS_MODULE);
+
+ /*
+ * Activate the timer
+ */
+ sbwdog_set(user_dog, timeout);
+ __raw_writeb(1, user_dog);
+
+ return 0;
+}
+
+/*
+ * Put the dog back in the kennel.
+ */
+static int sbwdog_release(struct inode *inode, struct file *file)
+{
+ if (expect_close == 42) {
+ __raw_writeb(0, user_dog);
+ module_put(THIS_MODULE);
+ } else {
+ printk(KERN_CRIT "%s: Unexpected close, not stopping watchdog!\n",
+ ident.identity);
+ sbwdog_pet(user_dog);
+ }
+ clear_bit(0, &sbwdog_gate);
+ expect_close = 0;
+
+ return 0;
+}
+
+/*
+ * 42 - the answer
+ */
+static ssize_t sbwdog_write(struct file *file, const char __user *data,
+ size_t len, loff_t *ppos)
+{
+ int i;
+
+ if (len) {
+ /*
+ * restart the timer
+ */
+ expect_close = 0;
+
+ for (i = 0; i != len; i++) {
+ char c;
+
+ if (get_user(c, data + i)) {
+ return -EFAULT;
+ }
+ if (c == 'V') {
+ expect_close = 42;
+ }
+ }
+ sbwdog_pet(user_dog);
+ }
+
+ return len;
+}
+
+static int sbwdog_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret = -ENOTTY;
+ unsigned long time;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ ret = copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
+ break;
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ ret = put_user(0, p);
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ ret = get_user(time, p);
+ if (ret) {
+ break;
+ }
+
+ time *= 1000000;
+ if (time > 0x7fffffUL) {
+ ret = -EINVAL;
+ break;
+ }
+ timeout = time;
+ sbwdog_set(user_dog, timeout);
+ sbwdog_pet(user_dog);
+
+ case WDIOC_GETTIMEOUT:
+ /*
+ * get the remaining count from the ... count register
+ * which is 1*8 before the config register
+ */
+ ret = put_user(__raw_readq(user_dog - 8) / 1000000, p);
+ break;
+
+ case WDIOC_KEEPALIVE:
+ sbwdog_pet(user_dog);
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Notifier for system down
+ */
+static int
+sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf)
+{
+ if (code == SYS_DOWN || code == SYS_HALT) {
+ /*
+ * sit and sit
+ */
+ __raw_writeb(0, user_dog);
+ __raw_writeb(0, kern_dog);
+ }
+
+ return NOTIFY_DONE;
+}
+
+static const struct file_operations sbwdog_fops =
+{
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = sbwdog_write,
+ .ioctl = sbwdog_ioctl,
+ .open = sbwdog_open,
+ .release = sbwdog_release,
+};
+
+static struct miscdevice sbwdog_miscdev =
+{
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &sbwdog_fops,
+};
+
+static struct notifier_block sbwdog_notifier = {
+ .notifier_call = sbwdog_notify_sys,
+};
+
+/*
+ * interrupt handler
+ *
+ * doesn't do a whole lot for user, but oh so cleverly written so kernel
+ * code can use it to re-up the watchdog, thereby saving the kernel from
+ * having to create and maintain a timer, just to tickle another timer,
+ * which is just so wrong.
+ */
+irqreturn_t sbwdog_interrupt(int irq, void *addr)
+{
+ unsigned long wd_init;
+ char *wd_cfg_reg = (char *)addr;
+ u8 cfg;
+
+ cfg = __raw_readb(wd_cfg_reg);
+ wd_init = __raw_readq(wd_cfg_reg - 8) & 0x7fffff;
+
+ /*
+ * if it's the second watchdog timer, it's for those users
+ */
+ if (wd_cfg_reg == user_dog) {
+ printk(KERN_CRIT
+ "%s in danger of initiating system reset in %ld.%01ld seconds\n",
+ ident.identity, wd_init / 1000000, (wd_init / 100000) % 10);
+ } else {
+ cfg |= 1;
+ }
+
+ __raw_writeb(cfg, wd_cfg_reg);
+
+ return IRQ_HANDLED;
+}
+
+static int __init sbwdog_init(void)
+{
+ int ret;
+
+ /*
+ * register a reboot notifier
+ */
+ ret = register_reboot_notifier(&sbwdog_notifier);
+ if (ret) {
+ printk (KERN_ERR "%s: cannot register reboot notifier (err=%d)\n",
+ ident.identity, ret);
+ return ret;
+ }
+
+ /*
+ * get the resources
+ */
+ ret = misc_register(&sbwdog_miscdev);
+ if (ret == 0) {
+ printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", ident.identity,
+ timeout / 1000000, (timeout / 100000) % 10);
+ }
+
+ ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED,
+ ident.identity, (void *)user_dog);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to request irq 1 - %d\n", ident.identity,
+ ret);
+ misc_deregister(&sbwdog_miscdev);
+ }
+
+ return ret;
+}
+
+static void __exit sbwdog_exit(void)
+{
+ misc_deregister(&sbwdog_miscdev);
+}
+
+module_init(sbwdog_init);
+module_exit(sbwdog_exit);
+
+MODULE_AUTHOR("Andrew Sharp <andy.sharp@onstor.com>");
+MODULE_DESCRIPTION("SiByte Watchdog");
+
+module_param(timeout, ulong, 0);
+MODULE_PARM_DESC(timeout,
+ "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)");
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
+/*
+ * example code that can be put in a platform code area to utilize the
+ * first watchdog timer for the kernels own purpose.
+
+ void
+platform_wd_setup(void)
+{
+ int ret;
+
+ ret = request_irq(0, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED,
+ "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0));
+ if (ret) {
+ printk(KERN_CRIT "Watchdog IRQ zero(0) failed to be requested - %d\n",
+ ret);
+ }
+}
+
+
+ */
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 41a958a7585..5e1a4fb5cac 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1424,6 +1424,18 @@ struct elf_note_info {
int thread_notes;
};
+/*
+ * When a regset has a writeback hook, we call it on each thread before
+ * dumping user memory. On register window machines, this makes sure the
+ * user memory backing the register data is up to date before we read it.
+ */
+static void do_thread_regset_writeback(struct task_struct *task,
+ const struct user_regset *regset)
+{
+ if (regset->writeback)
+ regset->writeback(task, regset, 1);
+}
+
static int fill_thread_core_info(struct elf_thread_core_info *t,
const struct user_regset_view *view,
long signr, size_t *total)
@@ -1445,6 +1457,8 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
sizeof(t->prstatus), &t->prstatus);
*total += notesize(&t->notes[0]);
+ do_thread_regset_writeback(t->task, &view->regsets[0]);
+
/*
* Each other regset might generate a note too. For each regset
* that has no core_note_type or is inactive, we leave t->notes[i]
@@ -1452,6 +1466,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
*/
for (i = 1; i < view->n; ++i) {
const struct user_regset *regset = &view->regsets[i];
+ do_thread_regset_writeback(t->task, regset);
if (regset->core_note_type &&
(!regset->active || regset->active(t->task, regset))) {
int ret;
diff --git a/fs/bio.c b/fs/bio.c
index 242e409dab4..3312fcc3c09 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -903,7 +903,7 @@ void bio_set_pages_dirty(struct bio *bio)
}
}
-void bio_release_pages(struct bio *bio)
+static void bio_release_pages(struct bio *bio)
{
struct bio_vec *bvec = bio->bi_io_vec;
int i;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 67fe72ce6ac..7d822fae776 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -31,6 +31,8 @@ struct bdev_inode {
struct inode vfs_inode;
};
+static const struct address_space_operations def_blk_aops;
+
static inline struct bdev_inode *BDEV_I(struct inode *inode)
{
return container_of(inode, struct bdev_inode, vfs_inode);
@@ -171,203 +173,6 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
iov, offset, nr_segs, blkdev_get_blocks, NULL);
}
-#if 0
-static void blk_end_aio(struct bio *bio, int error)
-{
- struct kiocb *iocb = bio->bi_private;
- atomic_t *bio_count = &iocb->ki_bio_count;
-
- if (bio_data_dir(bio) == READ)
- bio_check_pages_dirty(bio);
- else {
- bio_release_pages(bio);
- bio_put(bio);
- }
-
- /* iocb->ki_nbytes stores error code from LLDD */
- if (error)
- iocb->ki_nbytes = -EIO;
-
- if (atomic_dec_and_test(bio_count)) {
- if ((long)iocb->ki_nbytes < 0)
- aio_complete(iocb, iocb->ki_nbytes, 0);
- else
- aio_complete(iocb, iocb->ki_left, 0);
- }
-
- return 0;
-}
-
-#define VEC_SIZE 16
-struct pvec {
- unsigned short nr;
- unsigned short idx;
- struct page *page[VEC_SIZE];
-};
-
-#define PAGES_SPANNED(addr, len) \
- (DIV_ROUND_UP((addr) + (len), PAGE_SIZE) - (addr) / PAGE_SIZE);
-
-/*
- * get page pointer for user addr, we internally cache struct page array for
- * (addr, count) range in pvec to avoid frequent call to get_user_pages. If
- * internal page list is exhausted, a batch count of up to VEC_SIZE is used
- * to get next set of page struct.
- */
-static struct page *blk_get_page(unsigned long addr, size_t count, int rw,
- struct pvec *pvec)
-{
- int ret, nr_pages;
- if (pvec->idx == pvec->nr) {
- nr_pages = PAGES_SPANNED(addr, count);
- nr_pages = min(nr_pages, VEC_SIZE);
- down_read(&current->mm->mmap_sem);
- ret = get_user_pages(current, current->mm, addr, nr_pages,
- rw == READ, 0, pvec->page, NULL);
- up_read(&current->mm->mmap_sem);
- if (ret < 0)
- return ERR_PTR(ret);
- pvec->nr = ret;
- pvec->idx = 0;
- }
- return pvec->page[pvec->idx++];
-}
-
-/* return a page back to pvec array */
-static void blk_unget_page(struct page *page, struct pvec *pvec)
-{
- pvec->page[--pvec->idx] = page;
-}
-
-static ssize_t
-blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
- loff_t pos, unsigned long nr_segs)
-{
- struct inode *inode = iocb->ki_filp->f_mapping->host;
- unsigned blkbits = blksize_bits(bdev_hardsect_size(I_BDEV(inode)));
- unsigned blocksize_mask = (1 << blkbits) - 1;
- unsigned long seg = 0; /* iov segment iterator */
- unsigned long nvec; /* number of bio vec needed */
- unsigned long cur_off; /* offset into current page */
- unsigned long cur_len; /* I/O len of current page, up to PAGE_SIZE */
-
- unsigned long addr; /* user iovec address */
- size_t count; /* user iovec len */
- size_t nbytes = iocb->ki_nbytes = iocb->ki_left; /* total xfer size */
- loff_t size; /* size of block device */
- struct bio *bio;
- atomic_t *bio_count = &iocb->ki_bio_count;
- struct page *page;
- struct pvec pvec;
-
- pvec.nr = 0;
- pvec.idx = 0;
-
- if (pos & blocksize_mask)
- return -EINVAL;
-
- size = i_size_read(inode);
- if (pos + nbytes > size) {
- nbytes = size - pos;
- iocb->ki_left = nbytes;
- }
-
- /*
- * check first non-zero iov alignment, the remaining
- * iov alignment is checked inside bio loop below.
- */
- do {
- addr = (unsigned long) iov[seg].iov_base;
- count = min(iov[seg].iov_len, nbytes);
- if (addr & blocksize_mask || count & blocksize_mask)
- return -EINVAL;
- } while (!count && ++seg < nr_segs);
- atomic_set(bio_count, 1);
-
- while (nbytes) {
- /* roughly estimate number of bio vec needed */
- nvec = (nbytes + PAGE_SIZE - 1) / PAGE_SIZE;
- nvec = max(nvec, nr_segs - seg);
- nvec = min(nvec, (unsigned long) BIO_MAX_PAGES);
-
- /* bio_alloc should not fail with GFP_KERNEL flag */
- bio = bio_alloc(GFP_KERNEL, nvec);
- bio->bi_bdev = I_BDEV(inode);
- bio->bi_end_io = blk_end_aio;
- bio->bi_private = iocb;
- bio->bi_sector = pos >> blkbits;
-same_bio:
- cur_off = addr & ~PAGE_MASK;
- cur_len = PAGE_SIZE - cur_off;
- if (count < cur_len)
- cur_len = count;
-
- page = blk_get_page(addr, count, rw, &pvec);
- if (unlikely(IS_ERR(page)))
- goto backout;
-
- if (bio_add_page(bio, page, cur_len, cur_off)) {
- pos += cur_len;
- addr += cur_len;
- count -= cur_len;
- nbytes -= cur_len;
-
- if (count)
- goto same_bio;
- while (++seg < nr_segs) {
- addr = (unsigned long) iov[seg].iov_base;
- count = iov[seg].iov_len;
- if (!count)
- continue;
- if (unlikely(addr & blocksize_mask ||
- count & blocksize_mask)) {
- page = ERR_PTR(-EINVAL);
- goto backout;
- }
- count = min(count, nbytes);
- goto same_bio;
- }
- } else {
- blk_unget_page(page, &pvec);
- }
-
- /* bio is ready, submit it */
- if (rw == READ)
- bio_set_pages_dirty(bio);
- atomic_inc(bio_count);
- submit_bio(rw, bio);
- }
-
-completion:
- iocb->ki_left -= nbytes;
- nbytes = iocb->ki_left;
- iocb->ki_pos += nbytes;
-
- blk_run_address_space(inode->i_mapping);
- if (atomic_dec_and_test(bio_count))
- aio_complete(iocb, nbytes, 0);
-
- return -EIOCBQUEUED;
-
-backout:
- /*
- * back out nbytes count constructed so far for this bio,
- * we will throw away current bio.
- */
- nbytes += bio->bi_size;
- bio_release_pages(bio);
- bio_put(bio);
-
- /*
- * if no bio was submmitted, return the error code.
- * otherwise, proceed with pending I/O completion.
- */
- if (atomic_read(bio_count) == 1)
- return PTR_ERR(page);
- goto completion;
-}
-#endif
-
static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page, blkdev_get_block, wbc);
@@ -1334,7 +1139,7 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
return blkdev_ioctl(file->f_mapping->host, file, cmd, arg);
}
-const struct address_space_operations def_blk_aops = {
+static const struct address_space_operations def_blk_aops = {
.readpage = blkdev_readpage,
.writepage = blkdev_writepage,
.sync_page = block_sync_page,
diff --git a/fs/buffer.c b/fs/buffer.c
index 3ebccf4aa7e..ddfdd2c80bf 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -627,8 +627,7 @@ repeat:
}
/**
- * sync_mapping_buffers - write out and wait upon a mapping's "associated"
- * buffers
+ * sync_mapping_buffers - write out & wait upon a mapping's "associated" buffers
* @mapping: the mapping which wants those buffers written
*
* Starts I/O against the buffers at mapping->private_list, and waits upon
@@ -836,7 +835,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
smp_mb();
if (buffer_dirty(bh)) {
list_add(&bh->b_assoc_buffers,
- &bh->b_assoc_map->private_list);
+ &mapping->private_list);
bh->b_assoc_map = mapping;
}
spin_unlock(lock);
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index edd248367b3..dbd91461853 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -6,7 +6,9 @@ and sync so that events like out of disk space get reported properly on
cached files. Fix setxattr failure to certain Samba versions. Fix mount
of second share to disconnected server session (autoreconnect on this).
Add ability to modify cifs acls for handling chmod (when mounted with
-cifsacl flag).
+cifsacl flag). Fix prefixpath path separator so we can handle mounts
+with prefixpaths longer than one directory (one path component) when
+mounted to Windows servers.
Version 1.51
------------
diff --git a/fs/cifs/README b/fs/cifs/README
index c623e2f9c5d..50306229b0f 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -461,7 +461,7 @@ A partial list of the supported mount options follows:
cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for
the file. (EXPERIMENTAL)
servern Specify the server 's netbios name (RFC1001 name) to use
- when attempting to setup a session to the server. This is
+ when attempting to setup a session to the server.
This is needed for mounting to some older servers (such
as OS/2 or Windows 98 and Windows ME) since they do not
support a default server name. A server name can be up
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 73c4c419663..0228ed06069 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -98,8 +98,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
if (mid_entry->resp_buf) {
cifs_dump_detail(mid_entry->resp_buf);
cifs_dump_mem("existing buf: ",
- mid_entry->resp_buf,
- 62 /* fixme */);
+ mid_entry->resp_buf, 62);
}
}
}
@@ -439,7 +438,7 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
return length;
}
-#endif
+#endif /* STATS */
static struct proc_dir_entry *proc_fs_cifs;
read_proc_t cifs_txanchor_read;
@@ -482,7 +481,7 @@ cifs_proc_init(void)
cifs_stats_read, NULL);
if (pde)
pde->write_proc = cifs_stats_write;
-#endif
+#endif /* STATS */
pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
cifsFYI_read, NULL);
if (pde)
@@ -918,4 +917,12 @@ security_flags_write(struct file *file, const char __user *buffer,
/* BB should we turn on MAY flags for other MUST options? */
return count;
}
-#endif
+#else
+inline void cifs_proc_init(void)
+{
+}
+
+inline void cifs_proc_clean(void)
+{
+}
+#endif /* PROC_FS */
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index c26cd0d2c6d..5eb3b83bbfa 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -25,8 +25,11 @@
void cifs_dump_mem(char *label, void *data, int length);
#ifdef CONFIG_CIFS_DEBUG2
+#define DBG2 2
void cifs_dump_detail(struct smb_hdr *);
void cifs_dump_mids(struct TCP_Server_Info *);
+#else
+#define DBG2 0
#endif
extern int traceSMB; /* flag which enables the function below */
void dump_smb(struct smb_hdr *, int);
@@ -64,10 +67,10 @@ extern int cifsERROR;
* ---------
*/
#else /* _CIFS_DEBUG */
-#define cERROR(button,prspec)
-#define cEVENT(format,arg...)
+#define cERROR(button, prspec)
+#define cEVENT(format, arg...)
#define cFYI(button, prspec)
-#define cifserror(format,arg...)
+#define cifserror(format, arg...)
#endif /* _CIFS_DEBUG */
#endif /* _H_CIFS_DEBUG */
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 6ad44752996..7f883825341 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -286,7 +286,7 @@ static void dump_referral(const struct dfs_info3_param *ref)
cFYI(1, ("DFS: node path: %s", ref->node_name));
cFYI(1, ("DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type));
cFYI(1, ("DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag,
- ref->PathConsumed));
+ ref->path_consumed));
}
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index d543accc10d..6653e29637a 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -125,7 +125,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
#ifdef CONFIG_CIFS_DEBUG2
if (cifsFYI && !IS_ERR(spnego_key)) {
struct cifs_spnego_msg *msg = spnego_key->payload.data;
- cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024,
+ cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024U,
msg->secblob_len + msg->sesskey_len));
}
#endif /* CONFIG_CIFS_DEBUG2 */
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index b5903b89250..7d75272a6b3 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -32,7 +32,7 @@
*
*/
int
-cifs_strfromUCS_le(char *to, const __le16 * from,
+cifs_strfromUCS_le(char *to, const __le16 *from,
int len, const struct nls_table *codepage)
{
int i;
@@ -61,7 +61,7 @@ cifs_strfromUCS_le(char *to, const __le16 * from,
*
*/
int
-cifs_strtoUCS(__le16 * to, const char *from, int len,
+cifs_strtoUCS(__le16 *to, const char *from, int len,
const struct nls_table *codepage)
{
int charlen;
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index 614c11fcdcb..14eb9a2395d 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -254,7 +254,8 @@ UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2)
const wchar_t *anchor2 = ucs2;
while (*ucs1) {
- if (*ucs1 == *ucs2) { /* Partial match found */
+ if (*ucs1 == *ucs2) {
+ /* Partial match found */
ucs1++;
ucs2++;
} else {
@@ -279,7 +280,8 @@ UniToupper(register wchar_t uc)
{
register const struct UniCaseRange *rp;
- if (uc < sizeof (CifsUniUpperTable)) { /* Latin characters */
+ if (uc < sizeof(CifsUniUpperTable)) {
+ /* Latin characters */
return uc + CifsUniUpperTable[uc]; /* Use base tables */
} else {
rp = CifsUniUpperRange; /* Use range tables */
@@ -320,7 +322,8 @@ UniTolower(wchar_t uc)
{
register struct UniCaseRange *rp;
- if (uc < sizeof (UniLowerTable)) { /* Latin characters */
+ if (uc < sizeof(UniLowerTable)) {
+ /* Latin characters */
return uc + UniLowerTable[uc]; /* Use base tables */
} else {
rp = UniLowerRange; /* Use range tables */
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index a7035bd18e4..f93932c2177 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -46,8 +46,7 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
static const struct cifs_sid sid_everyone = {
1, 1, {0, 0, 0, 0, 0, 1}, {0} };
/* group users */
-static const struct cifs_sid sid_user =
- {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
+static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
int match_sid(struct cifs_sid *ctsid)
@@ -195,9 +194,9 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
/* For deny ACEs we change the mask so that subsequent allow access
control entries do not turn on the bits we are denying */
if (type == ACCESS_DENIED) {
- if (flags & GENERIC_ALL) {
+ if (flags & GENERIC_ALL)
*pbits_to_set &= ~S_IRWXUGO;
- }
+
if ((flags & GENERIC_WRITE) ||
((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
*pbits_to_set &= ~S_IWUGO;
@@ -216,9 +215,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
if (flags & GENERIC_ALL) {
*pmode |= (S_IRWXUGO & (*pbits_to_set));
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("all perms"));
-#endif
+ cFYI(DBG2, ("all perms"));
return;
}
if ((flags & GENERIC_WRITE) ||
@@ -231,9 +228,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
*pmode |= (S_IXUGO & (*pbits_to_set));
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("access flags 0x%x mode now 0x%x", flags, *pmode));
-#endif
+ cFYI(DBG2, ("access flags 0x%x mode now 0x%x", flags, *pmode));
return;
}
@@ -262,9 +257,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
if (mode & S_IXUGO)
*pace_flags |= SET_FILE_EXEC_RIGHTS;
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags));
-#endif
+ cFYI(DBG2, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags));
return;
}
@@ -358,11 +351,9 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
return;
}
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("DACL revision %d size %d num aces %d",
+ cFYI(DBG2, ("DACL revision %d size %d num aces %d",
le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
le32_to_cpu(pdacl->num_aces)));
-#endif
/* reset rwx permissions for user/group/other.
Also, if num_aces is 0 i.e. DACL has no ACEs,
@@ -381,10 +372,6 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
GFP_KERNEL);
-/* cifscred->cecount = pdacl->num_aces;
- cifscred->aces = kmalloc(num_aces *
- sizeof(struct cifs_ace *), GFP_KERNEL);*/
-
for (i = 0; i < num_aces; ++i) {
ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
#ifdef CONFIG_CIFS_DEBUG2
@@ -437,7 +424,7 @@ static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
&sid_everyone, nmode, S_IRWXO);
pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
- pndacl->num_aces = 3;
+ pndacl->num_aces = cpu_to_le32(3);
return (0);
}
@@ -495,13 +482,11 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
le32_to_cpu(pntsd->gsidoffset));
dacloffset = le32_to_cpu(pntsd->dacloffset);
dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
+ cFYI(DBG2, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
"sacloffset 0x%x dacloffset 0x%x",
pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
le32_to_cpu(pntsd->gsidoffset),
le32_to_cpu(pntsd->sacloffset), dacloffset));
-#endif
/* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
rc = parse_sid(owner_sid_ptr, end_of_acl);
if (rc)
@@ -636,9 +621,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
struct super_block *sb;
struct cifs_sb_info *cifs_sb;
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("set ACL for %s from mode 0x%x", path, inode->i_mode));
-#endif
+ cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode));
if (!inode)
return (rc);
@@ -669,9 +652,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
}
rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("SetCIFSACL rc = %d", rc));
-#endif
+ cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
if (unlock_file == TRUE)
atomic_dec(&open_file->wrtPending);
else
@@ -689,9 +670,7 @@ void acl_to_uid_mode(struct inode *inode, const char *path)
u32 acllen = 0;
int rc = 0;
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("converting ACL to mode for %s", path));
-#endif
+ cFYI(DBG2, ("converting ACL to mode for %s", path));
pntsd = get_cifs_acl(&acllen, inode, path);
/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
@@ -712,9 +691,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("set ACL from mode for %s", path));
-#endif
+ cFYI(DBG2, ("set ACL from mode for %s", path));
/* Get the security descriptor */
pntsd = get_cifs_acl(&acllen, inode, path);
@@ -736,16 +713,12 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
rc = build_sec_desc(pntsd, pnntsd, acllen, inode, nmode);
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("build_sec_desc rc: %d", rc));
-#endif
+ cFYI(DBG2, ("build_sec_desc rc: %d", rc));
if (!rc) {
/* Set the security descriptor */
rc = set_cifs_acl(pnntsd, acllen, inode, path);
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("set_cifs_acl rc: %d", rc));
-#endif
+ cFYI(DBG2, ("set_cifs_acl rc: %d", rc));
}
kfree(pnntsd);
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index fcc43422769..a04b17e5a9d 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -204,9 +204,8 @@ cifs_put_super(struct super_block *sb)
return;
}
rc = cifs_umount(sb, cifs_sb);
- if (rc) {
+ if (rc)
cERROR(1, ("cifs_umount failed with return code %d", rc));
- }
#ifdef CONFIG_CIFS_DFS_UPCALL
if (cifs_sb->mountdata) {
kfree(cifs_sb->mountdata);
@@ -461,7 +460,7 @@ int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
static struct quotactl_ops cifs_quotactl_ops = {
.set_xquota = cifs_xquota_set,
- .get_xquota = cifs_xquota_set,
+ .get_xquota = cifs_xquota_get,
.set_xstate = cifs_xstate_set,
.get_xstate = cifs_xstate_get,
};
@@ -472,9 +471,7 @@ static void cifs_umount_begin(struct vfsmount *vfsmnt, int flags)
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *tcon;
-#ifdef CONFIG_CIFS_DFS_UPCALL
dfs_shrink_umount_helper(vfsmnt);
-#endif /* CONFIG CIFS_DFS_UPCALL */
if (!(flags & MNT_FORCE))
return;
@@ -992,9 +989,7 @@ static int __init
init_cifs(void)
{
int rc = 0;
-#ifdef CONFIG_PROC_FS
cifs_proc_init();
-#endif
/* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */
INIT_LIST_HEAD(&GlobalSMBSessionList);
INIT_LIST_HEAD(&GlobalTreeConnectionList);
@@ -1095,19 +1090,15 @@ init_cifs(void)
out_destroy_inodecache:
cifs_destroy_inodecache();
out_clean_proc:
-#ifdef CONFIG_PROC_FS
cifs_proc_clean();
-#endif
return rc;
}
static void __exit
exit_cifs(void)
{
- cFYI(0, ("exit_cifs"));
-#ifdef CONFIG_PROC_FS
+ cFYI(DBG2, ("exit_cifs"));
cifs_proc_clean();
-#endif
#ifdef CONFIG_CIFS_DFS_UPCALL
unregister_key_type(&key_type_dns_resolver);
#endif
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 5d32d8ddc82..69a2e194254 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -454,7 +454,7 @@ struct dir_notify_req {
struct dfs_info3_param {
int flags; /* DFSREF_REFERRAL_SERVER, DFSREF_STORAGE_SERVER*/
- int PathConsumed;
+ int path_consumed;
int server_type;
int ref_flag;
char *path_name;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 2f09f565a3d..0af63e6b426 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -53,11 +53,11 @@ extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
struct kvec *, int /* nvec to send */,
int * /* type of buf returned */ , const int flags);
-extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
- struct cifsTconInfo *,
- struct smb_hdr * /* input */ ,
- struct smb_hdr * /* out */ ,
- int * /* bytes returned */);
+extern int SendReceiveBlockingLock(const unsigned int xid,
+ struct cifsTconInfo *ptcon,
+ struct smb_hdr *in_buf ,
+ struct smb_hdr *out_buf,
+ int *bytes_returned);
extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *);
extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
@@ -84,7 +84,7 @@ extern __u16 GetNextMid(struct TCP_Server_Info *server);
extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16,
struct cifsTconInfo *);
extern void DeleteOplockQEntry(struct oplock_q_entry *);
-extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
+extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601);
extern u64 cifs_UnixTimeToNT(struct timespec);
extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
@@ -104,7 +104,11 @@ extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
#ifdef CONFIG_CIFS_DFS_UPCALL
extern void dfs_shrink_umount_helper(struct vfsmount *vfsmnt);
-#endif
+#else
+static inline void dfs_shrink_umount_helper(struct vfsmount *vfsmnt)
+{
+}
+#endif /* DFS_UPCALL */
void cifs_proc_init(void);
void cifs_proc_clean(void);
@@ -175,11 +179,11 @@ extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
struct kstatfs *FSData);
extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon,
- const char *fileName, const FILE_BASIC_INFO * data,
+ const char *fileName, const FILE_BASIC_INFO *data,
const struct nls_table *nls_codepage,
int remap_special_chars);
extern int CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
- const FILE_BASIC_INFO * data, __u16 fid);
+ const FILE_BASIC_INFO *data, __u16 fid);
#if 0
extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
char *fileName, __u16 dos_attributes,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 9409524e4bf..30bbe448e26 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifssmb.c
*
- * Copyright (C) International Business Machines Corp., 2002,2007
+ * Copyright (C) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com)
*
* Contains the routines for constructing the SMB PDUs themselves
@@ -102,10 +102,12 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
to this tcon */
}
-/* If the return code is zero, this function must fill in request_buf pointer */
+/* Allocate and return pointer to an SMB request buffer, and set basic
+ SMB information in the SMB header. If the return code is zero, this
+ function must have filled in request_buf pointer */
static int
small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
- void **request_buf /* returned */)
+ void **request_buf)
{
int rc = 0;
@@ -363,7 +365,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
*response_buf = *request_buf;
header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
- wct /*wct */ );
+ wct);
if (tcon != NULL)
cifs_stats_inc(&tcon->num_smbs_sent);
@@ -523,7 +525,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
if (remain >= (MIN_TZ_ADJ / 2))
result += MIN_TZ_ADJ;
if (val < 0)
- result = - result;
+ result = -result;
server->timeAdj = result;
} else {
server->timeAdj = (int)tmp;
@@ -600,7 +602,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize),
(__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
server->maxRw = le32_to_cpu(pSMBr->MaxRawSize);
- cFYI(0, ("Max buf = %d", ses->server->maxBuf));
+ cFYI(DBG2, ("Max buf = %d", ses->server->maxBuf));
GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
server->capabilities = le32_to_cpu(pSMBr->Capabilities);
server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
@@ -868,9 +870,8 @@ PsxDelete:
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
+ if (rc)
cFYI(1, ("Posix delete returned %d", rc));
- }
cifs_buf_release(pSMB);
cifs_stats_inc(&tcon->num_deletes);
@@ -916,9 +917,8 @@ DelFileRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
cifs_stats_inc(&tcon->num_deletes);
- if (rc) {
+ if (rc)
cFYI(1, ("Error in RMFile = %d", rc));
- }
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
@@ -961,9 +961,8 @@ RmDirRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
cifs_stats_inc(&tcon->num_rmdirs);
- if (rc) {
+ if (rc)
cFYI(1, ("Error in RMDir = %d", rc));
- }
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
@@ -1005,9 +1004,8 @@ MkDirRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
cifs_stats_inc(&tcon->num_mkdirs);
- if (rc) {
+ if (rc)
cFYI(1, ("Error in Mkdir = %d", rc));
- }
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
@@ -1017,7 +1015,7 @@ MkDirRetry:
int
CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
- __u64 mode, __u16 * netfid, FILE_UNIX_BASIC_INFO *pRetData,
+ __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData,
__u32 *pOplock, const char *name,
const struct nls_table *nls_codepage, int remap)
{
@@ -1027,8 +1025,8 @@ CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
int rc = 0;
int bytes_returned = 0;
__u16 params, param_offset, offset, byte_count, count;
- OPEN_PSX_REQ * pdata;
- OPEN_PSX_RSP * psx_rsp;
+ OPEN_PSX_REQ *pdata;
+ OPEN_PSX_RSP *psx_rsp;
cFYI(1, ("In POSIX Create"));
PsxCreat:
@@ -1110,9 +1108,7 @@ PsxCreat:
/* check to make sure response data is there */
if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
pRetData->Type = cpu_to_le32(-1); /* unknown */
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("unknown type"));
-#endif
+ cFYI(DBG2, ("unknown type"));
} else {
if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
+ sizeof(FILE_UNIX_BASIC_INFO)) {
@@ -1169,8 +1165,8 @@ static __u16 convert_disposition(int disposition)
int
SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const int openDisposition,
- const int access_flags, const int create_options, __u16 * netfid,
- int *pOplock, FILE_ALL_INFO * pfile_info,
+ const int access_flags, const int create_options, __u16 *netfid,
+ int *pOplock, FILE_ALL_INFO *pfile_info,
const struct nls_table *nls_codepage, int remap)
{
int rc = -EACCES;
@@ -1221,8 +1217,8 @@ OldOpenRetry:
if (create_options & CREATE_OPTION_SPECIAL)
pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
- else
- pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */
+ else /* BB FIXME BB */
+ pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
/* if ((omode & S_IWUGO) == 0)
pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
@@ -1284,8 +1280,8 @@ OldOpenRetry:
int
CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const int openDisposition,
- const int access_flags, const int create_options, __u16 * netfid,
- int *pOplock, FILE_ALL_INFO * pfile_info,
+ const int access_flags, const int create_options, __u16 *netfid,
+ int *pOplock, FILE_ALL_INFO *pfile_info,
const struct nls_table *nls_codepage, int remap)
{
int rc = -EACCES;
@@ -1556,9 +1552,9 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
} /* else setting file size with write of zero bytes */
if (wct == 14)
byte_count = bytes_sent + 1; /* pad */
- else /* wct == 12 */ {
+ else /* wct == 12 */
byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
- }
+
pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
pSMB->hdr.smb_buf_length += byte_count;
@@ -1663,7 +1659,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
rc = -EIO;
*nbytes = 0;
} else {
- WRITE_RSP * pSMBr = (WRITE_RSP *)iov[0].iov_base;
+ WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
*nbytes = le16_to_cpu(pSMBr->CountHigh);
*nbytes = (*nbytes) << 16;
*nbytes += le16_to_cpu(pSMBr->Count);
@@ -1744,9 +1740,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
/* SMB buffer freed by function above */
}
cifs_stats_inc(&tcon->num_locks);
- if (rc) {
+ if (rc)
cFYI(1, ("Send error in Lock = %d", rc));
- }
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
@@ -1791,7 +1786,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
count = sizeof(struct cifs_posix_lock);
pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
+ pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
if (get_flag)
@@ -1972,9 +1967,8 @@ renameRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
cifs_stats_inc(&tcon->num_renames);
- if (rc) {
+ if (rc)
cFYI(1, ("Send error in rename = %d", rc));
- }
cifs_buf_release(pSMB);
@@ -2016,7 +2010,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
rename_info = (struct set_file_rename *) data_offset;
pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
+ pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
@@ -2052,9 +2046,8 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
cifs_stats_inc(&pTcon->num_t2renames);
- if (rc) {
+ if (rc)
cFYI(1, ("Send error in Rename (by file handle) = %d", rc));
- }
cifs_buf_release(pSMB);
@@ -2211,9 +2204,8 @@ createSymLinkRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
cifs_stats_inc(&tcon->num_symlinks);
- if (rc) {
+ if (rc)
cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc));
- }
if (pSMB)
cifs_buf_release(pSMB);
@@ -2299,9 +2291,8 @@ createHardLinkRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
cifs_stats_inc(&tcon->num_hardlinks);
- if (rc) {
+ if (rc)
cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc));
- }
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
@@ -2370,9 +2361,9 @@ winCreateHardLinkRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
cifs_stats_inc(&tcon->num_hardlinks);
- if (rc) {
+ if (rc)
cFYI(1, ("Send error in hard link (NT rename) = %d", rc));
- }
+
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
goto winCreateHardLinkRetry;
@@ -2968,9 +2959,8 @@ setAclRetry:
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
+ if (rc)
cFYI(1, ("Set POSIX ACL returned %d", rc));
- }
setACLerrorExit:
cifs_buf_release(pSMB);
@@ -2982,7 +2972,7 @@ setACLerrorExit:
/* BB fix tabs in this function FIXME BB */
int
CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
- const int netfid, __u64 * pExtAttrBits, __u64 *pMask)
+ const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
{
int rc = 0;
struct smb_t2_qfi_req *pSMB = NULL;
@@ -3000,7 +2990,7 @@ GetExtAttrRetry:
if (rc)
return rc;
- params = 2 /* level */ +2 /* fid */;
+ params = 2 /* level */ + 2 /* fid */;
pSMB->t2.TotalDataCount = 0;
pSMB->t2.MaxParameterCount = cpu_to_le16(4);
/* BB find exact max data count below from sess structure BB */
@@ -3071,7 +3061,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
{
int rc = 0;
int buf_type = 0;
- QUERY_SEC_DESC_REQ * pSMB;
+ QUERY_SEC_DESC_REQ *pSMB;
struct kvec iov[1];
cFYI(1, ("GetCifsACL"));
@@ -3101,7 +3091,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
if (rc) {
cFYI(1, ("Send error in QuerySecDesc = %d", rc));
} else { /* decode response */
- __le32 * parm;
+ __le32 *parm;
__u32 parm_len;
__u32 acl_len;
struct smb_com_ntransact_rsp *pSMBr;
@@ -3230,8 +3220,8 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
FILE_ALL_INFO *pFinfo,
const struct nls_table *nls_codepage, int remap)
{
- QUERY_INFORMATION_REQ * pSMB;
- QUERY_INFORMATION_RSP * pSMBr;
+ QUERY_INFORMATION_REQ *pSMB;
+ QUERY_INFORMATION_RSP *pSMBr;
int rc = 0;
int bytes_returned;
int name_len;
@@ -3263,9 +3253,11 @@ QInfRetry:
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cFYI(1, ("Send error in QueryInfo = %d", rc));
- } else if (pFinfo) { /* decode response */
+ } else if (pFinfo) {
struct timespec ts;
__u32 time = le32_to_cpu(pSMBr->last_write_time);
+
+ /* decode response */
/* BB FIXME - add time zone adjustment BB */
memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
ts.tv_nsec = 0;
@@ -3296,7 +3288,7 @@ QInfRetry:
int
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
- FILE_ALL_INFO * pFindData,
+ FILE_ALL_INFO *pFindData,
int legacy /* old style infolevel */,
const struct nls_table *nls_codepage, int remap)
{
@@ -3371,10 +3363,12 @@ QPathInfoRetry:
else if (pFindData) {
int size;
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- if (legacy) /* we do not read the last field, EAsize,
- fortunately since it varies by subdialect
- and on Set vs. Get, is two bytes or 4
- bytes depending but we don't care here */
+
+ /* On legacy responses we do not read the last field,
+ EAsize, fortunately since it varies by subdialect and
+ also note it differs on Set vs. Get, ie two bytes or 4
+ bytes depending but we don't care here */
+ if (legacy)
size = sizeof(FILE_INFO_STANDARD);
else
size = sizeof(FILE_ALL_INFO);
@@ -3476,85 +3470,6 @@ UnixQPathInfoRetry:
return rc;
}
-#if 0 /* function unused at present */
-int CIFSFindSingle(const int xid, struct cifsTconInfo *tcon,
- const char *searchName, FILE_ALL_INFO * findData,
- const struct nls_table *nls_codepage)
-{
-/* level 257 SMB_ */
- TRANSACTION2_FFIRST_REQ *pSMB = NULL;
- TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- int name_len;
- __u16 params, byte_count;
-
- cFYI(1, ("In FindUnique"));
-findUniqueRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, searchName, name_len);
- }
-
- params = 12 + name_len /* includes null */ ;
- pSMB->TotalDataCount = 0; /* no EAs */
- pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(
- offsetof(struct smb_com_transaction2_ffirst_req, InformationLevel)-4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1; /* one byte, no need to le convert */
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->SearchAttributes =
- cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
- ATTR_DIRECTORY);
- pSMB->SearchCount = cpu_to_le16(16); /* BB increase */
- pSMB->SearchFlags = cpu_to_le16(1);
- pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
- pSMB->SearchStorageType = 0; /* BB what should we set this to? BB */
- pSMB->hdr.smb_buf_length += byte_count;
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-
- if (rc) {
- cFYI(1, ("Send error in FindFileDirInfo = %d", rc));
- } else { /* decode response */
- cifs_stats_inc(&tcon->num_ffirst);
- /* BB fill in */
- }
-
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto findUniqueRetry;
-
- return rc;
-}
-#endif /* end unused (temporarily) function */
-
/* xid, tcon, searchName and codepage are input parms, rest are returned */
int
CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
@@ -3566,7 +3481,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
/* level 257 SMB_ */
TRANSACTION2_FFIRST_REQ *pSMB = NULL;
TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
- T2_FFIRST_RSP_PARMS * parms;
+ T2_FFIRST_RSP_PARMS *parms;
int rc = 0;
int bytes_returned = 0;
int name_len;
@@ -3697,7 +3612,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
{
TRANSACTION2_FNEXT_REQ *pSMB = NULL;
TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
- T2_FNEXT_RSP_PARMS * parms;
+ T2_FNEXT_RSP_PARMS *parms;
char *response_data;
int rc = 0;
int bytes_returned, name_len;
@@ -3836,9 +3751,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
pSMB->FileID = searchHandle;
pSMB->ByteCount = 0;
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
- if (rc) {
+ if (rc)
cERROR(1, ("Send error in FindClose = %d", rc));
- }
+
cifs_stats_inc(&tcon->num_fclose);
/* Since session is dead, search handle closed on server already */
@@ -3851,7 +3766,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
int
CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
- __u64 * inode_number,
+ __u64 *inode_number,
const struct nls_table *nls_codepage, int remap)
{
int rc = 0;
@@ -4560,9 +4475,8 @@ SETFSUnixRetry:
cERROR(1, ("Send error in SETFSUnixInfo = %d", rc));
} else { /* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if (rc) {
+ if (rc)
rc = -EIO; /* bad smb */
- }
}
cifs_buf_release(pSMB);
@@ -4744,9 +4658,8 @@ SetEOFRetry:
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
+ if (rc)
cFYI(1, ("SetPathInfo (file size) returned %d", rc));
- }
cifs_buf_release(pSMB);
@@ -4897,9 +4810,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
pSMB->ByteCount = cpu_to_le16(byte_count);
memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
- if (rc) {
+ if (rc)
cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
- }
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
@@ -4975,9 +4887,8 @@ SetTimesRetry:
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
+ if (rc)
cFYI(1, ("SetPathInfo (times) returned %d", rc));
- }
cifs_buf_release(pSMB);
@@ -5027,9 +4938,8 @@ SetAttrLgcyRetry:
pSMB->ByteCount = cpu_to_le16(name_len + 1);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
+ if (rc)
cFYI(1, ("Error in LegacySetAttr = %d", rc));
- }
cifs_buf_release(pSMB);
@@ -5138,9 +5048,8 @@ setPermsRetry:
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
+ if (rc)
cFYI(1, ("SetPathInfo (perms) returned %d", rc));
- }
if (pSMB)
cifs_buf_release(pSMB);
@@ -5615,9 +5524,8 @@ SetEARetry:
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
+ if (rc)
cFYI(1, ("SetPathInfo (EA) returned %d", rc));
- }
cifs_buf_release(pSMB);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 65d0ba72e78..8dbfa97cd18 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1722,8 +1722,15 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
originally at mount time */
if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
- if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0)
+ if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
+ if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
+ cERROR(1, ("POSIXPATH support change"));
cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
+ } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
+ cERROR(1, ("possible reconnect error"));
+ cERROR(1,
+ ("server disabled POSIX path support"));
+ }
}
cap &= CIFS_UNIX_CAP_MASK;
@@ -1753,9 +1760,8 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
CIFS_SB(sb)->rsize = 127 * 1024;
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("larger reads not supported by srv"));
-#endif
+ cFYI(DBG2,
+ ("larger reads not supported by srv"));
}
}
@@ -1792,6 +1798,26 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
}
}
+static void
+convert_delimiter(char *path, char delim)
+{
+ int i;
+ char old_delim;
+
+ if (path == NULL)
+ return;
+
+ if (delim == '/')
+ old_delim = '\\';
+ else
+ old_delim = '/';
+
+ for (i = 0; path[i] != '\0'; i++) {
+ if (path[i] == old_delim)
+ path[i] = delim;
+ }
+}
+
int
cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
char *mount_data, const char *devname)
@@ -2057,7 +2083,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb->prepath = volume_info.prepath;
if (cifs_sb->prepath) {
cifs_sb->prepathlen = strlen(cifs_sb->prepath);
- cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
+ /* we can not convert the / to \ in the path
+ separators in the prefixpath yet because we do not
+ know (until reset_cifs_unix_caps is called later)
+ whether POSIX PATH CAP is available. We normalize
+ the / to \ after reset_cifs_unix_caps is called */
volume_info.prepath = NULL;
} else
cifs_sb->prepathlen = 0;
@@ -2225,11 +2255,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
else
tcon->unix_ext = 0; /* server does not support them */
+ /* convert forward to back slashes in prepath here if needed */
+ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
+ convert_delimiter(cifs_sb->prepath,
+ CIFS_DIR_SEP(cifs_sb));
+
if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
cifs_sb->rsize = 1024 * 127;
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("no very large read support, rsize now 127K"));
-#endif
+ cFYI(DBG2,
+ ("no very large read support, rsize now 127K"));
}
if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
cifs_sb->wsize = min(cifs_sb->wsize,
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 699ec119840..4e83b47c4b3 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -3,7 +3,7 @@
*
* vfs operations that deal with dentries
*
- * Copyright (C) International Business Machines Corp., 2002,2007
+ * 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
@@ -111,16 +111,6 @@ cifs_bp_rename_retry:
return full_path;
}
-/* char * build_wildcard_path_from_dentry(struct dentry *direntry)
-{
- if(full_path == NULL)
- return full_path;
-
- full_path[namelen] = '\\';
- full_path[namelen+1] = '*';
- full_path[namelen+2] = 0;
-BB remove above eight lines BB */
-
/* Inode operations in similar order to how they appear in Linux file fs.h */
int
@@ -171,9 +161,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
disposition = FILE_OVERWRITE_IF;
else if ((oflags & O_CREAT) == O_CREAT)
disposition = FILE_OPEN_IF;
- else {
+ else
cFYI(1, ("Create flag not set in create function"));
- }
}
/* BB add processing to set equivalent of mode - e.g. via CreateX with
@@ -367,7 +356,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
int oplock = 0;
u16 fileHandle;
- FILE_ALL_INFO * buf;
+ FILE_ALL_INFO *buf;
cFYI(1, ("sfu compat create special file"));
@@ -534,9 +523,8 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
int isValid = 1;
if (direntry->d_inode) {
- if (cifs_revalidate(direntry)) {
+ if (cifs_revalidate(direntry))
return 0;
- }
} else {
cFYI(1, ("neg dentry 0x%p name = %s",
direntry, direntry->d_name.name));
diff --git a/fs/cifs/dns_resolve.h b/fs/cifs/dns_resolve.h
index 073fdc3db41..966e9288930 100644
--- a/fs/cifs/dns_resolve.h
+++ b/fs/cifs/dns_resolve.h
@@ -1,7 +1,7 @@
/*
* fs/cifs/dns_resolve.h -- DNS Resolver upcall management for CIFS DFS
* Handles host name to IP address resolution
- *
+ *
* Copyright (c) International Business Machines Corp., 2008
* Author(s): Steve French (sfrench@us.ibm.com)
*
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
index 995474c9088..7d1d5aa4c43 100644
--- a/fs/cifs/fcntl.c
+++ b/fs/cifs/fcntl.c
@@ -35,9 +35,8 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags)
/* No way on Linux VFS to ask to monitor xattr
changes (and no stream support either */
- if (fcntl_notify_flags & DN_ACCESS) {
+ if (fcntl_notify_flags & DN_ACCESS)
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
- }
if (fcntl_notify_flags & DN_MODIFY) {
/* What does this mean on directories? */
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE |
@@ -47,9 +46,8 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags)
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_LAST_WRITE;
}
- if (fcntl_notify_flags & DN_DELETE) {
+ if (fcntl_notify_flags & DN_DELETE)
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE;
- }
if (fcntl_notify_flags & DN_RENAME) {
/* BB review this - checking various server behaviors */
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 5f7c374ae89..fa849c91d32 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -353,9 +353,9 @@ static int cifs_reopen_file(struct file *file, int can_flush)
int disposition = FILE_OPEN;
__u16 netfid;
- if (file->private_data) {
+ if (file->private_data)
pCifsFile = (struct cifsFileInfo *)file->private_data;
- } else
+ else
return -EBADF;
xid = GetXid();
@@ -499,9 +499,8 @@ int cifs_close(struct inode *inode, struct file *file)
the struct would be in each open file,
but this should give enough time to
clear the socket */
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("close delay, write pending"));
-#endif /* DEBUG2 */
+ cFYI(DBG2,
+ ("close delay, write pending"));
msleep(timeout);
timeout *= 4;
}
@@ -1423,9 +1422,8 @@ static int cifs_writepage(struct page *page, struct writeback_control *wbc)
xid = GetXid();
/* BB add check for wbc flags */
page_cache_get(page);
- if (!PageUptodate(page)) {
+ if (!PageUptodate(page))
cFYI(1, ("ppw - page not up to date"));
- }
/*
* Set the "writeback" flag, and clear "dirty" in the radix tree.
@@ -1460,9 +1458,9 @@ static int cifs_commit_write(struct file *file, struct page *page,
cFYI(1, ("commit write for page %p up to position %lld for %d",
page, position, to));
spin_lock(&inode->i_lock);
- if (position > inode->i_size) {
+ if (position > inode->i_size)
i_size_write(inode, position);
- }
+
spin_unlock(&inode->i_lock);
if (!PageUptodate(page)) {
position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
@@ -1596,9 +1594,9 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
}
open_file = (struct cifsFileInfo *)file->private_data;
- if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
+ if ((file->f_flags & O_ACCMODE) == O_WRONLY)
cFYI(1, ("attempting read on write only file instance"));
- }
+
for (total_read = 0, current_offset = read_data;
read_size > total_read;
total_read += bytes_read, current_offset += bytes_read) {
@@ -1625,9 +1623,8 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
smb_read_data +
4 /* RFC1001 length field */ +
le16_to_cpu(pSMBr->DataOffset),
- bytes_read)) {
+ bytes_read))
rc = -EFAULT;
- }
if (buf_type == CIFS_SMALL_BUFFER)
cifs_small_buf_release(smb_read_data);
@@ -1814,9 +1811,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
pTcon = cifs_sb->tcon;
pagevec_init(&lru_pvec, 0);
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("rpages: num pages %d", num_pages));
-#endif
+ cFYI(DBG2, ("rpages: num pages %d", num_pages));
for (i = 0; i < num_pages; ) {
unsigned contig_pages;
struct page *tmp_page;
@@ -1849,10 +1844,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
/* Read size needs to be in multiples of one page */
read_size = min_t(const unsigned int, read_size,
cifs_sb->rsize & PAGE_CACHE_MASK);
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("rpages: read size 0x%x contiguous pages %d",
+ cFYI(DBG2, ("rpages: read size 0x%x contiguous pages %d",
read_size, contig_pages));
-#endif
rc = -EAGAIN;
while (rc == -EAGAIN) {
if ((open_file->invalidHandle) &&
@@ -2026,7 +2019,7 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
struct cifs_sb_info *cifs_sb;
cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
- if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
/* since no page cache to corrupt on directio
we can change size safely */
return 1;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b1a4a65eaa0..24eb4d39215 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -29,6 +29,130 @@
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
+
+static void cifs_set_ops(struct inode *inode)
+{
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+
+ switch (inode->i_mode & S_IFMT) {
+ case S_IFREG:
+ inode->i_op = &cifs_file_inode_ops;
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+ inode->i_fop = &cifs_file_direct_nobrl_ops;
+ else
+ inode->i_fop = &cifs_file_direct_ops;
+ } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+ inode->i_fop = &cifs_file_nobrl_ops;
+ else { /* not direct, send byte range locks */
+ inode->i_fop = &cifs_file_ops;
+ }
+
+
+ /* check if server can support readpages */
+ if (cifs_sb->tcon->ses->server->maxBuf <
+ PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
+ inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
+ else
+ inode->i_data.a_ops = &cifs_addr_ops;
+ break;
+ case S_IFDIR:
+ inode->i_op = &cifs_dir_inode_ops;
+ inode->i_fop = &cifs_dir_ops;
+ break;
+ case S_IFLNK:
+ inode->i_op = &cifs_symlink_inode_ops;
+ break;
+ default:
+ init_special_inode(inode, inode->i_mode, inode->i_rdev);
+ break;
+ }
+}
+
+static void cifs_unix_info_to_inode(struct inode *inode,
+ FILE_UNIX_BASIC_INFO *info, int force_uid_gid)
+{
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
+ __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes);
+ __u64 end_of_file = le64_to_cpu(info->EndOfFile);
+
+ inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(info->LastAccessTime));
+ inode->i_mtime =
+ cifs_NTtimeToUnix(le64_to_cpu(info->LastModificationTime));
+ inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(info->LastStatusChange));
+ inode->i_mode = le64_to_cpu(info->Permissions);
+
+ /*
+ * Since we set the inode type below we need to mask off
+ * to avoid strange results if bits set above.
+ */
+ inode->i_mode &= ~S_IFMT;
+ switch (le32_to_cpu(info->Type)) {
+ case UNIX_FILE:
+ inode->i_mode |= S_IFREG;
+ break;
+ case UNIX_SYMLINK:
+ inode->i_mode |= S_IFLNK;
+ break;
+ case UNIX_DIR:
+ inode->i_mode |= S_IFDIR;
+ break;
+ case UNIX_CHARDEV:
+ inode->i_mode |= S_IFCHR;
+ inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor),
+ le64_to_cpu(info->DevMinor) & MINORMASK);
+ break;
+ case UNIX_BLOCKDEV:
+ inode->i_mode |= S_IFBLK;
+ inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor),
+ le64_to_cpu(info->DevMinor) & MINORMASK);
+ break;
+ case UNIX_FIFO:
+ inode->i_mode |= S_IFIFO;
+ break;
+ case UNIX_SOCKET:
+ inode->i_mode |= S_IFSOCK;
+ break;
+ default:
+ /* safest to call it a file if we do not know */
+ inode->i_mode |= S_IFREG;
+ cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
+ break;
+ }
+
+ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) &&
+ !force_uid_gid)
+ inode->i_uid = cifs_sb->mnt_uid;
+ else
+ inode->i_uid = le64_to_cpu(info->Uid);
+
+ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) &&
+ !force_uid_gid)
+ inode->i_gid = cifs_sb->mnt_gid;
+ else
+ inode->i_gid = le64_to_cpu(info->Gid);
+
+ inode->i_nlink = le64_to_cpu(info->Nlinks);
+
+ spin_lock(&inode->i_lock);
+ if (is_size_safe_to_change(cifsInfo, end_of_file)) {
+ /*
+ * We can not safely change the file size here if the client
+ * is writing to it due to potential races.
+ */
+ i_size_write(inode, end_of_file);
+
+ /*
+ * i_blocks is not related to (i_size / i_blksize),
+ * but instead 512 byte (2**9) size is required for
+ * calculating num blocks.
+ */
+ inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
+ }
+ spin_unlock(&inode->i_lock);
+}
+
int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path, struct super_block *sb, int xid)
{
@@ -74,7 +198,6 @@ int cifs_get_inode_info_unix(struct inode **pinode,
}
} else {
struct cifsInodeInfo *cifsInfo;
- __u32 type = le32_to_cpu(findData.Type);
__u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes);
__u64 end_of_file = le64_to_cpu(findData.EndOfFile);
@@ -105,112 +228,16 @@ int cifs_get_inode_info_unix(struct inode **pinode,
/* this is ok to set on every inode revalidate */
atomic_set(&cifsInfo->inUse, 1);
- inode->i_atime =
- cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
- inode->i_mtime =
- cifs_NTtimeToUnix(le64_to_cpu
- (findData.LastModificationTime));
- inode->i_ctime =
- cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
- inode->i_mode = le64_to_cpu(findData.Permissions);
- /* since we set the inode type below we need to mask off
- to avoid strange results if bits set above */
- inode->i_mode &= ~S_IFMT;
- if (type == UNIX_FILE) {
- inode->i_mode |= S_IFREG;
- } else if (type == UNIX_SYMLINK) {
- inode->i_mode |= S_IFLNK;
- } else if (type == UNIX_DIR) {
- inode->i_mode |= S_IFDIR;
- } else if (type == UNIX_CHARDEV) {
- inode->i_mode |= S_IFCHR;
- inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor),
- le64_to_cpu(findData.DevMinor) & MINORMASK);
- } else if (type == UNIX_BLOCKDEV) {
- inode->i_mode |= S_IFBLK;
- inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor),
- le64_to_cpu(findData.DevMinor) & MINORMASK);
- } else if (type == UNIX_FIFO) {
- inode->i_mode |= S_IFIFO;
- } else if (type == UNIX_SOCKET) {
- inode->i_mode |= S_IFSOCK;
- } else {
- /* safest to call it a file if we do not know */
- inode->i_mode |= S_IFREG;
- cFYI(1, ("unknown type %d", type));
- }
+ cifs_unix_info_to_inode(inode, &findData, 0);
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
- inode->i_uid = cifs_sb->mnt_uid;
- else
- inode->i_uid = le64_to_cpu(findData.Uid);
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
- inode->i_gid = cifs_sb->mnt_gid;
- else
- inode->i_gid = le64_to_cpu(findData.Gid);
-
- inode->i_nlink = le64_to_cpu(findData.Nlinks);
-
- spin_lock(&inode->i_lock);
- if (is_size_safe_to_change(cifsInfo, end_of_file)) {
- /* can not safely change the file size here if the
- client is writing to it due to potential races */
- i_size_write(inode, end_of_file);
-
- /* blksize needs to be multiple of two. So safer to default to
- blksize and blkbits set in superblock so 2**blkbits and blksize
- will match rather than setting to:
- (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
-
- /* This seems incredibly stupid but it turns out that i_blocks
- is not related to (i_size / i_blksize), instead 512 byte size
- is required for calculating num blocks */
-
- /* 512 bytes (2**9) is the fake blocksize that must be used */
- /* for this calculation */
- inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
- }
- spin_unlock(&inode->i_lock);
if (num_of_bytes < end_of_file)
cFYI(1, ("allocation size less than end of file"));
cFYI(1, ("Size %ld and blocks %llu",
(unsigned long) inode->i_size,
(unsigned long long)inode->i_blocks));
- if (S_ISREG(inode->i_mode)) {
- cFYI(1, ("File inode"));
- inode->i_op = &cifs_file_inode_ops;
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- inode->i_fop =
- &cifs_file_direct_nobrl_ops;
- else
- inode->i_fop = &cifs_file_direct_ops;
- } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- inode->i_fop = &cifs_file_nobrl_ops;
- else /* not direct, send byte range locks */
- inode->i_fop = &cifs_file_ops;
-
- /* check if server can support readpages */
- if (pTcon->ses->server->maxBuf <
- PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
- inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
- else
- inode->i_data.a_ops = &cifs_addr_ops;
- } else if (S_ISDIR(inode->i_mode)) {
- cFYI(1, ("Directory inode"));
- inode->i_op = &cifs_dir_inode_ops;
- inode->i_fop = &cifs_dir_ops;
- } else if (S_ISLNK(inode->i_mode)) {
- cFYI(1, ("Symbolic Link inode"));
- inode->i_op = &cifs_symlink_inode_ops;
- /* tmp_inode->i_fop = */ /* do not need to set to anything */
- } else {
- cFYI(1, ("Init special inode"));
- init_special_inode(inode, inode->i_mode,
- inode->i_rdev);
- }
+
+ cifs_set_ops(inode);
}
return rc;
}
@@ -490,9 +517,9 @@ int cifs_get_inode_info(struct inode **pinode,
if (decode_sfu_inode(inode,
le64_to_cpu(pfindData->EndOfFile),
search_path,
- cifs_sb, xid)) {
+ cifs_sb, xid))
cFYI(1, ("Unrecognized sfu inode type"));
- }
+
cFYI(1, ("sfu mode 0%o", inode->i_mode));
} else {
inode->i_mode |= S_IFREG;
@@ -546,36 +573,7 @@ int cifs_get_inode_info(struct inode **pinode,
atomic_set(&cifsInfo->inUse, 1);
}
- if (S_ISREG(inode->i_mode)) {
- cFYI(1, ("File inode"));
- inode->i_op = &cifs_file_inode_ops;
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- inode->i_fop =
- &cifs_file_direct_nobrl_ops;
- else
- inode->i_fop = &cifs_file_direct_ops;
- } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- inode->i_fop = &cifs_file_nobrl_ops;
- else /* not direct, send byte range locks */
- inode->i_fop = &cifs_file_ops;
-
- if (pTcon->ses->server->maxBuf <
- PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
- inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
- else
- inode->i_data.a_ops = &cifs_addr_ops;
- } else if (S_ISDIR(inode->i_mode)) {
- cFYI(1, ("Directory inode"));
- inode->i_op = &cifs_dir_inode_ops;
- inode->i_fop = &cifs_dir_ops;
- } else if (S_ISLNK(inode->i_mode)) {
- cFYI(1, ("Symbolic Link inode"));
- inode->i_op = &cifs_symlink_inode_ops;
- } else {
- init_special_inode(inode, inode->i_mode,
- inode->i_rdev);
- }
+ cifs_set_ops(inode);
}
kfree(buf);
return rc;
@@ -792,17 +790,12 @@ psx_del_no_retry:
}
static void posix_fill_in_inode(struct inode *tmp_inode,
- FILE_UNIX_BASIC_INFO *pData, int *pobject_type, int isNewInode)
+ FILE_UNIX_BASIC_INFO *pData, int isNewInode)
{
+ struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
loff_t local_size;
struct timespec local_mtime;
- struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
-
- __u32 type = le32_to_cpu(pData->Type);
- __u64 num_of_bytes = le64_to_cpu(pData->NumOfBytes);
- __u64 end_of_file = le64_to_cpu(pData->EndOfFile);
cifsInfo->time = jiffies;
atomic_inc(&cifsInfo->inUse);
@@ -810,115 +803,27 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
local_mtime = tmp_inode->i_mtime;
local_size = tmp_inode->i_size;
- tmp_inode->i_atime =
- cifs_NTtimeToUnix(le64_to_cpu(pData->LastAccessTime));
- tmp_inode->i_mtime =
- cifs_NTtimeToUnix(le64_to_cpu(pData->LastModificationTime));
- tmp_inode->i_ctime =
- cifs_NTtimeToUnix(le64_to_cpu(pData->LastStatusChange));
-
- tmp_inode->i_mode = le64_to_cpu(pData->Permissions);
- /* since we set the inode type below we need to mask off type
- to avoid strange results if bits above were corrupt */
- tmp_inode->i_mode &= ~S_IFMT;
- if (type == UNIX_FILE) {
- *pobject_type = DT_REG;
- tmp_inode->i_mode |= S_IFREG;
- } else if (type == UNIX_SYMLINK) {
- *pobject_type = DT_LNK;
- tmp_inode->i_mode |= S_IFLNK;
- } else if (type == UNIX_DIR) {
- *pobject_type = DT_DIR;
- tmp_inode->i_mode |= S_IFDIR;
- } else if (type == UNIX_CHARDEV) {
- *pobject_type = DT_CHR;
- tmp_inode->i_mode |= S_IFCHR;
- tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor),
- le64_to_cpu(pData->DevMinor) & MINORMASK);
- } else if (type == UNIX_BLOCKDEV) {
- *pobject_type = DT_BLK;
- tmp_inode->i_mode |= S_IFBLK;
- tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor),
- le64_to_cpu(pData->DevMinor) & MINORMASK);
- } else if (type == UNIX_FIFO) {
- *pobject_type = DT_FIFO;
- tmp_inode->i_mode |= S_IFIFO;
- } else if (type == UNIX_SOCKET) {
- *pobject_type = DT_SOCK;
- tmp_inode->i_mode |= S_IFSOCK;
- } else {
- /* safest to just call it a file */
- *pobject_type = DT_REG;
- tmp_inode->i_mode |= S_IFREG;
- cFYI(1, ("unknown inode type %d", type));
- }
-
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("object type: %d", type));
-#endif
- tmp_inode->i_uid = le64_to_cpu(pData->Uid);
- tmp_inode->i_gid = le64_to_cpu(pData->Gid);
- tmp_inode->i_nlink = le64_to_cpu(pData->Nlinks);
-
- spin_lock(&tmp_inode->i_lock);
- if (is_size_safe_to_change(cifsInfo, end_of_file)) {
- /* can not safely change the file size here if the
- client is writing to it due to potential races */
- i_size_write(tmp_inode, end_of_file);
+ cifs_unix_info_to_inode(tmp_inode, pData, 1);
+ cifs_set_ops(tmp_inode);
- /* 512 bytes (2**9) is the fake blocksize that must be used */
- /* for this calculation, not the real blocksize */
- tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
- }
- spin_unlock(&tmp_inode->i_lock);
-
- if (S_ISREG(tmp_inode->i_mode)) {
- cFYI(1, ("File inode"));
- tmp_inode->i_op = &cifs_file_inode_ops;
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
- else
- tmp_inode->i_fop = &cifs_file_direct_ops;
+ if (!S_ISREG(tmp_inode->i_mode))
+ return;
- } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- tmp_inode->i_fop = &cifs_file_nobrl_ops;
- else
- tmp_inode->i_fop = &cifs_file_ops;
-
- if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
- (cifs_sb->tcon->ses->server->maxBuf <
- PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
- tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
- else
- tmp_inode->i_data.a_ops = &cifs_addr_ops;
-
- if (isNewInode)
- return; /* No sense invalidating pages for new inode
- since we we have not started caching
- readahead file data yet */
+ /*
+ * No sense invalidating pages for new inode
+ * since we we have not started caching
+ * readahead file data yet.
+ */
+ if (isNewInode)
+ return;
- if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
- (local_size == tmp_inode->i_size)) {
- cFYI(1, ("inode exists but unchanged"));
- } else {
- /* file may have changed on server */
- cFYI(1, ("invalidate inode, readdir detected change"));
- invalidate_remote_inode(tmp_inode);
- }
- } else if (S_ISDIR(tmp_inode->i_mode)) {
- cFYI(1, ("Directory inode"));
- tmp_inode->i_op = &cifs_dir_inode_ops;
- tmp_inode->i_fop = &cifs_dir_ops;
- } else if (S_ISLNK(tmp_inode->i_mode)) {
- cFYI(1, ("Symbolic Link inode"));
- tmp_inode->i_op = &cifs_symlink_inode_ops;
-/* tmp_inode->i_fop = *//* do not need to set to anything */
+ if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
+ (local_size == tmp_inode->i_size)) {
+ cFYI(1, ("inode exists but unchanged"));
} else {
- cFYI(1, ("Special inode"));
- init_special_inode(tmp_inode, tmp_inode->i_mode,
- tmp_inode->i_rdev);
+ /* file may have changed on server */
+ cFYI(1, ("invalidate inode, readdir detected change"));
+ invalidate_remote_inode(tmp_inode);
}
}
@@ -968,7 +873,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
cFYI(1, ("posix mkdir returned 0x%x", rc));
d_drop(direntry);
} else {
- int obj_type;
if (pInfo->Type == cpu_to_le32(-1)) {
/* no return info, go query for it */
kfree(pInfo);
@@ -1004,7 +908,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
/* we already checked in POSIXCreate whether
frame was long enough */
posix_fill_in_inode(direntry->d_inode,
- pInfo, &obj_type, 1 /* NewInode */);
+ pInfo, 1 /* NewInode */);
#ifdef CONFIG_CIFS_DEBUG2
cFYI(1, ("instantiated dentry %p %s to inode %p",
direntry, direntry->d_name.name, newinode));
@@ -1214,9 +1118,8 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
} /* if we can not get memory just leave rc as EEXIST */
}
- if (rc) {
+ if (rc)
cFYI(1, ("rename rc %d", rc));
- }
if ((rc == -EIO) || (rc == -EEXIST)) {
int oplock = FALSE;
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index d24fe6880a0..5c792df13d6 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -30,7 +30,7 @@
#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
-int cifs_ioctl (struct inode *inode, struct file *filep,
+int cifs_ioctl(struct inode *inode, struct file *filep,
unsigned int command, unsigned long arg)
{
int rc = -ENOTTY; /* strange error - but the precedent */
diff --git a/fs/cifs/md4.c b/fs/cifs/md4.c
index a2415c1a14d..a725c2609d6 100644
--- a/fs/cifs/md4.c
+++ b/fs/cifs/md4.c
@@ -56,7 +56,7 @@ lshift(__u32 x, int s)
/* this applies md4 to 64 byte chunks */
static void
-mdfour64(__u32 * M, __u32 * A, __u32 *B, __u32 * C, __u32 *D)
+mdfour64(__u32 *M, __u32 *A, __u32 *B, __u32 *C, __u32 *D)
{
int j;
__u32 AA, BB, CC, DD;
@@ -137,7 +137,7 @@ mdfour64(__u32 * M, __u32 * A, __u32 *B, __u32 * C, __u32 *D)
}
static void
-copy64(__u32 * M, unsigned char *in)
+copy64(__u32 *M, unsigned char *in)
{
int i;
diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c
index f13f96d42fc..462bbfefd4b 100644
--- a/fs/cifs/md5.c
+++ b/fs/cifs/md5.c
@@ -161,7 +161,7 @@ MD5Final(unsigned char digest[16], struct MD5Context *ctx)
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+ (w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x)
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
@@ -302,9 +302,8 @@ hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
int i;
/* if key is longer than 64 bytes truncate it */
- if (key_len > 64) {
+ if (key_len > 64)
key_len = 64;
- }
/* start out by storing key in pads */
memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad));
@@ -359,9 +358,9 @@ hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
{
struct HMACMD5Context ctx;
hmac_md5_init_limK_to_64(key, 16, &ctx);
- if (data_len != 0) {
+ if (data_len != 0)
hmac_md5_update(data, data_len, &ctx);
- }
+
hmac_md5_final(digest, &ctx);
}
#endif
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 15546c2354c..2a42d9fedbb 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/misc.c
*
- * Copyright (C) International Business Machines Corp., 2002,2007
+ * 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
@@ -320,9 +320,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
if (treeCon->ses) {
if (treeCon->ses->capabilities & CAP_UNICODE)
buffer->Flags2 |= SMBFLG2_UNICODE;
- if (treeCon->ses->capabilities & CAP_STATUS32) {
+ if (treeCon->ses->capabilities & CAP_STATUS32)
buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- }
+
/* Uid is not converted */
buffer->Uid = treeCon->ses->Suid;
buffer->Mid = GetNextMid(treeCon->ses->server);
@@ -610,7 +610,8 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
buffer = (unsigned char *) smb_buf;
for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
- if (i % 8 == 0) { /* have reached the beginning of line */
+ if (i % 8 == 0) {
+ /* have reached the beginning of line */
printk(KERN_DEBUG "| ");
j = 0;
}
@@ -621,7 +622,8 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
else
debug_line[1 + (2 * j)] = '_';
- if (i % 8 == 7) { /* reached end of line, time to print ascii */
+ if (i % 8 == 7) {
+ /* reached end of line, time to print ascii */
debug_line[16] = 0;
printk(" | %s\n", debug_line);
}
@@ -631,7 +633,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
debug_line[2 * j] = ' ';
debug_line[1 + (2 * j)] = ' ';
}
- printk( " | %s\n", debug_line);
+ printk(" | %s\n", debug_line);
return;
}
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 646e1f06941..3b5a5ce882b 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/netmisc.c
*
- * Copyright (c) International Business Machines Corp., 2002
+ * Copyright (c) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com)
*
* Error mapping routines from Samba libsmb/errormap.c
@@ -150,9 +150,7 @@ static int canonicalize_unc(char *cp)
if (cp[i] == '\\')
break;
if (cp[i] == '/') {
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("change slash to backslash in malformed UNC"));
-#endif
+ cFYI(DBG2, ("change slash to \\ in malformed UNC"));
cp[i] = '\\';
return 1;
}
@@ -178,9 +176,7 @@ cifs_inet_pton(int address_family, char *cp, void *dst)
} else if (address_family == AF_INET6) {
ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
}
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("address conversion returned %d for %s", ret, cp));
-#endif
+ cFYI(DBG2, ("address conversion returned %d for %s", ret, cp));
if (ret > 0)
ret = 1;
return ret;
@@ -253,7 +249,8 @@ static const struct {
ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_MIX}, {
ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, {
ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, {
- ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_INVALID}, { /* mapping changed since shell does lookup on * and expects file not found */
+ /* mapping changed since shell does lookup on * expects FileNotFound */
+ ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_INVALID}, {
ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, {
ERRDOS, ERRalreadyexists, NT_STATUS_OBJECT_NAME_COLLISION}, {
ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, {
@@ -820,7 +817,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
/* old style errors */
/* DOS class smb error codes - map DOS */
- if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */
+ if (smberrclass == ERRDOS) {
+ /* 1 byte field no need to byte reverse */
for (i = 0;
i <
sizeof(mapping_table_ERRDOS) /
@@ -834,7 +832,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
}
/* else try next error mapping one to see if match */
}
- } else if (smberrclass == ERRSRV) { /* server class of error codes */
+ } else if (smberrclass == ERRSRV) {
+ /* server class of error codes */
for (i = 0;
i <
sizeof(mapping_table_ERRSRV) /
@@ -922,8 +921,8 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
{
struct timespec ts;
int sec, min, days, month, year;
- SMB_TIME * st = (SMB_TIME *)&time;
- SMB_DATE * sd = (SMB_DATE *)&date;
+ SMB_TIME *st = (SMB_TIME *)&time;
+ SMB_DATE *sd = (SMB_DATE *)&date;
cFYI(1, ("date %d time %d", date, time));
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 0f22def4bdf..32b445edc88 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -3,7 +3,7 @@
*
* Directory search handling
*
- * Copyright (C) International Business Machines Corp., 2004, 2007
+ * Copyright (C) International Business Machines Corp., 2004, 2008
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -42,17 +42,18 @@ static void dump_cifs_file_struct(struct file *file, char *label)
cFYI(1, ("empty cifs private file data"));
return;
}
- if (cf->invalidHandle) {
+ if (cf->invalidHandle)
cFYI(1, ("invalid handle"));
- }
- if (cf->srch_inf.endOfSearch) {
+ if (cf->srch_inf.endOfSearch)
cFYI(1, ("end of search"));
- }
- if (cf->srch_inf.emptyDir) {
+ if (cf->srch_inf.emptyDir)
cFYI(1, ("empty dir"));
- }
}
}
+#else
+static inline void dump_cifs_file_struct(struct file *file, char *label)
+{
+}
#endif /* DEBUG2 */
/* Returns one if new inode created (which therefore needs to be hashed) */
@@ -150,7 +151,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
} else { /* legacy, OS2 and DOS style */
/* struct timespec ts;*/
- FIND_FILE_STANDARD_INFO * pfindData =
+ FIND_FILE_STANDARD_INFO *pfindData =
(FIND_FILE_STANDARD_INFO *)buf;
tmp_inode->i_mtime = cnvrtDosUnixTm(
@@ -198,9 +199,8 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
if (attr & ATTR_DIRECTORY) {
*pobject_type = DT_DIR;
/* override default perms since we do not lock dirs */
- if (atomic_read(&cifsInfo->inUse) == 0) {
+ if (atomic_read(&cifsInfo->inUse) == 0)
tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
- }
tmp_inode->i_mode |= S_IFDIR;
} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
(attr & ATTR_SYSTEM)) {
@@ -231,9 +231,8 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
} /* could add code here - to validate if device or weird share type? */
/* can not fill in nlink here as in qpathinfo version and Unx search */
- if (atomic_read(&cifsInfo->inUse) == 0) {
+ if (atomic_read(&cifsInfo->inUse) == 0)
atomic_set(&cifsInfo->inUse, 1);
- }
spin_lock(&tmp_inode->i_lock);
if (is_size_safe_to_change(cifsInfo, end_of_file)) {
@@ -461,9 +460,8 @@ static int initiate_cifs_search(const int xid, struct file *file)
full_path = build_path_from_dentry(file->f_path.dentry);
- if (full_path == NULL) {
+ if (full_path == NULL)
return -ENOMEM;
- }
cFYI(1, ("Full path: %s start at: %lld", full_path, file->f_pos));
@@ -471,9 +469,9 @@ ffirst_retry:
/* test for Unix extensions */
/* but now check for them on the share/mount not on the SMB session */
/* if (pTcon->ses->capabilities & CAP_UNIX) { */
- if (pTcon->unix_ext) {
+ if (pTcon->unix_ext)
cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;
- } else if ((pTcon->ses->capabilities &
+ else if ((pTcon->ses->capabilities &
(CAP_NT_SMBS | CAP_NT_FIND)) == 0) {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
@@ -514,10 +512,10 @@ static int cifs_unicode_bytelen(char *str)
static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
{
char *new_entry;
- FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry;
+ FILE_DIRECTORY_INFO *pDirInfo = (FILE_DIRECTORY_INFO *)old_entry;
if (level == SMB_FIND_FILE_INFO_STANDARD) {
- FIND_FILE_STANDARD_INFO * pfData;
+ FIND_FILE_STANDARD_INFO *pfData;
pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo;
new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) +
@@ -553,7 +551,7 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
int len = 0;
if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) {
- FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
+ FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
filename = &pFindData->FileName[0];
if (cfile->srch_inf.unicode) {
len = cifs_unicode_bytelen(filename);
@@ -562,30 +560,30 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
len = strnlen(filename, 5);
}
} else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) {
- FILE_DIRECTORY_INFO * pFindData =
+ FILE_DIRECTORY_INFO *pFindData =
(FILE_DIRECTORY_INFO *)current_entry;
filename = &pFindData->FileName[0];
len = le32_to_cpu(pFindData->FileNameLength);
} else if (cfile->srch_inf.info_level ==
SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
- FILE_FULL_DIRECTORY_INFO * pFindData =
+ FILE_FULL_DIRECTORY_INFO *pFindData =
(FILE_FULL_DIRECTORY_INFO *)current_entry;
filename = &pFindData->FileName[0];
len = le32_to_cpu(pFindData->FileNameLength);
} else if (cfile->srch_inf.info_level ==
SMB_FIND_FILE_ID_FULL_DIR_INFO) {
- SEARCH_ID_FULL_DIR_INFO * pFindData =
+ SEARCH_ID_FULL_DIR_INFO *pFindData =
(SEARCH_ID_FULL_DIR_INFO *)current_entry;
filename = &pFindData->FileName[0];
len = le32_to_cpu(pFindData->FileNameLength);
} else if (cfile->srch_inf.info_level ==
SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
- FILE_BOTH_DIRECTORY_INFO * pFindData =
+ FILE_BOTH_DIRECTORY_INFO *pFindData =
(FILE_BOTH_DIRECTORY_INFO *)current_entry;
filename = &pFindData->FileName[0];
len = le32_to_cpu(pFindData->FileNameLength);
} else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) {
- FIND_FILE_STANDARD_INFO * pFindData =
+ FIND_FILE_STANDARD_INFO *pFindData =
(FIND_FILE_STANDARD_INFO *)current_entry;
filename = &pFindData->FileName[0];
len = pFindData->FileNameLength;
@@ -666,9 +664,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
. and .. for the root of a drive and for those we need
to start two entries earlier */
-#ifdef CONFIG_CIFS_DEBUG2
dump_cifs_file_struct(file, "In fce ");
-#endif
if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
is_dir_changed(file)) ||
(index_to_find < first_entry_in_buffer)) {
@@ -718,7 +714,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
pos_in_buf = index_to_find - first_entry_in_buffer;
cFYI(1, ("found entry - pos_in_buf %d", pos_in_buf));
- for (i=0; (i < (pos_in_buf)) && (current_entry != NULL); i++) {
+ for (i = 0; (i < (pos_in_buf)) && (current_entry != NULL); i++) {
/* go entry by entry figuring out which is first */
current_entry = nxt_dir_entry(current_entry, end_of_smb,
cifsFile->srch_inf.info_level);
@@ -793,7 +789,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
filename = &pFindData->FileName[0];
len = le32_to_cpu(pFindData->FileNameLength);
} else if (level == SMB_FIND_FILE_INFO_STANDARD) {
- FIND_FILE_STANDARD_INFO * pFindData =
+ FIND_FILE_STANDARD_INFO *pFindData =
(FIND_FILE_STANDARD_INFO *)current_entry;
filename = &pFindData->FileName[0];
/* one byte length, no name conversion */
@@ -928,7 +924,7 @@ static int cifs_save_resume_key(const char *current_entry,
level = cifsFile->srch_inf.info_level;
if (level == SMB_FIND_FILE_UNIX) {
- FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
+ FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
filename = &pFindData->FileName[0];
if (cifsFile->srch_inf.unicode) {
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index d2153abcba6..ed150efbe27 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -417,10 +417,6 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
calc_lanman_hash(ses, lnm_session_key);
ses->flags |= CIFS_SES_LANMAN;
-/* #ifdef CONFIG_CIFS_DEBUG2
- cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
- CIFS_SESS_KEY_SIZE);
-#endif */
memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
bcc_ptr += CIFS_SESS_KEY_SIZE;
diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c
index cfa6d21fb4e..04943c976f9 100644
--- a/fs/cifs/smbdes.c
+++ b/fs/cifs/smbdes.c
@@ -114,42 +114,42 @@ static uchar sbox[8][4][16] = {
{{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
- {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
+ {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13} },
{{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
- {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
+ {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} },
{{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
- {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
+ {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} },
{{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
- {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
+ {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} },
{{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
- {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
+ {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3} },
{{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
- {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
+ {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} },
{{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
- {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
+ {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} },
{{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
- {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}
+ {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} }
};
static void
@@ -313,9 +313,8 @@ str_to_key(unsigned char *str, unsigned char *key)
key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
key[7] = str[6] & 0x7F;
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 8; i++)
key[i] = (key[i] << 1);
- }
}
static void
@@ -344,9 +343,8 @@ smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
dohash(outb, inb, keyb, forw);
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 8; i++)
out[i] = 0;
- }
for (i = 0; i < 64; i++) {
if (outb[i])
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 50b623ad932..3612d6c0a0b 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/transport.c
*
- * Copyright (C) International Business Machines Corp., 2002,2007
+ * Copyright (C) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com)
* Jeremy Allison (jra@samba.org) 2006.
*
@@ -358,9 +358,9 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
} else if (ses->status != CifsGood) {
/* check if SMB session is bad because we are setting it up */
if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
- (in_buf->Command != SMB_COM_NEGOTIATE)) {
+ (in_buf->Command != SMB_COM_NEGOTIATE))
return -EAGAIN;
- } /* else ok - we are setting up session */
+ /* else ok - we are setting up session */
}
*ppmidQ = AllocMidQEntry(in_buf, ses);
if (*ppmidQ == NULL)
@@ -437,9 +437,8 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
iov[0].iov_len = in_buf->smb_buf_length + 4;
flags |= CIFS_NO_RESP;
rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("SendRcvNoR flags %d rc %d", flags, rc));
-#endif
+ cFYI(DBG2, ("SendRcvNoRsp flags %d rc %d", flags, rc));
+
return rc;
}
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 54e8ef96cb7..8cd6a445b01 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -139,9 +139,9 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
} else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
goto set_ea_exit;
- if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) {
+ if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0)
cFYI(1, ("attempt to set cifs inode metadata"));
- }
+
ea_name += 5; /* skip past user. prefix */
rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
(__u16)value_size, cifs_sb->local_nls,
@@ -262,7 +262,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
#ifdef CONFIG_CIFS_EXPERIMENTAL
- else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+ else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
__u16 fid;
int oplock = FALSE;
struct cifs_ntsd *pacl = NULL;
@@ -303,11 +303,10 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
} else if (strncmp(ea_name,
CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {
cFYI(1, ("Security xattr namespace not supported yet"));
- } else {
+ } else
cFYI(1,
("illegal xattr request %s (only user namespace supported)",
ea_name));
- }
/* We could add an additional check for streams ie
if proc/fs/cifs/streamstoxattr is set then
diff --git a/fs/compat.c b/fs/compat.c
index 43ca0165740..2ce4456aad3 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -702,9 +702,6 @@ static int do_nfs4_super_data_conv(void *raw_data)
real->flags = raw->flags;
real->version = raw->version;
}
- else {
- return -EINVAL;
- }
return 0;
}
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index d26e2826ba5..e9602d85c11 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -29,10 +29,6 @@
#define DEBUGFS_MAGIC 0x64626720
-/* declared over in file.c */
-extern struct file_operations debugfs_file_operations;
-extern struct inode_operations debugfs_link_operations;
-
static struct vfsmount *debugfs_mount;
static int debugfs_mount_count;
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c
index 035e6f9990b..67522c268c1 100644
--- a/fs/dlm/rcom.c
+++ b/fs/dlm/rcom.c
@@ -215,6 +215,8 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len)
ls->ls_recover_nodeid = nodeid;
if (nodeid == dlm_our_nodeid()) {
+ ls->ls_recover_buf->rc_header.h_length =
+ dlm_config.ci_buffer_size;
dlm_copy_master_names(ls, last_name, last_len,
ls->ls_recover_buf->rc_buf,
max_size, nodeid);
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index dc74b186145..6df1debdccc 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -263,52 +263,102 @@ out:
return 0;
}
-/* This function must zero any hole we create */
+/**
+ * ecryptfs_prepare_write
+ * @file: The eCryptfs file
+ * @page: The eCryptfs page
+ * @from: The start byte from which we will write
+ * @to: The end byte to which we will write
+ *
+ * This function must zero any hole we create
+ *
+ * Returns zero on success; non-zero otherwise
+ */
static int ecryptfs_prepare_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
- int rc = 0;
loff_t prev_page_end_size;
+ int rc = 0;
if (!PageUptodate(page)) {
- rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
- PAGE_CACHE_SIZE,
- page->mapping->host);
- if (rc) {
- printk(KERN_ERR "%s: Error attemping to read lower "
- "page segment; rc = [%d]\n", __FUNCTION__, rc);
- ClearPageUptodate(page);
- goto out;
- } else
+ struct ecryptfs_crypt_stat *crypt_stat =
+ &ecryptfs_inode_to_private(
+ file->f_path.dentry->d_inode)->crypt_stat;
+
+ if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
+ || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
+ rc = ecryptfs_read_lower_page_segment(
+ page, page->index, 0, PAGE_CACHE_SIZE,
+ page->mapping->host);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attemping to read "
+ "lower page segment; rc = [%d]\n",
+ __FUNCTION__, rc);
+ ClearPageUptodate(page);
+ goto out;
+ } else
+ SetPageUptodate(page);
+ } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
+ if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
+ rc = ecryptfs_copy_up_encrypted_with_header(
+ page, crypt_stat);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting "
+ "to copy the encrypted content "
+ "from the lower file whilst "
+ "inserting the metadata from "
+ "the xattr into the header; rc "
+ "= [%d]\n", __FUNCTION__, rc);
+ ClearPageUptodate(page);
+ goto out;
+ }
+ SetPageUptodate(page);
+ } else {
+ rc = ecryptfs_read_lower_page_segment(
+ page, page->index, 0, PAGE_CACHE_SIZE,
+ page->mapping->host);
+ if (rc) {
+ printk(KERN_ERR "%s: Error reading "
+ "page; rc = [%d]\n",
+ __FUNCTION__, rc);
+ ClearPageUptodate(page);
+ goto out;
+ }
+ SetPageUptodate(page);
+ }
+ } else {
+ rc = ecryptfs_decrypt_page(page);
+ if (rc) {
+ printk(KERN_ERR "%s: Error decrypting page "
+ "at index [%ld]; rc = [%d]\n",
+ __FUNCTION__, page->index, rc);
+ ClearPageUptodate(page);
+ goto out;
+ }
SetPageUptodate(page);
+ }
}
-
prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT);
-
- /*
- * If creating a page or more of holes, zero them out via truncate.
- * Note, this will increase i_size.
- */
+ /* If creating a page or more of holes, zero them out via truncate.
+ * Note, this will increase i_size. */
if (page->index != 0) {
if (prev_page_end_size > i_size_read(page->mapping->host)) {
rc = ecryptfs_truncate(file->f_path.dentry,
prev_page_end_size);
if (rc) {
- printk(KERN_ERR "Error on attempt to "
+ printk(KERN_ERR "%s: Error on attempt to "
"truncate to (higher) offset [%lld];"
- " rc = [%d]\n", prev_page_end_size, rc);
+ " rc = [%d]\n", __FUNCTION__,
+ prev_page_end_size, rc);
goto out;
}
}
}
- /*
- * Writing to a new page, and creating a small hole from start of page?
- * Zero it out.
- */
- if ((i_size_read(page->mapping->host) == prev_page_end_size) &&
- (from != 0)) {
+ /* Writing to a new page, and creating a small hole from start
+ * of page? Zero it out. */
+ if ((i_size_read(page->mapping->host) == prev_page_end_size)
+ && (from != 0))
zero_user(page, 0, PAGE_CACHE_SIZE);
- }
out:
return rc;
}
diff --git a/fs/efs/dir.c b/fs/efs/dir.c
index dfb5cb40021..49308a29798 100644
--- a/fs/efs/dir.c
+++ b/fs/efs/dir.c
@@ -5,8 +5,8 @@
*/
#include <linux/buffer_head.h>
-#include <linux/efs_fs.h>
#include <linux/smp_lock.h>
+#include "efs.h"
static int efs_readdir(struct file *, void *, filldir_t);
diff --git a/fs/efs/efs.h b/fs/efs/efs.h
new file mode 100644
index 00000000000..d8305b582ab
--- /dev/null
+++ b/fs/efs/efs.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1999 Al Smith
+ *
+ * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
+ * Portions derived from IRIX header files (c) 1988 Silicon Graphics
+ */
+#ifndef _EFS_EFS_H_
+#define _EFS_EFS_H_
+
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+
+#define EFS_VERSION "1.0a"
+
+static const char cprt[] = "EFS: "EFS_VERSION" - (c) 1999 Al Smith <Al.Smith@aeschi.ch.eu.org>";
+
+
+/* 1 block is 512 bytes */
+#define EFS_BLOCKSIZE_BITS 9
+#define EFS_BLOCKSIZE (1 << EFS_BLOCKSIZE_BITS)
+
+typedef int32_t efs_block_t;
+typedef uint32_t efs_ino_t;
+
+#define EFS_DIRECTEXTENTS 12
+
+/*
+ * layout of an extent, in memory and on disk. 8 bytes exactly.
+ */
+typedef union extent_u {
+ unsigned char raw[8];
+ struct extent_s {
+ unsigned int ex_magic:8; /* magic # (zero) */
+ unsigned int ex_bn:24; /* basic block */
+ unsigned int ex_length:8; /* numblocks in this extent */
+ unsigned int ex_offset:24; /* logical offset into file */
+ } cooked;
+} efs_extent;
+
+typedef struct edevs {
+ __be16 odev;
+ __be32 ndev;
+} efs_devs;
+
+/*
+ * extent based filesystem inode as it appears on disk. The efs inode
+ * is exactly 128 bytes long.
+ */
+struct efs_dinode {
+ __be16 di_mode; /* mode and type of file */
+ __be16 di_nlink; /* number of links to file */
+ __be16 di_uid; /* owner's user id */
+ __be16 di_gid; /* owner's group id */
+ __be32 di_size; /* number of bytes in file */
+ __be32 di_atime; /* time last accessed */
+ __be32 di_mtime; /* time last modified */
+ __be32 di_ctime; /* time created */
+ __be32 di_gen; /* generation number */
+ __be16 di_numextents; /* # of extents */
+ u_char di_version; /* version of inode */
+ u_char di_spare; /* spare - used by AFS */
+ union di_addr {
+ efs_extent di_extents[EFS_DIRECTEXTENTS];
+ efs_devs di_dev; /* device for IFCHR/IFBLK */
+ } di_u;
+};
+
+/* efs inode storage in memory */
+struct efs_inode_info {
+ int numextents;
+ int lastextent;
+
+ efs_extent extents[EFS_DIRECTEXTENTS];
+ struct inode vfs_inode;
+};
+
+#include <linux/efs_fs_sb.h>
+
+#define EFS_DIRBSIZE_BITS EFS_BLOCKSIZE_BITS
+#define EFS_DIRBSIZE (1 << EFS_DIRBSIZE_BITS)
+
+struct efs_dentry {
+ __be32 inode;
+ unsigned char namelen;
+ char name[3];
+};
+
+#define EFS_DENTSIZE (sizeof(struct efs_dentry) - 3 + 1)
+#define EFS_MAXNAMELEN ((1 << (sizeof(char) * 8)) - 1)
+
+#define EFS_DIRBLK_HEADERSIZE 4
+#define EFS_DIRBLK_MAGIC 0xbeef /* moo */
+
+struct efs_dir {
+ __be16 magic;
+ unsigned char firstused;
+ unsigned char slots;
+
+ unsigned char space[EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE];
+};
+
+#define EFS_MAXENTS \
+ ((EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE) / \
+ (EFS_DENTSIZE + sizeof(char)))
+
+#define EFS_SLOTAT(dir, slot) EFS_REALOFF((dir)->space[slot])
+
+#define EFS_REALOFF(offset) ((offset << 1))
+
+
+static inline struct efs_inode_info *INODE_INFO(struct inode *inode)
+{
+ return container_of(inode, struct efs_inode_info, vfs_inode);
+}
+
+static inline struct efs_sb_info *SUPER_INFO(struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
+
+struct statfs;
+struct fid;
+
+extern const struct inode_operations efs_dir_inode_operations;
+extern const struct file_operations efs_dir_operations;
+extern const struct address_space_operations efs_symlink_aops;
+
+extern struct inode *efs_iget(struct super_block *, unsigned long);
+extern efs_block_t efs_map_block(struct inode *, efs_block_t);
+extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
+
+extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *);
+extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
+extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
+extern struct dentry *efs_get_parent(struct dentry *);
+extern int efs_bmap(struct inode *, int);
+
+#endif /* _EFS_EFS_H_ */
diff --git a/fs/efs/file.c b/fs/efs/file.c
index 5db20129681..1ccb364ffa6 100644
--- a/fs/efs/file.c
+++ b/fs/efs/file.c
@@ -7,7 +7,7 @@
*/
#include <linux/buffer_head.h>
-#include <linux/efs_fs.h>
+#include "efs.h"
int efs_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
diff --git a/fs/efs/inode.c b/fs/efs/inode.c
index 627c3026946..79e19e5958e 100644
--- a/fs/efs/inode.c
+++ b/fs/efs/inode.c
@@ -7,11 +7,11 @@
* and from work (c) 1998 Mike Shaver.
*/
-#include <linux/efs_fs.h>
-#include <linux/efs_fs_sb.h>
#include <linux/buffer_head.h>
#include <linux/module.h>
#include <linux/fs.h>
+#include "efs.h"
+#include <linux/efs_fs_sb.h>
static int efs_readpage(struct file *file, struct page *page)
{
diff --git a/fs/efs/namei.c b/fs/efs/namei.c
index e26704742d4..3a404e7fad5 100644
--- a/fs/efs/namei.c
+++ b/fs/efs/namei.c
@@ -8,9 +8,9 @@
#include <linux/buffer_head.h>
#include <linux/string.h>
-#include <linux/efs_fs.h>
#include <linux/smp_lock.h>
#include <linux/exportfs.h>
+#include "efs.h"
static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) {
diff --git a/fs/efs/super.c b/fs/efs/super.c
index 14082405cdd..d733531b55e 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -8,14 +8,15 @@
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/efs_fs.h>
-#include <linux/efs_vh.h>
-#include <linux/efs_fs_sb.h>
#include <linux/exportfs.h>
#include <linux/slab.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
+#include "efs.h"
+#include <linux/efs_vh.h>
+#include <linux/efs_fs_sb.h>
+
static int efs_statfs(struct dentry *dentry, struct kstatfs *buf);
static int efs_fill_super(struct super_block *s, void *d, int silent);
diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c
index 1d30d2ff440..41911ec83aa 100644
--- a/fs/efs/symlink.c
+++ b/fs/efs/symlink.c
@@ -7,10 +7,10 @@
*/
#include <linux/string.h>
-#include <linux/efs_fs.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/smp_lock.h>
+#include "efs.h"
static int efs_symlink_readpage(struct file *file, struct page *page)
{
diff --git a/fs/exec.c b/fs/exec.c
index a44b142fb46..54a0a557b67 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -173,8 +173,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
return NULL;
if (write) {
- struct rlimit *rlim = current->signal->rlim;
unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
+ struct rlimit *rlim;
+
+ /*
+ * We've historically supported up to 32 pages (ARG_MAX)
+ * of argument strings even with small stacks
+ */
+ if (size <= ARG_MAX)
+ return page;
/*
* Limit to 1/4-th the stack size for the argv+env strings.
@@ -183,6 +190,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
* - the program will have a reasonable amount of stack left
* to work from.
*/
+ rlim = current->signal->rlim;
if (size > rlim[RLIMIT_STACK].rlim_cur / 4) {
put_page(page);
return NULL;
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 18769cc3237..ad536066408 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -806,8 +806,8 @@ static match_table_t tokens = {
{Opt_quota, "quota"},
{Opt_usrquota, "usrquota"},
{Opt_barrier, "barrier=%u"},
- {Opt_err, NULL},
{Opt_resize, "resize"},
+ {Opt_err, NULL},
};
static ext3_fsblk_t get_sb_block(void **data)
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 33888bb5814..2c23bade9aa 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -46,7 +46,7 @@ const struct file_operations ext4_dir_operations = {
#ifdef CONFIG_COMPAT
.compat_ioctl = ext4_compat_ioctl,
#endif
- .fsync = ext4_sync_file, /* BKL held */
+ .fsync = ext4_sync_file,
.release = ext4_release_dir,
};
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index bc7081f1fbe..9ae6e67090c 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -148,6 +148,7 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
{
struct ext4_inode_info *ei = EXT4_I(inode);
ext4_fsblk_t bg_start;
+ ext4_fsblk_t last_block;
ext4_grpblk_t colour;
int depth;
@@ -169,8 +170,13 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
/* OK. use inode's group */
bg_start = (ei->i_block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) +
le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block);
- colour = (current->pid % 16) *
+ last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1;
+
+ if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block)
+ colour = (current->pid % 16) *
(EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16);
+ else
+ colour = (current->pid % 16) * ((last_block - bg_start) / 16);
return bg_start + colour + block;
}
@@ -349,7 +355,7 @@ static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path)
#define ext4_ext_show_leaf(inode,path)
#endif
-static void ext4_ext_drop_refs(struct ext4_ext_path *path)
+void ext4_ext_drop_refs(struct ext4_ext_path *path)
{
int depth = path->p_depth;
int i;
@@ -2168,6 +2174,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
newblock = iblock - ee_block + ext_pblock(ex);
ex2 = ex;
+ err = ext4_ext_get_access(handle, inode, path + depth);
+ if (err)
+ goto out;
+
/* ex1: ee_block to iblock - 1 : uninitialized */
if (iblock > ee_block) {
ex1 = ex;
@@ -2200,16 +2210,20 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
newdepth = ext_depth(inode);
if (newdepth != depth) {
depth = newdepth;
- path = ext4_ext_find_extent(inode, iblock, NULL);
+ ext4_ext_drop_refs(path);
+ path = ext4_ext_find_extent(inode, iblock, path);
if (IS_ERR(path)) {
err = PTR_ERR(path);
- path = NULL;
goto out;
}
eh = path[depth].p_hdr;
ex = path[depth].p_ext;
if (ex2 != &newex)
ex2 = ex;
+
+ err = ext4_ext_get_access(handle, inode, path + depth);
+ if (err)
+ goto out;
}
allocated = max_blocks;
}
@@ -2230,9 +2244,6 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
ex2->ee_len = cpu_to_le16(allocated);
if (ex2 != ex)
goto insert;
- err = ext4_ext_get_access(handle, inode, path + depth);
- if (err)
- goto out;
/*
* New (initialized) extent starts from the first block
* in the current extent. i.e., ex2 == ex
@@ -2276,9 +2287,22 @@ out:
}
/*
+ * Block allocation/map/preallocation routine for extents based files
+ *
+ *
* Need to be called with
* down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
* (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
+ *
+ * return > 0, number of of blocks already mapped/allocated
+ * if create == 0 and these are pre-allocated blocks
+ * buffer head is unmapped
+ * otherwise blocks are mapped
+ *
+ * return = 0, if plain look up failed (blocks have not been allocated)
+ * buffer head is unmapped
+ *
+ * return < 0, error case.
*/
int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
ext4_lblk_t iblock,
@@ -2623,7 +2647,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
* modify 1 super block, 1 block bitmap and 1 group descriptor.
*/
credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3;
- down_write((&EXT4_I(inode)->i_data_sem));
+ mutex_lock(&inode->i_mutex);
retry:
while (ret >= 0 && ret < max_blocks) {
block = block + ret;
@@ -2634,16 +2658,17 @@ retry:
break;
}
- ret = ext4_ext_get_blocks(handle, inode, block,
+ ret = ext4_get_blocks_wrap(handle, inode, block,
max_blocks, &map_bh,
EXT4_CREATE_UNINITIALIZED_EXT, 0);
- WARN_ON(ret <= 0);
if (ret <= 0) {
- ext4_error(inode->i_sb, "ext4_fallocate",
- "ext4_ext_get_blocks returned error: "
- "inode#%lu, block=%u, max_blocks=%lu",
+#ifdef EXT4FS_DEBUG
+ WARN_ON(ret <= 0);
+ printk(KERN_ERR "%s: ext4_ext_get_blocks "
+ "returned error inode#%lu, block=%u, "
+ "max_blocks=%lu", __func__,
inode->i_ino, block, max_blocks);
- ret = -EIO;
+#endif
ext4_mark_inode_dirty(handle, inode);
ret2 = ext4_journal_stop(handle);
break;
@@ -2680,7 +2705,6 @@ retry:
if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
goto retry;
- up_write((&EXT4_I(inode)->i_data_sem));
/*
* Time to update the file size.
* Update only when preallocation was requested beyond the file size.
@@ -2692,21 +2716,18 @@ retry:
* if no error, we assume preallocation succeeded
* completely
*/
- mutex_lock(&inode->i_mutex);
i_size_write(inode, offset + len);
EXT4_I(inode)->i_disksize = i_size_read(inode);
- mutex_unlock(&inode->i_mutex);
} else if (ret < 0 && nblocks) {
/* Handle partial allocation scenario */
loff_t newsize;
- mutex_lock(&inode->i_mutex);
newsize = (nblocks << blkbits) + i_size_read(inode);
i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits));
EXT4_I(inode)->i_disksize = i_size_read(inode);
- mutex_unlock(&inode->i_mutex);
}
}
+ mutex_unlock(&inode->i_mutex);
return ret > 0 ? ret2 : ret;
}
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index da18a74b966..8036b9b5376 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -702,7 +702,12 @@ got:
ei->i_dir_start_lookup = 0;
ei->i_disksize = 0;
- ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL;
+ /*
+ * Don't inherit extent flag from directory. We set extent flag on
+ * newly created directory and file only if -o extent mount option is
+ * specified
+ */
+ ei->i_flags = EXT4_I(dir)->i_flags & ~(EXT4_INDEX_FL|EXT4_EXTENTS_FL);
if (S_ISLNK(mode))
ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL);
/* dirsync only applies to directories */
@@ -745,12 +750,15 @@ got:
goto fail_free_drop;
}
if (test_opt(sb, EXTENTS)) {
- EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL;
- ext4_ext_tree_init(handle, inode);
- err = ext4_update_incompat_feature(handle, sb,
- EXT4_FEATURE_INCOMPAT_EXTENTS);
- if (err)
- goto fail;
+ /* set extent flag only for directory and file */
+ if (S_ISDIR(mode) || S_ISREG(mode)) {
+ EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL;
+ ext4_ext_tree_init(handle, inode);
+ err = ext4_update_incompat_feature(handle, sb,
+ EXT4_FEATURE_INCOMPAT_EXTENTS);
+ if (err)
+ goto fail;
+ }
}
ext4_debug("allocating inode %lu\n", inode->i_ino);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 7dd9b50d5eb..945cbf6cb1f 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -403,6 +403,7 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind)
__le32 *start = ind->bh ? (__le32*) ind->bh->b_data : ei->i_data;
__le32 *p;
ext4_fsblk_t bg_start;
+ ext4_fsblk_t last_block;
ext4_grpblk_t colour;
/* Try to find previous block */
@@ -420,8 +421,13 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind)
* into the same cylinder group then.
*/
bg_start = ext4_group_first_block_no(inode->i_sb, ei->i_block_group);
- colour = (current->pid % 16) *
+ last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1;
+
+ if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block)
+ colour = (current->pid % 16) *
(EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16);
+ else
+ colour = (current->pid % 16) * ((last_block - bg_start) / 16);
return bg_start + colour;
}
@@ -768,7 +774,6 @@ err_out:
*
* `handle' can be NULL if create == 0.
*
- * The BKL may not be held on entry here. Be sure to take it early.
* return > 0, # of blocks mapped or allocated.
* return = 0, if plain lookup failed.
* return < 0, error case.
@@ -903,11 +908,38 @@ out:
*/
#define DIO_CREDITS 25
+
+/*
+ *
+ *
+ * ext4_ext4 get_block() wrapper function
+ * It will do a look up first, and returns if the blocks already mapped.
+ * Otherwise it takes the write lock of the i_data_sem and allocate blocks
+ * and store the allocated blocks in the result buffer head and mark it
+ * mapped.
+ *
+ * If file type is extents based, it will call ext4_ext_get_blocks(),
+ * Otherwise, call with ext4_get_blocks_handle() to handle indirect mapping
+ * based files
+ *
+ * On success, it returns the number of blocks being mapped or allocate.
+ * if create==0 and the blocks are pre-allocated and uninitialized block,
+ * the result buffer head is unmapped. If the create ==1, it will make sure
+ * the buffer head is mapped.
+ *
+ * It returns 0 if plain look up failed (blocks have not been allocated), in
+ * that casem, buffer head is unmapped
+ *
+ * It returns the error in case of allocation failure.
+ */
int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
unsigned long max_blocks, struct buffer_head *bh,
int create, int extend_disksize)
{
int retval;
+
+ clear_buffer_mapped(bh);
+
/*
* Try to see if we can get the block without requesting
* for new file system block.
@@ -921,12 +953,26 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
inode, block, max_blocks, bh, 0, 0);
}
up_read((&EXT4_I(inode)->i_data_sem));
- if (!create || (retval > 0))
+
+ /* If it is only a block(s) look up */
+ if (!create)
+ return retval;
+
+ /*
+ * Returns if the blocks have already allocated
+ *
+ * Note that if blocks have been preallocated
+ * ext4_ext_get_block() returns th create = 0
+ * with buffer head unmapped.
+ */
+ if (retval > 0 && buffer_mapped(bh))
return retval;
/*
- * We need to allocate new blocks which will result
- * in i_data update
+ * New blocks allocate and/or writing to uninitialized extent
+ * will possibly result in updating i_data, so we take
+ * the write lock of i_data_sem, and call get_blocks()
+ * with create == 1 flag.
*/
down_write((&EXT4_I(inode)->i_data_sem));
/*
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index dd0fcfcb35c..ef97f19c2f9 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -627,21 +627,19 @@ static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb,
return block;
}
+static inline void *mb_correct_addr_and_bit(int *bit, void *addr)
+{
#if BITS_PER_LONG == 64
-#define mb_correct_addr_and_bit(bit, addr) \
-{ \
- bit += ((unsigned long) addr & 7UL) << 3; \
- addr = (void *) ((unsigned long) addr & ~7UL); \
-}
+ *bit += ((unsigned long) addr & 7UL) << 3;
+ addr = (void *) ((unsigned long) addr & ~7UL);
#elif BITS_PER_LONG == 32
-#define mb_correct_addr_and_bit(bit, addr) \
-{ \
- bit += ((unsigned long) addr & 3UL) << 3; \
- addr = (void *) ((unsigned long) addr & ~3UL); \
-}
+ *bit += ((unsigned long) addr & 3UL) << 3;
+ addr = (void *) ((unsigned long) addr & ~3UL);
#else
#error "how many bits you are?!"
#endif
+ return addr;
+}
static inline int mb_test_bit(int bit, void *addr)
{
@@ -649,34 +647,54 @@ static inline int mb_test_bit(int bit, void *addr)
* ext4_test_bit on architecture like powerpc
* needs unsigned long aligned address
*/
- mb_correct_addr_and_bit(bit, addr);
+ addr = mb_correct_addr_and_bit(&bit, addr);
return ext4_test_bit(bit, addr);
}
static inline void mb_set_bit(int bit, void *addr)
{
- mb_correct_addr_and_bit(bit, addr);
+ addr = mb_correct_addr_and_bit(&bit, addr);
ext4_set_bit(bit, addr);
}
static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr)
{
- mb_correct_addr_and_bit(bit, addr);
+ addr = mb_correct_addr_and_bit(&bit, addr);
ext4_set_bit_atomic(lock, bit, addr);
}
static inline void mb_clear_bit(int bit, void *addr)
{
- mb_correct_addr_and_bit(bit, addr);
+ addr = mb_correct_addr_and_bit(&bit, addr);
ext4_clear_bit(bit, addr);
}
static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr)
{
- mb_correct_addr_and_bit(bit, addr);
+ addr = mb_correct_addr_and_bit(&bit, addr);
ext4_clear_bit_atomic(lock, bit, addr);
}
+static inline int mb_find_next_zero_bit(void *addr, int max, int start)
+{
+ int fix = 0;
+ addr = mb_correct_addr_and_bit(&fix, addr);
+ max += fix;
+ start += fix;
+
+ return ext4_find_next_zero_bit(addr, max, start) - fix;
+}
+
+static inline int mb_find_next_bit(void *addr, int max, int start)
+{
+ int fix = 0;
+ addr = mb_correct_addr_and_bit(&fix, addr);
+ max += fix;
+ start += fix;
+
+ return ext4_find_next_bit(addr, max, start) - fix;
+}
+
static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max)
{
char *bb;
@@ -906,7 +924,7 @@ static void ext4_mb_mark_free_simple(struct super_block *sb,
unsigned short chunk;
unsigned short border;
- BUG_ON(len >= EXT4_BLOCKS_PER_GROUP(sb));
+ BUG_ON(len > EXT4_BLOCKS_PER_GROUP(sb));
border = 2 << sb->s_blocksize_bits;
@@ -946,12 +964,12 @@ static void ext4_mb_generate_buddy(struct super_block *sb,
/* initialize buddy from bitmap which is aggregation
* of on-disk bitmap and preallocations */
- i = ext4_find_next_zero_bit(bitmap, max, 0);
+ i = mb_find_next_zero_bit(bitmap, max, 0);
grp->bb_first_free = i;
while (i < max) {
fragments++;
first = i;
- i = ext4_find_next_bit(bitmap, max, i);
+ i = mb_find_next_bit(bitmap, max, i);
len = i - first;
free += len;
if (len > 1)
@@ -959,7 +977,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb,
else
grp->bb_counters[0]++;
if (i < max)
- i = ext4_find_next_zero_bit(bitmap, max, i);
+ i = mb_find_next_zero_bit(bitmap, max, i);
}
grp->bb_fragments = fragments;
@@ -967,6 +985,10 @@ static void ext4_mb_generate_buddy(struct super_block *sb,
ext4_error(sb, __FUNCTION__,
"EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n",
group, free, grp->bb_free);
+ /*
+ * If we intent to continue, we consider group descritor
+ * corrupt and update bb_free using bitmap value
+ */
grp->bb_free = free;
}
@@ -1778,7 +1800,7 @@ static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac,
buddy = mb_find_buddy(e4b, i, &max);
BUG_ON(buddy == NULL);
- k = ext4_find_next_zero_bit(buddy, max, 0);
+ k = mb_find_next_zero_bit(buddy, max, 0);
BUG_ON(k >= max);
ac->ac_found++;
@@ -1818,11 +1840,11 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
i = e4b->bd_info->bb_first_free;
while (free && ac->ac_status == AC_STATUS_CONTINUE) {
- i = ext4_find_next_zero_bit(bitmap,
+ i = mb_find_next_zero_bit(bitmap,
EXT4_BLOCKS_PER_GROUP(sb), i);
if (i >= EXT4_BLOCKS_PER_GROUP(sb)) {
/*
- * IF we corrupt the bitmap we won't find any
+ * IF we have corrupt bitmap, we won't find any
* free blocks even though group info says we
* we have free blocks
*/
@@ -1838,6 +1860,12 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
ext4_error(sb, __FUNCTION__, "%d free blocks as per "
"group info. But got %d blocks\n",
free, ex.fe_len);
+ /*
+ * The number of free blocks differs. This mostly
+ * indicate that the bitmap is corrupt. So exit
+ * without claiming the space.
+ */
+ break;
}
ext4_mb_measure_extent(ac, &ex, e4b);
@@ -3740,10 +3768,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b,
}
while (bit < end) {
- bit = ext4_find_next_zero_bit(bitmap_bh->b_data, end, bit);
+ bit = mb_find_next_zero_bit(bitmap_bh->b_data, end, bit);
if (bit >= end)
break;
- next = ext4_find_next_bit(bitmap_bh->b_data, end, bit);
+ next = mb_find_next_bit(bitmap_bh->b_data, end, bit);
if (next > end)
next = end;
start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit +
@@ -3771,6 +3799,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b,
(unsigned long) pa->pa_len);
ext4_error(sb, __FUNCTION__, "free %u, pa_free %u\n",
free, pa->pa_free);
+ /*
+ * pa is already deleted so we use the value obtained
+ * from the bitmap and continue.
+ */
}
atomic_add(free, &sbi->s_mb_discarded);
if (ac)
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index 8c6c685b9d2..5c1e27de775 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -43,6 +43,7 @@ static int finish_range(handle_t *handle, struct inode *inode,
if (IS_ERR(path)) {
retval = PTR_ERR(path);
+ path = NULL;
goto err_out;
}
@@ -74,6 +75,10 @@ static int finish_range(handle_t *handle, struct inode *inode,
}
retval = ext4_ext_insert_extent(handle, inode, path, &newext);
err_out:
+ if (path) {
+ ext4_ext_drop_refs(path);
+ kfree(path);
+ }
lb->first_pblock = 0;
return retval;
}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index a9347fb43bc..28aa2ed4297 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1804,12 +1804,8 @@ retry:
inode->i_fop = &ext4_dir_operations;
inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
dir_block = ext4_bread (handle, inode, 0, 1, &err);
- if (!dir_block) {
- ext4_dec_count(handle, inode); /* is this nlink == 0? */
- ext4_mark_inode_dirty(handle, inode);
- iput (inode);
- goto out_stop;
- }
+ if (!dir_block)
+ goto out_clear_inode;
BUFFER_TRACE(dir_block, "get_write_access");
ext4_journal_get_write_access(handle, dir_block);
de = (struct ext4_dir_entry_2 *) dir_block->b_data;
@@ -1832,7 +1828,8 @@ retry:
ext4_mark_inode_dirty(handle, inode);
err = ext4_add_entry (handle, dentry, inode);
if (err) {
- inode->i_nlink = 0;
+out_clear_inode:
+ clear_nlink(inode);
ext4_mark_inode_dirty(handle, inode);
iput (inode);
goto out_stop;
@@ -2164,7 +2161,7 @@ static int ext4_unlink(struct inode * dir, struct dentry *dentry)
dir->i_ctime = dir->i_mtime = ext4_current_time(dir);
ext4_update_dx_flag(dir);
ext4_mark_inode_dirty(handle, dir);
- ext4_dec_count(handle, inode);
+ drop_nlink(inode);
if (!inode->i_nlink)
ext4_orphan_add(handle, inode);
inode->i_ctime = ext4_current_time(inode);
@@ -2214,7 +2211,7 @@ retry:
err = __page_symlink(inode, symname, l,
mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
if (err) {
- ext4_dec_count(handle, inode);
+ clear_nlink(inode);
ext4_mark_inode_dirty(handle, inode);
iput (inode);
goto out_stop;
@@ -2223,7 +2220,6 @@ retry:
inode->i_op = &ext4_fast_symlink_inode_operations;
memcpy((char*)&EXT4_I(inode)->i_data,symname,l);
inode->i_size = l-1;
- EXT4_I(inode)->i_flags &= ~EXT4_EXTENTS_FL;
}
EXT4_I(inode)->i_disksize = inode->i_size;
err = ext4_add_nondir(handle, dentry, inode);
@@ -2407,7 +2403,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
ext4_dec_count(handle, old_dir);
if (new_inode) {
/* checked empty_dir above, can't have another parent,
- * ext3_dec_count() won't work for many-linked dirs */
+ * ext4_dec_count() won't work for many-linked dirs */
new_inode->i_nlink = 0;
} else {
ext4_inc_count(handle, new_dir);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 9477a2bd6ff..e29efa0f9d6 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1037,6 +1037,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
ext4_warning(sb, __FUNCTION__,
"multiple resizers run on filesystem!");
unlock_super(sb);
+ ext4_journal_stop(handle);
err = -EBUSY;
goto exit_put;
}
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 7fb514b6d85..c4807b3fc8a 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -906,7 +906,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
}
if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
- int err = generic_permission(inode, mask, NULL);
+ err = generic_permission(inode, mask, NULL);
/* If permission is denied, try to refresh file
attributes. This is also needed, because the root
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 038ed743619..c6cbb6cd59b 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -369,7 +369,7 @@ out:
/**
- * int journal_restart() - restart a handle .
+ * int journal_restart() - restart a handle.
* @handle: handle to restart
* @nblocks: nr credits requested
*
@@ -844,8 +844,7 @@ out:
}
/**
- * int journal_get_undo_access() - Notify intent to modify metadata with
- * non-rewindable consequences
+ * int journal_get_undo_access() - Notify intent to modify metadata with non-rewindable consequences
* @handle: transaction
* @bh: buffer to undo
* @credits: store the number of taken credits here (if not NULL)
@@ -921,12 +920,14 @@ out:
}
/**
- * int journal_dirty_data() - mark a buffer as containing dirty data which
- * needs to be flushed before we can commit the
- * current transaction.
+ * int journal_dirty_data() - mark a buffer as containing dirty data to be flushed
* @handle: transaction
* @bh: bufferhead to mark
*
+ * Description:
+ * Mark a buffer as containing dirty data which needs to be flushed before
+ * we can commit the current transaction.
+ *
* The buffer is placed on the transaction's data list and is marked as
* belonging to the transaction.
*
@@ -1098,11 +1099,11 @@ no_journal:
}
/**
- * int journal_dirty_metadata() - mark a buffer as containing dirty metadata
+ * int journal_dirty_metadata() - mark a buffer as containing dirty metadata
* @handle: transaction to add buffer to.
* @bh: buffer to mark
*
- * mark dirty metadata which needs to be journaled as part of the current
+ * Mark dirty metadata which needs to be journaled as part of the current
* transaction.
*
* The buffer is placed on the transaction's metadata list and is marked
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 08226464e56..1ed8bd4de94 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -153,7 +153,7 @@ lockd(struct svc_rqst *rqstp)
*/
while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) {
long timeout = MAX_SCHEDULE_TIMEOUT;
- char buf[RPC_MAX_ADDRBUFLEN];
+ RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
if (signalled()) {
flush_signals(current);
diff --git a/fs/mpage.c b/fs/mpage.c
index 5df564366f3..235e4d3873a 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -325,16 +325,12 @@ confused:
}
/**
- * mpage_readpages - populate an address space with some pages, and
- * start reads against them.
- *
+ * mpage_readpages - populate an address space with some pages & start reads against them
* @mapping: the address_space
* @pages: The address of a list_head which contains the target pages. These
* pages have their ->index populated and are otherwise uninitialised.
- *
* The page at @pages->prev has the lowest file offset, and reads should be
* issued in @pages->prev to @pages->next order.
- *
* @nr_pages: The number of pages at *@pages
* @get_block: The filesystem's block mapper function.
*
@@ -360,6 +356,7 @@ confused:
* So an mpage read of the first 16 blocks of an ext2 file will cause I/O to be
* submitted in the following order:
* 12 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16
+ *
* because the indirect block has to be read to get the mappings of blocks
* 13,14,15,16. Obviously, this impacts performance.
*
@@ -656,9 +653,7 @@ out:
}
/**
- * mpage_writepages - walk the list of dirty pages of the given
- * address space and writepage() all of them.
- *
+ * mpage_writepages - walk the list of dirty pages of the given address space & writepage() all of them
* @mapping: address space structure to write
* @wbc: subtract the number of written pages from *@wbc->nr_to_write
* @get_block: the filesystem's block mapper function.
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index bd185a572a2..66648dd92d9 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -93,6 +93,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
svc_process(rqstp);
}
+ flush_signals(current);
svc_exit_thread(rqstp);
nfs_callback_info.pid = 0;
complete(&nfs_callback_info.stopped);
@@ -105,7 +106,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
*/
int nfs_callback_up(void)
{
- struct svc_serv *serv;
+ struct svc_serv *serv = NULL;
int ret = 0;
lock_kernel();
@@ -122,24 +123,30 @@ int nfs_callback_up(void)
ret = svc_create_xprt(serv, "tcp", nfs_callback_set_tcpport,
SVC_SOCK_ANONYMOUS);
if (ret <= 0)
- goto out_destroy;
+ goto out_err;
nfs_callback_tcpport = ret;
dprintk("Callback port = 0x%x\n", nfs_callback_tcpport);
ret = svc_create_thread(nfs_callback_svc, serv);
if (ret < 0)
- goto out_destroy;
+ goto out_err;
nfs_callback_info.serv = serv;
wait_for_completion(&nfs_callback_info.started);
out:
+ /*
+ * svc_create creates the svc_serv with sv_nrthreads == 1, and then
+ * svc_create_thread increments that. So we need to call svc_destroy
+ * on both success and failure so that the refcount is 1 when the
+ * thread exits.
+ */
+ if (serv)
+ svc_destroy(serv);
mutex_unlock(&nfs_callback_mutex);
unlock_kernel();
return ret;
-out_destroy:
+out_err:
dprintk("Couldn't create callback socket or server thread; err = %d\n",
ret);
- svc_destroy(serv);
-out_err:
nfs_callback_info.users--;
goto out;
}
@@ -165,7 +172,7 @@ void nfs_callback_down(void)
static int nfs_callback_authenticate(struct svc_rqst *rqstp)
{
struct nfs_client *clp;
- char buf[RPC_MAX_ADDRBUFLEN];
+ RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
/* Don't talk to strangers */
clp = nfs_find_client(svc_addr(rqstp), 4);
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index c63eb720b68..13619d24f02 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -254,7 +254,7 @@ static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap,
if (!(bitmap[0] & FATTR4_WORD0_CHANGE))
return 0;
p = xdr_reserve_space(xdr, 8);
- if (unlikely(p == 0))
+ if (unlikely(!p))
return htonl(NFS4ERR_RESOURCE);
p = xdr_encode_hyper(p, change);
return 0;
@@ -267,7 +267,7 @@ static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, u
if (!(bitmap[0] & FATTR4_WORD0_SIZE))
return 0;
p = xdr_reserve_space(xdr, 8);
- if (unlikely(p == 0))
+ if (unlikely(!p))
return htonl(NFS4ERR_RESOURCE);
p = xdr_encode_hyper(p, size);
return 0;
@@ -278,7 +278,7 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *ti
__be32 *p;
p = xdr_reserve_space(xdr, 12);
- if (unlikely(p == 0))
+ if (unlikely(!p))
return htonl(NFS4ERR_RESOURCE);
p = xdr_encode_hyper(p, time->tv_sec);
*p = htonl(time->tv_nsec);
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index b9eadd18ba7..00a5e4405e1 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -49,7 +49,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
struct file_lock *fl;
int status;
- for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
+ for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
continue;
if (nfs_file_open_context(fl->fl_file) != ctx)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 476cb0f837f..6cea7479c5b 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -154,7 +154,6 @@ typedef struct {
struct nfs_entry *entry;
decode_dirent_t decode;
int plus;
- int error;
unsigned long timestamp;
int timestamp_valid;
} nfs_readdir_descriptor_t;
@@ -213,7 +212,6 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
return 0;
error:
unlock_page(page);
- desc->error = error;
return -EIO;
}
@@ -483,13 +481,13 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
goto out;
}
timestamp = jiffies;
- desc->error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, *desc->dir_cookie,
- page,
+ status = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred,
+ *desc->dir_cookie, page,
NFS_SERVER(inode)->dtsize,
desc->plus);
desc->page = page;
desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */
- if (desc->error >= 0) {
+ if (status >= 0) {
desc->timestamp = timestamp;
desc->timestamp_valid = 1;
if ((status = dir_decode(desc)) == 0)
@@ -712,6 +710,8 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
{
struct nfs_server *server = NFS_SERVER(inode);
+ if (test_bit(NFS_INO_MOUNTPOINT, &NFS_I(inode)->flags))
+ return 0;
if (nd != NULL) {
/* VFS wants an on-the-wire revalidation */
if (nd->flags & LOOKUP_REVAL)
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 8ae5dba2d4e..86147b0ab2c 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -309,7 +309,7 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h,
mutex_lock(&idmap->idmap_im_lock);
he = idmap_lookup_id(h, id);
- if (he != 0) {
+ if (he) {
memcpy(name, he->ih_name, he->ih_namelen);
ret = he->ih_namelen;
goto out;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 966a8850aa3..a4c7cf2bff3 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -299,6 +299,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
else
inode->i_op = &nfs_mountpoint_inode_operations;
inode->i_fop = NULL;
+ set_bit(NFS_INO_MOUNTPOINT, &nfsi->flags);
}
} else if (S_ISLNK(inode->i_mode))
inode->i_op = &nfs_symlink_inode_operations;
@@ -1003,8 +1004,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
server = NFS_SERVER(inode);
/* Update the fsid? */
- if (S_ISDIR(inode->i_mode)
- && !nfs_fsid_equal(&server->fsid, &fattr->fsid))
+ if (S_ISDIR(inode->i_mode) &&
+ !nfs_fsid_equal(&server->fsid, &fattr->fsid) &&
+ !test_bit(NFS_INO_MOUNTPOINT, &nfsi->flags))
server->fsid = fattr->fsid;
/*
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 0f5619611b8..931992763e6 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -3,6 +3,7 @@
*/
#include <linux/mount.h>
+#include <linux/security.h>
struct nfs_string;
@@ -57,6 +58,8 @@ struct nfs_parsed_mount_data {
char *export_path;
int protocol;
} nfs_server;
+
+ struct security_mnt_opts lsm_opts;
};
/* client.c */
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index f9c7432471d..b962397004c 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -682,8 +682,8 @@ static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
if (seqid->sequence->flags & NFS_SEQID_CONFIRMED)
return;
printk(KERN_WARNING "NFS: v4 server returned a bad"
- "sequence-id error on an"
- "unconfirmed sequence %p!\n",
+ " sequence-id error on an"
+ " unconfirmed sequence %p!\n",
seqid->sequence);
case -NFS4ERR_STALE_CLIENTID:
case -NFS4ERR_STALE_STATEID:
@@ -785,7 +785,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s
struct file_lock *fl;
int status = 0;
- for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
+ for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
continue;
if (nfs_file_open_context(fl->fl_file)->state != state)
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 7f4505f6ac6..fcf4b982c88 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -190,6 +190,10 @@ static match_table_t nfs_secflavor_tokens = {
{ Opt_sec_lkeyi, "lkeyi" },
{ Opt_sec_lkeyp, "lkeyp" },
+ { Opt_sec_spkm, "spkm3" },
+ { Opt_sec_spkmi, "spkm3i" },
+ { Opt_sec_spkmp, "spkm3p" },
+
{ Opt_sec_err, NULL }
};
@@ -680,8 +684,9 @@ static void nfs_parse_server_address(char *value,
static int nfs_parse_mount_options(char *raw,
struct nfs_parsed_mount_data *mnt)
{
- char *p, *string;
+ char *p, *string, *secdata;
unsigned short port = 0;
+ int rc;
if (!raw) {
dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
@@ -689,6 +694,20 @@ static int nfs_parse_mount_options(char *raw,
}
dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
+ secdata = alloc_secdata();
+ if (!secdata)
+ goto out_nomem;
+
+ rc = security_sb_copy_data(raw, secdata);
+ if (rc)
+ goto out_security_failure;
+
+ rc = security_sb_parse_opts_str(secdata, &mnt->lsm_opts);
+ if (rc)
+ goto out_security_failure;
+
+ free_secdata(secdata);
+
while ((p = strsep(&raw, ",")) != NULL) {
substring_t args[MAX_OPT_ARGS];
int option, token;
@@ -1038,7 +1057,10 @@ static int nfs_parse_mount_options(char *raw,
out_nomem:
printk(KERN_INFO "NFS: not enough memory to parse option\n");
return 0;
-
+out_security_failure:
+ free_secdata(secdata);
+ printk(KERN_INFO "NFS: security options invalid: %d\n", rc);
+ return 0;
out_unrec_vers:
printk(KERN_INFO "NFS: unrecognized NFS version number\n");
return 0;
@@ -1210,6 +1232,33 @@ static int nfs_validate_mount_data(void *options,
args->namlen = data->namlen;
args->bsize = data->bsize;
args->auth_flavors[0] = data->pseudoflavor;
+
+ /*
+ * The legacy version 6 binary mount data from userspace has a
+ * field used only to transport selinux information into the
+ * the kernel. To continue to support that functionality we
+ * have a touch of selinux knowledge here in the NFS code. The
+ * userspace code converted context=blah to just blah so we are
+ * converting back to the full string selinux understands.
+ */
+ if (data->context[0]){
+#ifdef CONFIG_SECURITY_SELINUX
+ int rc;
+ char *opts_str = kmalloc(sizeof(data->context) + 8, GFP_KERNEL);
+ if (!opts_str)
+ return -ENOMEM;
+ strcpy(opts_str, "context=");
+ data->context[NFS_MAX_CONTEXT_LEN] = '\0';
+ strcat(opts_str, &data->context[0]);
+ rc = security_sb_parse_opts_str(opts_str, &args->lsm_opts);
+ kfree(opts_str);
+ if (rc)
+ return rc;
+#else
+ return -EINVAL;
+#endif
+ }
+
break;
default: {
unsigned int len;
@@ -1472,6 +1521,8 @@ static int nfs_get_sb(struct file_system_type *fs_type,
};
int error;
+ security_init_mnt_opts(&data.lsm_opts);
+
/* Validate the mount data */
error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
if (error < 0)
@@ -1511,6 +1562,10 @@ static int nfs_get_sb(struct file_system_type *fs_type,
goto error_splat_super;
}
+ error = security_sb_set_mnt_opts(s, &data.lsm_opts);
+ if (error)
+ goto error_splat_root;
+
s->s_flags |= MS_ACTIVE;
mnt->mnt_sb = s;
mnt->mnt_root = mntroot;
@@ -1519,12 +1574,15 @@ static int nfs_get_sb(struct file_system_type *fs_type,
out:
kfree(data.nfs_server.hostname);
kfree(data.mount_server.hostname);
+ security_free_mnt_opts(&data.lsm_opts);
return error;
out_err_nosb:
nfs_free_server(server);
goto out;
+error_splat_root:
+ dput(mntroot);
error_splat_super:
up_write(&s->s_umount);
deactivate_super(s);
@@ -1604,6 +1662,9 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
mnt->mnt_sb = s;
mnt->mnt_root = mntroot;
+ /* clone any lsm security options from the parent to the new sb */
+ security_sb_clone_mnt_opts(data->sb, s);
+
dprintk("<-- nfs_xdev_get_sb() = 0\n");
return 0;
@@ -1846,6 +1907,8 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
};
int error;
+ security_init_mnt_opts(&data.lsm_opts);
+
/* Validate the mount data */
error = nfs4_validate_mount_data(raw_data, &data, dev_name);
if (error < 0)
@@ -1894,6 +1957,7 @@ out:
kfree(data.client_address);
kfree(data.nfs_server.export_path);
kfree(data.nfs_server.hostname);
+ security_free_mnt_opts(&data.lsm_opts);
return error;
out_free:
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index f55c437124a..80c61fdb272 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -734,7 +734,7 @@ int nfs_updatepage(struct file *file, struct page *page,
*/
if (nfs_write_pageuptodate(page, inode) &&
inode->i_flock == NULL &&
- !(file->f_mode & O_SYNC)) {
+ !(file->f_flags & O_SYNC)) {
count = max(count + offset, nfs_page_length(page));
offset = 0;
}
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 0130b345234..1eb771d79cc 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -101,7 +101,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
{
/* Check if the request originated from a secure port. */
if (!rqstp->rq_secure && EX_SECURE(exp)) {
- char buf[RPC_MAX_ADDRBUFLEN];
+ RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
dprintk(KERN_WARNING
"nfsd: request from insecure port %s!\n",
svc_print_addr(rqstp, buf, sizeof(buf)));
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 82243127eeb..90383ed6100 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -257,7 +257,7 @@ static int ocfs2_readpage_inline(struct inode *inode, struct page *page)
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
BUG_ON(!PageLocked(page));
- BUG_ON(!OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL);
+ BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL));
ret = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &di_bh,
OCFS2_BH_CACHED, inode);
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index e280833ceb9..8a187584808 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -390,9 +390,8 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
goto bail;
}
if (pde)
- pde->rec_len =
- cpu_to_le16(le16_to_cpu(pde->rec_len) +
- le16_to_cpu(de->rec_len));
+ le16_add_cpu(&pde->rec_len,
+ le16_to_cpu(de->rec_len));
else
de->inode = 0;
dir->i_version++;
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index a54d33d95ad..c92d1b19fc0 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -1695,9 +1695,9 @@ send_response:
* can periodically run all locks owned by this node
* and re-assert across the cluster...
*/
-int dlm_do_assert_master(struct dlm_ctxt *dlm,
- struct dlm_lock_resource *res,
- void *nodemap, u32 flags)
+static int dlm_do_assert_master(struct dlm_ctxt *dlm,
+ struct dlm_lock_resource *res,
+ void *nodemap, u32 flags)
{
struct dlm_assert_master assert;
int to, tmpret;
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 351130c9b73..f7794306b2b 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -3042,7 +3042,7 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres,
inode = ocfs2_lock_res_inode(lockres);
mapping = inode->i_mapping;
- if (S_ISREG(inode->i_mode))
+ if (!S_ISREG(inode->i_mode))
goto out;
/*
@@ -3219,8 +3219,8 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres,
return UNBLOCK_CONTINUE_POST;
}
-void ocfs2_process_blocked_lock(struct ocfs2_super *osb,
- struct ocfs2_lock_res *lockres)
+static void ocfs2_process_blocked_lock(struct ocfs2_super *osb,
+ struct ocfs2_lock_res *lockres)
{
int status;
struct ocfs2_unblock_ctl ctl = {0, 0,};
@@ -3356,7 +3356,7 @@ static int ocfs2_downconvert_thread_should_wake(struct ocfs2_super *osb)
return should_wake;
}
-int ocfs2_downconvert_thread(void *arg)
+static int ocfs2_downconvert_thread(void *arg)
{
int status = 0;
struct ocfs2_super *osb = arg;
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h
index 1d5b0699d0a..e3cf902404b 100644
--- a/fs/ocfs2/dlmglue.h
+++ b/fs/ocfs2/dlmglue.h
@@ -109,8 +109,6 @@ void ocfs2_simple_drop_lockres(struct ocfs2_super *osb,
struct ocfs2_lock_res *lockres);
/* for the downconvert thread */
-void ocfs2_process_blocked_lock(struct ocfs2_super *osb,
- struct ocfs2_lock_res *lockres);
void ocfs2_wake_downconvert_thread(struct ocfs2_super *osb);
struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void);
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c
index c0efd9489fe..0758daf64da 100644
--- a/fs/ocfs2/heartbeat.c
+++ b/fs/ocfs2/heartbeat.c
@@ -49,10 +49,15 @@ static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map,
static inline void __ocfs2_node_map_clear_bit(struct ocfs2_node_map *map,
int bit);
static inline int __ocfs2_node_map_is_empty(struct ocfs2_node_map *map);
-static void __ocfs2_node_map_dup(struct ocfs2_node_map *target,
- struct ocfs2_node_map *from);
-static void __ocfs2_node_map_set(struct ocfs2_node_map *target,
- struct ocfs2_node_map *from);
+
+/* special case -1 for now
+ * TODO: should *really* make sure the calling func never passes -1!! */
+static void ocfs2_node_map_init(struct ocfs2_node_map *map)
+{
+ map->num_nodes = OCFS2_NODE_MAP_MAX_NODES;
+ memset(map->map, 0, BITS_TO_LONGS(OCFS2_NODE_MAP_MAX_NODES) *
+ sizeof(unsigned long));
+}
void ocfs2_init_node_maps(struct ocfs2_super *osb)
{
@@ -136,15 +141,6 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb)
mlog_errno(ret);
}
-/* special case -1 for now
- * TODO: should *really* make sure the calling func never passes -1!! */
-void ocfs2_node_map_init(struct ocfs2_node_map *map)
-{
- map->num_nodes = OCFS2_NODE_MAP_MAX_NODES;
- memset(map->map, 0, BITS_TO_LONGS(OCFS2_NODE_MAP_MAX_NODES) *
- sizeof(unsigned long));
-}
-
static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map,
int bit)
{
@@ -216,6 +212,8 @@ int ocfs2_node_map_is_empty(struct ocfs2_super *osb,
return ret;
}
+#if 0
+
static void __ocfs2_node_map_dup(struct ocfs2_node_map *target,
struct ocfs2_node_map *from)
{
@@ -254,6 +252,8 @@ static void __ocfs2_node_map_set(struct ocfs2_node_map *target,
target->map[i] = from->map[i];
}
+#endif /* 0 */
+
/* Returns whether the recovery bit was actually set - it may not be
* if a node is still marked as needing recovery */
int ocfs2_recovery_map_set(struct ocfs2_super *osb,
diff --git a/fs/ocfs2/heartbeat.h b/fs/ocfs2/heartbeat.h
index 56859211888..eac63aed761 100644
--- a/fs/ocfs2/heartbeat.h
+++ b/fs/ocfs2/heartbeat.h
@@ -33,7 +33,6 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb);
/* node map functions - used to keep track of mounted and in-recovery
* nodes. */
-void ocfs2_node_map_init(struct ocfs2_node_map *map);
int ocfs2_node_map_is_empty(struct ocfs2_super *osb,
struct ocfs2_node_map *map);
void ocfs2_node_map_set_bit(struct ocfs2_super *osb,
@@ -57,9 +56,5 @@ int ocfs2_recovery_map_set(struct ocfs2_super *osb,
int num);
void ocfs2_recovery_map_clear(struct ocfs2_super *osb,
int num);
-/* returns 1 if bit is the only bit set in target, 0 otherwise */
-int ocfs2_node_map_is_only(struct ocfs2_super *osb,
- struct ocfs2_node_map *target,
- int bit);
#endif /* OCFS2_HEARTBEAT_H */
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index add1ffdc5c6..ab83fd56242 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -120,9 +120,6 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb)
mlog_entry_void();
- if (ocfs2_mount_local(osb))
- goto bail;
-
if (osb->local_alloc_size == 0)
goto bail;
@@ -588,8 +585,7 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
while(bits_wanted--)
ocfs2_set_bit(start++, bitmap);
- alloc->id1.bitmap1.i_used = cpu_to_le32(*num_bits +
- le32_to_cpu(alloc->id1.bitmap1.i_used));
+ le32_add_cpu(&alloc->id1.bitmap1.i_used, *num_bits);
status = ocfs2_journal_dirty(handle, osb->local_alloc_bh);
if (status < 0) {
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 88f8edf1825..91a1bd67ac1 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -314,9 +314,12 @@ static int proc_pid_schedstat(struct task_struct *task, char *buffer)
static int lstats_show_proc(struct seq_file *m, void *v)
{
int i;
- struct task_struct *task = m->private;
- seq_puts(m, "Latency Top version : v0.1\n");
+ struct inode *inode = m->private;
+ struct task_struct *task = get_proc_task(inode);
+ if (!task)
+ return -ESRCH;
+ seq_puts(m, "Latency Top version : v0.1\n");
for (i = 0; i < 32; i++) {
if (task->latency_record[i].backtrace[0]) {
int q;
@@ -341,32 +344,24 @@ static int lstats_show_proc(struct seq_file *m, void *v)
}
}
+ put_task_struct(task);
return 0;
}
static int lstats_open(struct inode *inode, struct file *file)
{
- int ret;
- struct seq_file *m;
- struct task_struct *task = get_proc_task(inode);
-
- ret = single_open(file, lstats_show_proc, NULL);
- if (!ret) {
- m = file->private_data;
- m->private = task;
- }
- return ret;
+ return single_open(file, lstats_show_proc, inode);
}
static ssize_t lstats_write(struct file *file, const char __user *buf,
size_t count, loff_t *offs)
{
- struct seq_file *m;
- struct task_struct *task;
+ struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
- m = file->private_data;
- task = m->private;
+ if (!task)
+ return -ESRCH;
clear_all_latency_tracing(task);
+ put_task_struct(task);
return count;
}
@@ -416,6 +411,7 @@ static const struct limit_names lnames[RLIM_NLIMITS] = {
[RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"},
[RLIMIT_NICE] = {"Max nice priority", NULL},
[RLIMIT_RTPRIO] = {"Max realtime priority", NULL},
+ [RLIMIT_RTTIME] = {"Max realtime timeout", "us"},
};
/* Display limits for a process */
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 468805d40e2..2d563979cb0 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -32,6 +32,7 @@
#include <linux/interrupt.h>
#include <linux/swap.h>
#include <linux/slab.h>
+#include <linux/genhd.h>
#include <linux/smp.h>
#include <linux/signal.h>
#include <linux/module.h>
@@ -377,7 +378,6 @@ static int stram_read_proc(char *page, char **start, off_t off,
#endif
#ifdef CONFIG_BLOCK
-extern const struct seq_operations partitions_op;
static int partitions_open(struct inode *inode, struct file *file)
{
return seq_open(file, &partitions_op);
@@ -389,7 +389,6 @@ static const struct file_operations proc_partitions_operations = {
.release = seq_release,
};
-extern const struct seq_operations diskstats_op;
static int diskstats_open(struct inode *inode, struct file *file)
{
return seq_open(file, &diskstats_op);
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 49958cffbd8..6dc0334815f 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -531,7 +531,7 @@ struct pagemapread {
#define PM_RESERVED_BITS 3
#define PM_RESERVED_OFFSET (64 - PM_RESERVED_BITS)
#define PM_RESERVED_MASK (((1LL<<PM_RESERVED_BITS)-1) << PM_RESERVED_OFFSET)
-#define PM_SPECIAL(nr) (((nr) << PM_RESERVED_OFFSET) | PM_RESERVED_MASK)
+#define PM_SPECIAL(nr) (((nr) << PM_RESERVED_OFFSET) & PM_RESERVED_MASK)
#define PM_NOT_PRESENT PM_SPECIAL(1LL)
#define PM_SWAP PM_SPECIAL(2LL)
#define PM_END_OF_BUFFER 1
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 6841452e0de..393cc22c171 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -2031,7 +2031,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
return -EXDEV;
}
/* We must not pack tails for quota files on reiserfs for quota IO to work */
- if (!REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask) {
+ if (!(REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask)) {
reiserfs_warning(sb,
"reiserfs: Quota file must have tail packing disabled.");
path_put(&nd.path);
diff --git a/fs/splice.c b/fs/splice.c
index 9b559ee711a..0670c915cd3 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1669,6 +1669,13 @@ static int link_pipe(struct pipe_inode_info *ipipe,
i++;
} while (len);
+ /*
+ * return EAGAIN if we have the potential of some data in the
+ * future, otherwise just return 0
+ */
+ if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK))
+ ret = -EAGAIN;
+
inode_double_unlock(ipipe->inode, opipe->inode);
/*
@@ -1709,11 +1716,8 @@ static long do_tee(struct file *in, struct file *out, size_t len,
ret = link_ipipe_prep(ipipe, flags);
if (!ret) {
ret = link_opipe_prep(opipe, flags);
- if (!ret) {
+ if (!ret)
ret = link_pipe(ipipe, opipe, len, flags);
- if (!ret && (flags & SPLICE_F_NONBLOCK))
- ret = -EAGAIN;
- }
}
}
diff --git a/fs/super.c b/fs/super.c
index 88811f60c8d..010446d8c40 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -870,12 +870,12 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
if (!mnt)
goto out;
- if (data) {
+ if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
secdata = alloc_secdata();
if (!secdata)
goto out_mnt;
- error = security_sb_copy_data(type, data, secdata);
+ error = security_sb_copy_data(data, secdata);
if (error)
goto out_free_secdata;
}
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index b26fc4dec1e..23ceed8c8fb 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -58,7 +58,7 @@ ufs_set_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1,
{
switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
case UFS_ST_SUNOS:
- if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) {
+ if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) {
usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value);
break;
}
diff --git a/fs/xfs/Kbuild b/fs/xfs/Kbuild
deleted file mode 100644
index 2566e96706f..00000000000
--- a/fs/xfs/Kbuild
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# The xfs people like to share Makefile with 2.6 and 2.4.
-# Utilise file named Kbuild file which has precedence over Makefile.
-#
-
-include $(srctree)/$(obj)/Makefile-linux-2.6
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 49e3e7e5e3d..36ec614e699 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -1 +1,117 @@
-include $(TOPDIR)/fs/xfs/Makefile-linux-$(VERSION).$(PATCHLEVEL)
+#
+# Copyright (c) 2000-2005 Silicon Graphics, Inc.
+# All Rights Reserved.
+#
+# 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.
+#
+# This program is distributed in the hope that it would 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 the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+EXTRA_CFLAGS += -I$(src) -I$(src)/linux-2.6 -funsigned-char
+
+XFS_LINUX := linux-2.6
+
+ifeq ($(CONFIG_XFS_DEBUG),y)
+ EXTRA_CFLAGS += -g
+endif
+
+obj-$(CONFIG_XFS_FS) += xfs.o
+
+xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \
+ xfs_dquot.o \
+ xfs_dquot_item.o \
+ xfs_trans_dquot.o \
+ xfs_qm_syscalls.o \
+ xfs_qm_bhv.o \
+ xfs_qm.o)
+
+ifeq ($(CONFIG_XFS_QUOTA),y)
+xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o
+endif
+
+xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
+xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
+xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o
+xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o
+xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o
+
+
+xfs-y += xfs_alloc.o \
+ xfs_alloc_btree.o \
+ xfs_attr.o \
+ xfs_attr_leaf.o \
+ xfs_bit.o \
+ xfs_bmap.o \
+ xfs_bmap_btree.o \
+ xfs_btree.o \
+ xfs_buf_item.o \
+ xfs_da_btree.o \
+ xfs_dir2.o \
+ xfs_dir2_block.o \
+ xfs_dir2_data.o \
+ xfs_dir2_leaf.o \
+ xfs_dir2_node.o \
+ xfs_dir2_sf.o \
+ xfs_error.o \
+ xfs_extfree_item.o \
+ xfs_filestream.o \
+ xfs_fsops.o \
+ xfs_ialloc.o \
+ xfs_ialloc_btree.o \
+ xfs_iget.o \
+ xfs_inode.o \
+ xfs_inode_item.o \
+ xfs_iomap.o \
+ xfs_itable.o \
+ xfs_dfrag.o \
+ xfs_log.o \
+ xfs_log_recover.o \
+ xfs_mount.o \
+ xfs_mru_cache.o \
+ xfs_rename.o \
+ xfs_trans.o \
+ xfs_trans_ail.o \
+ xfs_trans_buf.o \
+ xfs_trans_extfree.o \
+ xfs_trans_inode.o \
+ xfs_trans_item.o \
+ xfs_utils.o \
+ xfs_vfsops.o \
+ xfs_vnodeops.o \
+ xfs_rw.o \
+ xfs_dmops.o \
+ xfs_qmops.o
+
+xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o
+
+# Objects in linux/
+xfs-y += $(addprefix $(XFS_LINUX)/, \
+ kmem.o \
+ xfs_aops.o \
+ xfs_buf.o \
+ xfs_export.o \
+ xfs_file.o \
+ xfs_fs_subr.o \
+ xfs_globals.o \
+ xfs_ioctl.o \
+ xfs_iops.o \
+ xfs_lrw.o \
+ xfs_super.o \
+ xfs_vnode.o)
+
+# Objects in support/
+xfs-y += $(addprefix support/, \
+ debug.o \
+ uuid.o)
+
+xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o
+
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
deleted file mode 100644
index 97316451fc6..00000000000
--- a/fs/xfs/Makefile-linux-2.6
+++ /dev/null
@@ -1,117 +0,0 @@
-#
-# Copyright (c) 2000-2005 Silicon Graphics, Inc.
-# All Rights Reserved.
-#
-# 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.
-#
-# This program is distributed in the hope that it would 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 the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char
-
-XFS_LINUX := linux-2.6
-
-ifeq ($(CONFIG_XFS_DEBUG),y)
- EXTRA_CFLAGS += -g
-endif
-
-obj-$(CONFIG_XFS_FS) += xfs.o
-
-xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \
- xfs_dquot.o \
- xfs_dquot_item.o \
- xfs_trans_dquot.o \
- xfs_qm_syscalls.o \
- xfs_qm_bhv.o \
- xfs_qm.o)
-
-ifeq ($(CONFIG_XFS_QUOTA),y)
-xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o
-endif
-
-xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
-xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
-xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o
-xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o
-xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o
-
-
-xfs-y += xfs_alloc.o \
- xfs_alloc_btree.o \
- xfs_attr.o \
- xfs_attr_leaf.o \
- xfs_bit.o \
- xfs_bmap.o \
- xfs_bmap_btree.o \
- xfs_btree.o \
- xfs_buf_item.o \
- xfs_da_btree.o \
- xfs_dir2.o \
- xfs_dir2_block.o \
- xfs_dir2_data.o \
- xfs_dir2_leaf.o \
- xfs_dir2_node.o \
- xfs_dir2_sf.o \
- xfs_error.o \
- xfs_extfree_item.o \
- xfs_filestream.o \
- xfs_fsops.o \
- xfs_ialloc.o \
- xfs_ialloc_btree.o \
- xfs_iget.o \
- xfs_inode.o \
- xfs_inode_item.o \
- xfs_iomap.o \
- xfs_itable.o \
- xfs_dfrag.o \
- xfs_log.o \
- xfs_log_recover.o \
- xfs_mount.o \
- xfs_mru_cache.o \
- xfs_rename.o \
- xfs_trans.o \
- xfs_trans_ail.o \
- xfs_trans_buf.o \
- xfs_trans_extfree.o \
- xfs_trans_inode.o \
- xfs_trans_item.o \
- xfs_utils.o \
- xfs_vfsops.o \
- xfs_vnodeops.o \
- xfs_rw.o \
- xfs_dmops.o \
- xfs_qmops.o
-
-xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o
-
-# Objects in linux/
-xfs-y += $(addprefix $(XFS_LINUX)/, \
- kmem.o \
- xfs_aops.o \
- xfs_buf.o \
- xfs_export.o \
- xfs_file.o \
- xfs_fs_subr.o \
- xfs_globals.o \
- xfs_ioctl.o \
- xfs_iops.o \
- xfs_lrw.o \
- xfs_super.o \
- xfs_vnode.o)
-
-# Objects in support/
-xfs-y += $(addprefix support/, \
- debug.o \
- uuid.o)
-
-xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o
-
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 21dfc9da235..8831d951879 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -171,7 +171,7 @@ xfs_parseargs(
char *this_char, *value, *eov;
int dsunit, dswidth, vol_dsunit, vol_dswidth;
int iosize;
- int ikeep = 0;
+ int dmapi_implies_ikeep = 1;
args->flags |= XFSMNT_BARRIER;
args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
@@ -302,10 +302,10 @@ xfs_parseargs(
} else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
args->flags &= ~XFSMNT_BARRIER;
} else if (!strcmp(this_char, MNTOPT_IKEEP)) {
- ikeep = 1;
- args->flags &= ~XFSMNT_IDELETE;
+ args->flags |= XFSMNT_IKEEP;
} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
- args->flags |= XFSMNT_IDELETE;
+ dmapi_implies_ikeep = 0;
+ args->flags &= ~XFSMNT_IKEEP;
} else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE;
} else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
@@ -410,8 +410,8 @@ xfs_parseargs(
* Note that if "ikeep" or "noikeep" mount options are
* supplied, then they are honored.
*/
- if (!(args->flags & XFSMNT_DMAPI) && !ikeep)
- args->flags |= XFSMNT_IDELETE;
+ if ((args->flags & XFSMNT_DMAPI) && dmapi_implies_ikeep)
+ args->flags |= XFSMNT_IKEEP;
if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
if (dsunit) {
@@ -446,6 +446,7 @@ xfs_showargs(
{
static struct proc_xfs_info xfs_info_set[] = {
/* the few simple ones we can get from the mount struct */
+ { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP },
{ XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC },
{ XFS_MOUNT_INO64, "," MNTOPT_INO64 },
{ XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN },
@@ -461,7 +462,6 @@ xfs_showargs(
};
static struct proc_xfs_info xfs_info_unset[] = {
/* the few simple ones we can get from the mount struct */
- { XFS_MOUNT_IDELETE, "," MNTOPT_IKEEP },
{ XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO },
{ XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER },
{ XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE },
diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c
index 48228848f5a..fab0b6d5a41 100644
--- a/fs/xfs/xfs_bit.c
+++ b/fs/xfs/xfs_bit.c
@@ -25,6 +25,109 @@
* XFS bit manipulation routines, used in non-realtime code.
*/
+#ifndef HAVE_ARCH_HIGHBIT
+/*
+ * Index of high bit number in byte, -1 for none set, 0..7 otherwise.
+ */
+static const char xfs_highbit[256] = {
+ -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */
+ 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */
+ 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */
+ 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */
+ 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */
+ 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */
+ 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */
+ 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */
+ 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */
+ 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */
+ 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */
+ 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */
+ 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */
+ 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */
+ 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */
+ 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */
+ 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */
+};
+#endif
+
+/*
+ * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set.
+ */
+inline int
+xfs_highbit32(
+ __uint32_t v)
+{
+#ifdef HAVE_ARCH_HIGHBIT
+ return highbit32(v);
+#else
+ int i;
+
+ if (v & 0xffff0000)
+ if (v & 0xff000000)
+ i = 24;
+ else
+ i = 16;
+ else if (v & 0x0000ffff)
+ if (v & 0x0000ff00)
+ i = 8;
+ else
+ i = 0;
+ else
+ return -1;
+ return i + xfs_highbit[(v >> i) & 0xff];
+#endif
+}
+
+/*
+ * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set.
+ */
+int
+xfs_lowbit64(
+ __uint64_t v)
+{
+ __uint32_t w = (__uint32_t)v;
+ int n = 0;
+
+ if (w) { /* lower bits */
+ n = ffs(w);
+ } else { /* upper bits */
+ w = (__uint32_t)(v >> 32);
+ if (w && (n = ffs(w)))
+ n += 32;
+ }
+ return n - 1;
+}
+
+/*
+ * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set.
+ */
+int
+xfs_highbit64(
+ __uint64_t v)
+{
+ __uint32_t h = (__uint32_t)(v >> 32);
+
+ if (h)
+ return xfs_highbit32(h) + 32;
+ return xfs_highbit32((__uint32_t)v);
+}
+
+
/*
* Return whether bitmap is empty.
* Size is number of words in the bitmap, which is padded to word boundary
diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h
index 325a007dec9..082641a9782 100644
--- a/fs/xfs/xfs_bit.h
+++ b/fs/xfs/xfs_bit.h
@@ -47,30 +47,13 @@ static inline __uint64_t xfs_mask64lo(int n)
}
/* Get high bit set out of 32-bit argument, -1 if none set */
-static inline int xfs_highbit32(__uint32_t v)
-{
- return fls(v) - 1;
-}
-
-/* Get high bit set out of 64-bit argument, -1 if none set */
-static inline int xfs_highbit64(__uint64_t v)
-{
- return fls64(v) - 1;
-}
-
-/* Get low bit set out of 32-bit argument, -1 if none set */
-static inline int xfs_lowbit32(__uint32_t v)
-{
- __uint32_t t = v;
- return (t) ? find_first_bit((unsigned long *)&t, 32) : -1;
-}
+extern int xfs_highbit32(__uint32_t v);
/* Get low bit set out of 64-bit argument, -1 if none set */
-static inline int xfs_lowbit64(__uint64_t v)
-{
- __uint64_t t = v;
- return (t) ? find_first_bit((unsigned long *)&t, 64) : -1;
-}
+extern int xfs_lowbit64(__uint64_t v);
+
+/* Get high bit set out of 64-bit argument, -1 if none set */
+extern int xfs_highbit64(__uint64_t);
/* Return whether bitmap is empty (1 == empty) */
extern int xfs_bitmap_empty(uint *map, uint size);
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h
index d16c1b97107..d5d1e60ee22 100644
--- a/fs/xfs/xfs_clnt.h
+++ b/fs/xfs/xfs_clnt.h
@@ -86,7 +86,7 @@ struct xfs_mount_args {
#define XFSMNT_NOUUID 0x01000000 /* Ignore fs uuid */
#define XFSMNT_DMAPI 0x02000000 /* enable dmapi/xdsm */
#define XFSMNT_BARRIER 0x04000000 /* use write barriers */
-#define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */
+#define XFSMNT_IKEEP 0x08000000 /* inode cluster delete */
#define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width
* allocation */
#define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index c5836b951d0..db9d5fa600a 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -1053,7 +1053,7 @@ xfs_difree(
/*
* When an inode cluster is free, it becomes eligible for removal
*/
- if ((mp->m_flags & XFS_MOUNT_IDELETE) &&
+ if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
(rec.ir_freecount == XFS_IALLOC_INODES(mp))) {
*delete = 1;
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index f01b07687fa..8e09b71f410 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -235,6 +235,7 @@ finish_inode:
*/
new_icl = kmem_zone_alloc(xfs_icluster_zone, KM_SLEEP);
if (radix_tree_preload(GFP_KERNEL)) {
+ xfs_idestroy(ip);
delay(1);
goto again;
}
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index f7c620ec6e6..1d8a4728d84 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -366,7 +366,7 @@ typedef struct xfs_mount {
#define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */
#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */
#define XFS_MOUNT_BARRIER (1ULL << 17)
-#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/
+#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/
#define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width
* allocation */
#define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index ca83ddf72af..47082c01872 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -73,6 +73,18 @@ STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int,
*/
/*
+ * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set.
+ */
+STATIC int
+xfs_lowbit32(
+ __uint32_t v)
+{
+ if (v)
+ return ffs(v) - 1;
+ return -1;
+}
+
+/*
* Allocate space to the bitmap or summary file, and zero it, for growfs.
*/
STATIC int /* error */
@@ -432,7 +444,6 @@ xfs_rtallocate_extent_near(
}
bbno = XFS_BITTOBLOCK(mp, bno);
i = 0;
- ASSERT(minlen != 0);
log2len = xfs_highbit32(minlen);
/*
* Loop over all bitmap blocks (bbno + i is current block).
@@ -601,8 +612,6 @@ xfs_rtallocate_extent_size(
xfs_suminfo_t sum; /* summary information for extents */
ASSERT(minlen % prod == 0 && maxlen % prod == 0);
- ASSERT(maxlen != 0);
-
/*
* Loop over all the levels starting with maxlen.
* At each level, look at all the bitmap blocks, to see if there
@@ -660,9 +669,6 @@ xfs_rtallocate_extent_size(
*rtblock = NULLRTBLOCK;
return 0;
}
- ASSERT(minlen != 0);
- ASSERT(maxlen != 0);
-
/*
* Loop over sizes, from maxlen down to minlen.
* This time, when we do the allocations, allow smaller ones
@@ -1948,7 +1954,6 @@ xfs_growfs_rt(
nsbp->sb_blocksize * nsbp->sb_rextsize);
nsbp->sb_rextents = nsbp->sb_rblocks;
do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
- ASSERT(nsbp->sb_rextents != 0);
nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
nrsumsize =
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 4d6330eddc8..76d470d8a1e 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -261,16 +261,19 @@ xfsaild_push(
xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
}
- /*
- * We reached the target so wait a bit longer for I/O to complete and
- * remove pushed items from the AIL before we start the next scan from
- * the start of the AIL.
- */
- if ((XFS_LSN_CMP(lsn, target) >= 0)) {
+ if (!count) {
+ /* We're past our target or empty, so idle */
+ tout = 1000;
+ } else if (XFS_LSN_CMP(lsn, target) >= 0) {
+ /*
+ * We reached the target so wait a bit longer for I/O to
+ * complete and remove pushed items from the AIL before we
+ * start the next scan from the start of the AIL.
+ */
tout += 20;
last_pushed_lsn = 0;
} else if ((restarts > XFS_TRANS_PUSH_AIL_RESTARTS) ||
- (count && ((stuck * 100) / count > 90))) {
+ ((stuck * 100) / count > 90)) {
/*
* Either there is a lot of contention on the AIL or we
* are stuck due to operations in progress. "Stuck" in this
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 413587f0215..7321304a69c 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -281,8 +281,8 @@ xfs_start_flags(
mp->m_readio_log = mp->m_writeio_log = ap->iosizelog;
}
- if (ap->flags & XFSMNT_IDELETE)
- mp->m_flags |= XFS_MOUNT_IDELETE;
+ if (ap->flags & XFSMNT_IKEEP)
+ mp->m_flags |= XFS_MOUNT_IKEEP;
if (ap->flags & XFSMNT_DIRSYNC)
mp->m_flags |= XFS_MOUNT_DIRSYNC;
if (ap->flags & XFSMNT_ATTR2)
diff --git a/include/asm-arm/arch-pxa/entry-macro.S b/include/asm-arm/arch-pxa/entry-macro.S
index b7e73085146..c145bb01bc8 100644
--- a/include/asm-arm/arch-pxa/entry-macro.S
+++ b/include/asm-arm/arch-pxa/entry-macro.S
@@ -35,7 +35,7 @@
1004:
mrc p6, 0, \irqstat, c6, c0, 0 @ ICIP2
mrc p6, 0, \irqnr, c7, c0, 0 @ ICMR2
- ands \irqstat, \irqstat, \irqnr
+ ands \irqnr, \irqstat, \irqnr
beq 1003f
rsb \irqstat, \irqnr, #0
and \irqstat, \irqstat, \irqnr
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index ac175b4d10c..2357a73340d 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -520,6 +520,9 @@
#define MCCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */
#define GCR __REG(0x4050000C) /* Global Control Register */
+#ifdef CONFIG_PXA3xx
+#define GCR_CLKBPB (1 << 31) /* Internal clock enable */
+#endif
#define GCR_nDMAEN (1 << 24) /* non DMA Enable */
#define GCR_CDONE_IE (1 << 19) /* Command Done Interrupt Enable */
#define GCR_SDONE_IE (1 << 18) /* Status Done Interrupt Enable */
diff --git a/include/asm-arm/arch-pxa/regs-ssp.h b/include/asm-arm/arch-pxa/regs-ssp.h
index 991cb688db7..0255328c3c1 100644
--- a/include/asm-arm/arch-pxa/regs-ssp.h
+++ b/include/asm-arm/arch-pxa/regs-ssp.h
@@ -85,6 +85,7 @@
#define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */
#define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */
#define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */
+#define SSCR1_IFS (1 << 16) /* Invert Frame Signal */
#define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */
#define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
index 1ee17b6951d..47fe34d692d 100644
--- a/include/asm-arm/kexec.h
+++ b/include/asm-arm/kexec.h
@@ -8,7 +8,7 @@
/* Maximum address we can reach in physical address mode */
#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
/* Maximum address we can use for the control code buffer */
-#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
#define KEXEC_CONTROL_CODE_SIZE 4096
diff --git a/include/asm-arm/kprobes.h b/include/asm-arm/kprobes.h
index 4e7bd32288a..c042194d3ab 100644
--- a/include/asm-arm/kprobes.h
+++ b/include/asm-arm/kprobes.h
@@ -20,7 +20,6 @@
#include <linux/ptrace.h>
#include <linux/percpu.h>
-#define ARCH_SUPPORTS_KRETPROBES
#define __ARCH_WANT_KPROBES_INSN_SLOT
#define MAX_INSN_SIZE 2
#define MAX_STACK_SIZE 64 /* 32 would probably be OK */
diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
index c59fad18e73..bcc8aed7c9a 100644
--- a/include/asm-arm/mach/arch.h
+++ b/include/asm-arm/mach/arch.h
@@ -17,7 +17,7 @@ struct sys_timer;
struct machine_desc {
/*
* Note! The first four elements are used
- * by assembler code in head-armv.S
+ * by assembler code in head.S, head-common.S
*/
unsigned int nr; /* architecture number */
unsigned int phys_io; /* start of physical io */
diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h
index 8431f6eed5c..5db03cf3b90 100644
--- a/include/asm-arm/unaligned.h
+++ b/include/asm-arm/unaligned.h
@@ -40,16 +40,16 @@ extern int __bug_unaligned_x(const void *ptr);
*/
#define __get_unaligned_2_le(__p) \
- (__p[0] | __p[1] << 8)
+ (unsigned int)(__p[0] | __p[1] << 8)
#define __get_unaligned_2_be(__p) \
- (__p[0] << 8 | __p[1])
+ (unsigned int)(__p[0] << 8 | __p[1])
#define __get_unaligned_4_le(__p) \
- (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
+ (unsigned int)(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
#define __get_unaligned_4_be(__p) \
- (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
+ (unsigned int)(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
#define __get_unaligned_8_le(__p) \
((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \
diff --git a/include/asm-avr32/pgtable.h b/include/asm-avr32/pgtable.h
index 018f6e2a024..3ae7b548fce 100644
--- a/include/asm-avr32/pgtable.h
+++ b/include/asm-avr32/pgtable.h
@@ -157,6 +157,7 @@ extern struct page *empty_zero_page;
#define _PAGE_S(x) _PAGE_NORMAL(x)
#define PAGE_COPY _PAGE_P(PAGE_WRITE | PAGE_READ)
+#define PAGE_SHARED _PAGE_S(PAGE_WRITE | PAGE_READ)
#ifndef __ASSEMBLY__
/*
diff --git a/include/asm-blackfin/gptimers.h b/include/asm-blackfin/gptimers.h
index 8265ea473d5..4f318f1fd2d 100644
--- a/include/asm-blackfin/gptimers.h
+++ b/include/asm-blackfin/gptimers.h
@@ -1,12 +1,11 @@
/*
- * include/asm/bf5xx_timers.h
- *
- * This file contains the major Data structures and constants
- * used for General Purpose Timer Implementation in BF5xx
+ * gptimers.h - Blackfin General Purpose Timer structs/defines/prototypes
*
+ * Copyright (c) 2005-2008 Analog Devices Inc.
* Copyright (C) 2005 John DeHority
* Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
*
+ * Licensed under the GPL-2.
*/
#ifndef _BLACKFIN_TIMERS_H_
diff --git a/include/asm-blackfin/irq.h b/include/asm-blackfin/irq.h
index 65480dab244..86b67834354 100644
--- a/include/asm-blackfin/irq.h
+++ b/include/asm-blackfin/irq.h
@@ -67,4 +67,6 @@ static __inline__ int irq_canonicalize(int irq)
#define NO_IRQ ((unsigned int)(-1))
#endif
+#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1))
+
#endif /* _BFIN_IRQ_H_ */
diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
index 15dbc21eed8..c0694ecd2ec 100644
--- a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
+++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
@@ -23,7 +23,6 @@
#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
#define UART_PUT_CHAR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_THR), v)
@@ -58,6 +57,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
int tx_count;
@@ -67,15 +67,31 @@ struct bfin_serial_port {
unsigned int tx_dma_channel;
unsigned int rx_dma_channel;
struct work_struct tx_dma_workqueue;
-#else
- struct work_struct cts_workqueue;
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ struct work_struct cts_workqueue;
int cts_pin;
int rts_pin;
#endif
};
+/* The hardware clears the LSR bits upon read, so we need to cache
+ * some of the more fun bits in software so they don't get lost
+ * when checking the LSR in other code paths (TX).
+ */
+static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
+{
+ unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
+ uart->lsr |= (lsr & (BI|FE|PE|OE));
+ return lsr | uart->lsr;
+}
+
+static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
+{
+ uart->lsr = 0;
+ bfin_write16(uart->port.membase + OFFSET_LSR, -1);
+}
+
struct bfin_serial_port bfin_serial_ports[NR_PORTS];
struct bfin_serial_res {
unsigned long uart_base_addr;
diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
index 7871d4313f4..b6f513bee56 100644
--- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
+++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
@@ -23,7 +23,6 @@
#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
@@ -46,6 +45,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
int tx_count;
@@ -56,14 +56,34 @@ struct bfin_serial_port {
unsigned int rx_dma_channel;
struct work_struct tx_dma_workqueue;
#else
- struct work_struct cts_workqueue;
+# if ANOMALY_05000230
+ unsigned int anomaly_threshold;
+# endif
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ struct work_struct cts_workqueue;
int cts_pin;
int rts_pin;
#endif
};
+/* The hardware clears the LSR bits upon read, so we need to cache
+ * some of the more fun bits in software so they don't get lost
+ * when checking the LSR in other code paths (TX).
+ */
+static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
+{
+ unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
+ uart->lsr |= (lsr & (BI|FE|PE|OE));
+ return lsr | uart->lsr;
+}
+
+static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
+{
+ uart->lsr = 0;
+ bfin_write16(uart->port.membase + OFFSET_LSR, -1);
+}
+
struct bfin_serial_port bfin_serial_ports[NR_PORTS];
struct bfin_serial_res {
unsigned long uart_base_addr;
diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
index 86e45c37983..8fc672d3105 100644
--- a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
+++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
@@ -23,7 +23,6 @@
#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
@@ -58,6 +57,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
int tx_count;
@@ -67,15 +67,31 @@ struct bfin_serial_port {
unsigned int tx_dma_channel;
unsigned int rx_dma_channel;
struct work_struct tx_dma_workqueue;
-#else
- struct work_struct cts_workqueue;
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ struct work_struct cts_workqueue;
int cts_pin;
int rts_pin;
#endif
};
+/* The hardware clears the LSR bits upon read, so we need to cache
+ * some of the more fun bits in software so they don't get lost
+ * when checking the LSR in other code paths (TX).
+ */
+static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
+{
+ unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
+ uart->lsr |= (lsr & (BI|FE|PE|OE));
+ return lsr | uart->lsr;
+}
+
+static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
+{
+ uart->lsr = 0;
+ bfin_write16(uart->port.membase + OFFSET_LSR, -1);
+}
+
struct bfin_serial_port bfin_serial_ports[NR_PORTS];
struct bfin_serial_res {
unsigned long uart_base_addr;
diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
index 3770aa38ee9..7e6339f62a5 100644
--- a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
+++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
@@ -24,6 +24,8 @@
#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
+#define UART_GET_MSR(uart) bfin_read16(((uart)->port.membase + OFFSET_MSR))
+#define UART_GET_MCR(uart) bfin_read16(((uart)->port.membase + OFFSET_MCR))
#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
@@ -32,7 +34,9 @@
#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
#define UART_PUT_LSR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LSR),v)
#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
+#define UART_CLEAR_LSR(uart) bfin_write16(((uart)->port.membase + OFFSET_LSR), -1)
#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
+#define UART_PUT_MCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_MCR),v)
#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
# define CONFIG_SERIAL_BFIN_CTSRTS
@@ -68,10 +72,9 @@ struct bfin_serial_port {
unsigned int tx_dma_channel;
unsigned int rx_dma_channel;
struct work_struct tx_dma_workqueue;
-#else
- struct work_struct cts_workqueue;
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ struct work_struct cts_workqueue;
int cts_pin;
int rts_pin;
#endif
diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
index 7871d4313f4..b6f513bee56 100644
--- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
+++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
@@ -23,7 +23,6 @@
#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
@@ -46,6 +45,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
int tx_count;
@@ -56,14 +56,34 @@ struct bfin_serial_port {
unsigned int rx_dma_channel;
struct work_struct tx_dma_workqueue;
#else
- struct work_struct cts_workqueue;
+# if ANOMALY_05000230
+ unsigned int anomaly_threshold;
+# endif
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ struct work_struct cts_workqueue;
int cts_pin;
int rts_pin;
#endif
};
+/* The hardware clears the LSR bits upon read, so we need to cache
+ * some of the more fun bits in software so they don't get lost
+ * when checking the LSR in other code paths (TX).
+ */
+static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
+{
+ unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
+ uart->lsr |= (lsr & (BI|FE|PE|OE));
+ return lsr | uart->lsr;
+}
+
+static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
+{
+ uart->lsr = 0;
+ bfin_write16(uart->port.membase + OFFSET_LSR, -1);
+}
+
struct bfin_serial_port bfin_serial_ports[NR_PORTS];
struct bfin_serial_res {
unsigned long uart_base_addr;
diff --git a/include/asm-blackfin/mach-bf561/blackfin.h b/include/asm-blackfin/mach-bf561/blackfin.h
index 362617f9384..3a16df2c86d 100644
--- a/include/asm-blackfin/mach-bf561/blackfin.h
+++ b/include/asm-blackfin/mach-bf561/blackfin.h
@@ -49,7 +49,8 @@
#define bfin_read_FIO_INEN() bfin_read_FIO0_INEN()
#define bfin_write_FIO_INEN(val) bfin_write_FIO0_INEN(val)
-
+#define SIC_IWR0 SICA_IWR0
+#define SIC_IWR1 SICA_IWR1
#define SIC_IAR0 SICA_IAR0
#define bfin_write_SIC_IMASK0 bfin_write_SICA_IMASK0
#define bfin_write_SIC_IMASK1 bfin_write_SICA_IMASK1
diff --git a/include/asm-blackfin/mach-bf561/cdefBF561.h b/include/asm-blackfin/mach-bf561/cdefBF561.h
index d667816486c..1bc8d2f89cc 100644
--- a/include/asm-blackfin/mach-bf561/cdefBF561.h
+++ b/include/asm-blackfin/mach-bf561/cdefBF561.h
@@ -559,6 +559,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
#define bfin_write_PPI0_CONTROL(val) bfin_write16(PPI0_CONTROL,val)
#define bfin_read_PPI0_STATUS() bfin_read16(PPI0_STATUS)
#define bfin_write_PPI0_STATUS(val) bfin_write16(PPI0_STATUS,val)
+#define bfin_clear_PPI0_STATUS() bfin_read_PPI0_STATUS()
#define bfin_read_PPI0_COUNT() bfin_read16(PPI0_COUNT)
#define bfin_write_PPI0_COUNT(val) bfin_write16(PPI0_COUNT,val)
#define bfin_read_PPI0_DELAY() bfin_read16(PPI0_DELAY)
@@ -570,6 +571,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
#define bfin_write_PPI1_CONTROL(val) bfin_write16(PPI1_CONTROL,val)
#define bfin_read_PPI1_STATUS() bfin_read16(PPI1_STATUS)
#define bfin_write_PPI1_STATUS(val) bfin_write16(PPI1_STATUS,val)
+#define bfin_clear_PPI1_STATUS() bfin_read_PPI1_STATUS()
#define bfin_read_PPI1_COUNT() bfin_read16(PPI1_COUNT)
#define bfin_write_PPI1_COUNT(val) bfin_write16(PPI1_COUNT,val)
#define bfin_read_PPI1_DELAY() bfin_read16(PPI1_DELAY)
diff --git a/include/asm-blackfin/mmu_context.h b/include/asm-blackfin/mmu_context.h
index b5eb67596ad..f55ec3c23a9 100644
--- a/include/asm-blackfin/mmu_context.h
+++ b/include/asm-blackfin/mmu_context.h
@@ -73,7 +73,7 @@ static inline void destroy_context(struct mm_struct *mm)
struct sram_list_struct *tmp;
if (current_l1_stack_save == mm->context.l1_stack_save)
- current_l1_stack_save = 0;
+ current_l1_stack_save = NULL;
if (mm->context.l1_stack_save)
free_l1stack();
diff --git a/include/asm-blackfin/unistd.h b/include/asm-blackfin/unistd.h
index e98167358d2..c18a399f6e3 100644
--- a/include/asm-blackfin/unistd.h
+++ b/include/asm-blackfin/unistd.h
@@ -361,7 +361,7 @@
#define __NR_epoll_pwait 346
#define __NR_utimensat 347
#define __NR_signalfd 348
-#define __NR_timerfd 349
+#define __NR_timerfd_create 349
#define __NR_eventfd 350
#define __NR_pread64 351
#define __NR_pwrite64 352
@@ -370,8 +370,10 @@
#define __NR_get_robust_list 355
#define __NR_fallocate 356
#define __NR_semtimedop 357
+#define __NR_timerfd_settime 358
+#define __NR_timerfd_gettime 359
-#define __NR_syscall 358
+#define __NR_syscall 360
#define NR_syscalls __NR_syscall
/* Old optional stuff no one actually uses */
diff --git a/include/asm-cris/uaccess.h b/include/asm-cris/uaccess.h
index 69d48a2dc8e..ea11eaf0e92 100644
--- a/include/asm-cris/uaccess.h
+++ b/include/asm-cris/uaccess.h
@@ -1,43 +1,6 @@
/*
* Authors: Bjorn Wesen (bjornw@axis.com)
* Hans-Peter Nilsson (hp@axis.com)
- *
- * $Log: uaccess.h,v $
- * Revision 1.8 2001/10/29 13:01:48 bjornw
- * Removed unused variable tmp2 in strnlen_user
- *
- * Revision 1.7 2001/10/02 12:44:52 hp
- * Add support for 64-bit put_user/get_user
- *
- * Revision 1.6 2001/10/01 14:51:17 bjornw
- * Added register prefixes and removed underscores
- *
- * Revision 1.5 2000/10/25 03:33:21 hp
- * - Provide implementation for everything else but get_user and put_user;
- * copying inline to/from user for constant length 0..16, 20, 24, and
- * clearing for 0..4, 8, 12, 16, 20, 24, strncpy_from_user and strnlen_user
- * always inline.
- * - Constraints for destination addr in get_user cannot be memory, only reg.
- * - Correct labels for PC at expected fault points.
- * - Nits with assembly code.
- * - Don't use statement expressions without value; use "do {} while (0)".
- * - Return correct values from __generic_... functions.
- *
- * Revision 1.4 2000/09/12 16:28:25 bjornw
- * * Removed comments from the get/put user asm code
- * * Constrains for destination addr in put_user cannot be memory, only reg
- *
- * Revision 1.3 2000/09/12 14:30:20 bjornw
- * MAX_ADDR_USER does not exist anymore
- *
- * Revision 1.2 2000/07/13 15:52:48 bjornw
- * New user-access functions
- *
- * Revision 1.1.1.1 2000/07/10 16:32:31 bjornw
- * CRIS architecture, working draft
- *
- *
- *
*/
/* Asm:s have been tweaked (within the domain of correctness) to give
@@ -209,9 +172,9 @@ extern long __get_user_bad(void);
/* More complex functions. Most are inline, but some call functions that
live in lib/usercopy.c */
-extern unsigned long __copy_user(void *to, const void *from, unsigned long n);
-extern unsigned long __copy_user_zeroing(void *to, const void *from, unsigned long n);
-extern unsigned long __do_clear_user(void *to, unsigned long n);
+extern unsigned long __copy_user(void __user *to, const void *from, unsigned long n);
+extern unsigned long __copy_user_zeroing(void *to, const void __user *from, unsigned long n);
+extern unsigned long __do_clear_user(void __user *to, unsigned long n);
static inline unsigned long
__generic_copy_to_user(void __user *to, const void *from, unsigned long n)
@@ -253,7 +216,7 @@ strncpy_from_user(char *dst, const char __user *src, long count)
}
-/* Note that if these expand awfully if made into switch constructs, so
+/* Note that these expand awfully if made into switch constructs, so
don't do that. */
static inline unsigned long
@@ -407,19 +370,21 @@ __constant_clear_user(void __user *to, unsigned long n)
*/
static inline unsigned long
-__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
+__generic_copy_from_user_nocheck(void *to, const void __user *from,
+ unsigned long n)
{
return __copy_user_zeroing(to,from,n);
}
static inline unsigned long
-__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
+__generic_copy_to_user_nocheck(void __user *to, const void *from,
+ unsigned long n)
{
return __copy_user(to,from,n);
}
static inline unsigned long
-__generic_clear_user_nocheck(void *to, unsigned long n)
+__generic_clear_user_nocheck(void __user *to, unsigned long n)
{
return __do_clear_user(to,n);
}
diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h
index 007cb16a6b5..76398ef87e9 100644
--- a/include/asm-cris/unistd.h
+++ b/include/asm-cris/unistd.h
@@ -329,12 +329,12 @@
#define __NR_timerfd_create 322
#define __NR_eventfd 323
#define __NR_fallocate 324
-#define __NR_timerfd_settime 315
-#define __NR_timerfd_gettime 316
+#define __NR_timerfd_settime 325
+#define __NR_timerfd_gettime 326
#ifdef __KERNEL__
-#define NR_syscalls 325
+#define NR_syscalls 327
#include <asm/arch/unistd.h>
diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h
index e8c98666753..f184eb8c047 100644
--- a/include/asm-frv/unistd.h
+++ b/include/asm-frv/unistd.h
@@ -328,9 +328,11 @@
#define __NR_epoll_pwait 319
#define __NR_utimensat 320
#define __NR_signalfd 321
-/* #define __NR_timerfd 322 removed */
+#define __NR_timerfd_create 322
#define __NR_eventfd 323
#define __NR_fallocate 324
+#define __NR_timerfd_settime 325
+#define __NR_timerfd_gettime 326
#ifdef __KERNEL__
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index 4b8d31cda1a..b0e63c672eb 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -32,6 +32,8 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
*/
#ifndef __my_cpu_offset
#define __my_cpu_offset per_cpu_offset(raw_smp_processor_id())
+#endif
+#ifdef CONFIG_DEBUG_PREEMPT
#define my_cpu_offset per_cpu_offset(smp_processor_id())
#else
#define my_cpu_offset __my_cpu_offset
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index f784d2f3414..f054778e916 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -238,6 +238,9 @@
*(.kprobes.text) \
VMLINUX_SYMBOL(__kprobes_text_end) = .;
+/* Section used for early init (in .S files) */
+#define HEAD_TEXT *(.head.text)
+
/* init and exit section handling */
#define INIT_DATA \
*(.init.data) \
diff --git a/include/asm-h8300/hardirq.h b/include/asm-h8300/hardirq.h
index 18fa7931e09..9d7f7a7462b 100644
--- a/include/asm-h8300/hardirq.h
+++ b/include/asm-h8300/hardirq.h
@@ -12,6 +12,8 @@ typedef struct {
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+extern void ack_bad_irq(unsigned int irq);
+
#define HARDIRQ_BITS 8
/*
diff --git a/include/asm-h8300/irq.h b/include/asm-h8300/irq.h
index 56eec28cc2c..13d7c601cd0 100644
--- a/include/asm-h8300/irq.h
+++ b/include/asm-h8300/irq.h
@@ -3,7 +3,7 @@
#include <asm/ptrace.h>
-#if defined(__H8300H__)
+#if defined(CONFIG_CPU_H8300H)
#define NR_IRQS 64
#define EXT_IRQ0 12
#define EXT_IRQ1 13
@@ -14,14 +14,6 @@
#define EXT_IRQ6 18
#define EXT_IRQ7 19
#define EXT_IRQS 5
-
-#include <asm/regs306x.h>
-#define h8300_clear_isr(irq) \
-do { \
- if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5) \
- *(volatile unsigned char *)ISR &= ~(1 << (irq - EXT_IRQ0)); \
-} while(0)
-
#define IER_REGS *(volatile unsigned char *)IER
#endif
#if defined(CONFIG_CPU_H8S)
@@ -44,13 +36,6 @@ do { \
#define EXT_IRQ15 31
#define EXT_IRQS 15
-#include <asm/regs267x.h>
-#define h8300_clear_isr(irq) \
-do { \
- if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) \
- *(volatile unsigned short *)ISR &= ~(1 << (irq - EXT_IRQ0)); \
-} while(0)
-
#define IER_REGS *(volatile unsigned short *)IER
#endif
@@ -59,4 +44,6 @@ static __inline__ int irq_canonicalize(int irq)
return irq;
}
+typedef void (*h8300_vector)(void);
+
#endif /* _H8300_IRQ_H_ */
diff --git a/include/asm-h8300/uaccess.h b/include/asm-h8300/uaccess.h
index ebe58c6c838..a22350ec271 100644
--- a/include/asm-h8300/uaccess.h
+++ b/include/asm-h8300/uaccess.h
@@ -91,7 +91,7 @@ extern int __put_user_bad(void);
#define get_user(x, ptr) \
({ \
int __gu_err = 0; \
- typeof(*(ptr)) __gu_val = 0; \
+ uint32_t __gu_val = 0; \
switch (sizeof(*(ptr))) { \
case 1: \
case 2: \
@@ -106,7 +106,7 @@ extern int __put_user_bad(void);
__gu_err = __get_user_bad(); \
break; \
} \
- (x) = __gu_val; \
+ (x) = (typeof(*(ptr)))__gu_val; \
__gu_err; \
})
#define __get_user(x, ptr) get_user(x, ptr)
diff --git a/include/asm-ia64/Kbuild b/include/asm-ia64/Kbuild
index 4a1e48b9f40..eb24a3f47ca 100644
--- a/include/asm-ia64/Kbuild
+++ b/include/asm-ia64/Kbuild
@@ -3,7 +3,6 @@ include include/asm-generic/Kbuild.asm
header-y += break.h
header-y += fpu.h
header-y += fpswa.h
-header-y += gcc_intrin.h
header-y += ia64regs.h
header-y += intel_intrin.h
header-y += intrinsics.h
@@ -12,5 +11,6 @@ header-y += ptrace_offsets.h
header-y += rse.h
header-y += ucontext.h
+unifdef-y += gcc_intrin.h
unifdef-y += perfmon.h
unifdef-y += ustack.h
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h
index 7e6e3779670..76366dc9c1a 100644
--- a/include/asm-ia64/hw_irq.h
+++ b/include/asm-ia64/hw_irq.h
@@ -93,6 +93,9 @@ extern __u8 isa_irq_to_vector_map[16];
struct irq_cfg {
ia64_vector vector;
cpumask_t domain;
+ cpumask_t old_domain;
+ unsigned move_cleanup_count;
+ u8 move_in_progress : 1;
};
extern spinlock_t vector_lock;
extern struct irq_cfg irq_cfg[NR_IRQS];
@@ -106,12 +109,19 @@ extern int assign_irq_vector (int irq); /* allocate a free vector */
extern void free_irq_vector (int vector);
extern int reserve_irq_vector (int vector);
extern void __setup_vector_irq(int cpu);
-extern int reassign_irq_vector(int irq, int cpu);
extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
extern int check_irq_used (int irq);
extern void destroy_and_reserve_irq (unsigned int irq);
+#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG))
+extern int irq_prepare_move(int irq, int cpu);
+extern void irq_complete_move(unsigned int irq);
+#else
+static inline int irq_prepare_move(int irq, int cpu) { return 0; }
+static inline void irq_complete_move(unsigned int irq) {}
+#endif
+
static inline void ia64_resend_irq(unsigned int vector)
{
platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h
index a93ce9ef07f..d03bf9ff68e 100644
--- a/include/asm-ia64/kprobes.h
+++ b/include/asm-ia64/kprobes.h
@@ -82,7 +82,6 @@ struct kprobe_ctlblk {
struct prev_kprobe prev_kprobe[ARCH_PREV_KPROBE_SZ];
};
-#define ARCH_SUPPORTS_KRETPROBES
#define kretprobe_blacklist_size 0
#define SLOT0_OPCODE_SHIFT (37)
@@ -118,14 +117,10 @@ struct arch_specific_insn {
unsigned short slot;
};
-extern int kprobes_fault_handler(struct pt_regs *regs, int trapnr);
+extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
extern int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
-/* ia64 does not need this */
-static inline void jprobe_return(void)
-{
-}
extern void invalidate_stacked_regs(void);
extern void flush_register_stack(void);
extern void arch_remove_kprobe(struct kprobe *p);
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
index 0bdce7dde1b..4b2a8d40ebc 100644
--- a/include/asm-ia64/ptrace.h
+++ b/include/asm-ia64/ptrace.h
@@ -233,8 +233,6 @@ struct switch_stack {
#include <asm/current.h>
#include <asm/page.h>
-#define __ARCH_SYS_PTRACE 1
-
/*
* We use the ia64_psr(regs)->ri to determine which of the three
* instructions in bundle (16 bytes) took the sample. Generate
@@ -314,6 +312,13 @@ struct switch_stack {
#define arch_ptrace_attach(child) \
ptrace_attach_sync_user_rbs(child)
+ #define arch_has_single_step() (1)
+ extern void user_enable_single_step(struct task_struct *);
+ extern void user_disable_single_step(struct task_struct *);
+
+ #define arch_has_block_step() (1)
+ extern void user_enable_block_step(struct task_struct *);
+
#endif /* !__KERNEL__ */
/* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */
diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h
index 2251118894a..f4904db3b05 100644
--- a/include/asm-ia64/sal.h
+++ b/include/asm-ia64/sal.h
@@ -807,6 +807,10 @@ static inline s64
ia64_sal_physical_id_info(u16 *splid)
{
struct ia64_sal_retval isrv;
+
+ if (sal_revision < SAL_VERSION_CODE(3,2))
+ return -1;
+
SAL_CALL(isrv, SAL_PHYSICAL_ID_INFO, 0, 0, 0, 0, 0, 0, 0);
if (splid)
*splid = isrv.v0;
diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
index 87f77b11931..e72ba563f10 100644
--- a/include/asm-m68k/unistd.h
+++ b/include/asm-m68k/unistd.h
@@ -320,13 +320,15 @@
#define __NR_epoll_pwait 315
#define __NR_utimensat 316
#define __NR_signalfd 317
-#define __NR_timerfd 318
+#define __NR_timerfd_create 318
#define __NR_eventfd 319
#define __NR_fallocate 320
+#define __NR_timerfd_settime 321
+#define __NR_timerfd_gettime 322
#ifdef __KERNEL__
-#define NR_syscalls 321
+#define NR_syscalls 323
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/include/asm-m68knommu/machdep.h b/include/asm-m68knommu/machdep.h
index 1cf26d240d8..de9f47a51cc 100644
--- a/include/asm-m68knommu/machdep.h
+++ b/include/asm-m68knommu/machdep.h
@@ -21,4 +21,6 @@ extern void (*mach_power_off)( void );
extern void config_BSP(char *command, int len);
+extern void do_IRQ(int irq, struct pt_regs *fp);
+
#endif /* _M68KNOMMU_MACHDEP_H */
diff --git a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h
index 27c2f9bb4db..4ba98b9c5d7 100644
--- a/include/asm-m68knommu/unistd.h
+++ b/include/asm-m68knommu/unistd.h
@@ -321,13 +321,15 @@
#define __NR_epoll_pwait 315
#define __NR_utimensat 316
#define __NR_signalfd 317
-#define __NR_timerfd 318
+#define __NR_timerfd_create 318
#define __NR_eventfd 319
#define __NR_fallocate 320
+#define __NR_timerfd_settime 321
+#define __NR_timerfd_gettime 322
#ifdef __KERNEL__
-#define NR_syscalls 321
+#define NR_syscalls 323
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/include/asm-mips/mach-db1x00/db1200.h b/include/asm-mips/mach-db1x00/db1200.h
index 050eae87ff0..a6bdac61ab4 100644
--- a/include/asm-mips/mach-db1x00/db1200.h
+++ b/include/asm-mips/mach-db1x00/db1200.h
@@ -25,6 +25,7 @@
#define __ASM_DB1200_H
#include <linux/types.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
// This is defined in au1000.h with bogus value
#undef AU1X00_EXTERNAL_INT
diff --git a/include/asm-mips/mach-db1x00/db1x00.h b/include/asm-mips/mach-db1x00/db1x00.h
index 0f5f4c29f4e..e7a88ba3583 100644
--- a/include/asm-mips/mach-db1x00/db1x00.h
+++ b/include/asm-mips/mach-db1x00/db1x00.h
@@ -28,6 +28,7 @@
#ifndef __ASM_DB1X00_H
#define __ASM_DB1X00_H
+#include <asm/mach-au1x00/au1xxx_psc.h>
#ifdef CONFIG_MIPS_DB1550
diff --git a/include/asm-mips/mach-ip27/dma-coherence.h b/include/asm-mips/mach-ip27/dma-coherence.h
index 3fdbbf68e95..ed7e6222dc1 100644
--- a/include/asm-mips/mach-ip27/dma-coherence.h
+++ b/include/asm-mips/mach-ip27/dma-coherence.h
@@ -35,7 +35,7 @@ static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
{
- return dma_addr & (0xffUL << 56);
+ return dma_addr & ~(0xffUL << 56);
}
static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
diff --git a/include/asm-mips/mach-pb1x00/pb1200.h b/include/asm-mips/mach-pb1x00/pb1200.h
index d9f384acfea..ed5fd739067 100644
--- a/include/asm-mips/mach-pb1x00/pb1200.h
+++ b/include/asm-mips/mach-pb1x00/pb1200.h
@@ -25,6 +25,7 @@
#define __ASM_PB1200_H
#include <linux/types.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
// This is defined in au1000.h with bogus value
#undef AU1X00_EXTERNAL_INT
diff --git a/include/asm-mips/mach-pb1x00/pb1550.h b/include/asm-mips/mach-pb1x00/pb1550.h
index 9a4955ce3b4..c2ab0e2df4a 100644
--- a/include/asm-mips/mach-pb1x00/pb1550.h
+++ b/include/asm-mips/mach-pb1x00/pb1550.h
@@ -28,6 +28,7 @@
#define __ASM_PB1550_H
#include <linux/types.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
diff --git a/include/asm-mips/qemu.h b/include/asm-mips/qemu.h
deleted file mode 100644
index 487ced4a40d..00000000000
--- a/include/asm-mips/qemu.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2005 by Ralf Baechle (ralf@linux-mips.org)
- */
-#ifndef __ASM_QEMU_H
-#define __ASM_QEMU_H
-
-/*
- * Interrupt numbers
- */
-#define Q_PIC_IRQ_BASE 0
-#define Q_COUNT_COMPARE_IRQ 23
-
-/*
- * Qemu clock rate. Unlike on real MIPS this has no relation to the
- * instruction issue rate, so the choosen value is pure fiction, just needs
- * to match the value in Qemu itself.
- */
-#define QEMU_C0_COUNTER_CLOCK 100000000
-
-/*
- * Magic qemu system control location.
- */
-#define QEMU_RESTART_REG 0xBFBF0000
-#define QEMU_HALT_REG 0xBFBF0004
-
-#endif /* __ASM_QEMU_H */
diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h
index e716447e5e0..8c1eb02c6d1 100644
--- a/include/asm-mips/sni.h
+++ b/include/asm-mips/sni.h
@@ -228,7 +228,14 @@ extern void sni_pcimt_irq_init(void);
extern void sni_cpu_time_init(void);
/* eisa init for RM200/400 */
+#ifdef CONFIG_EISA
extern int sni_eisa_root_init(void);
+#else
+static inline int sni_eisa_root_init(void)
+{
+ return 0;
+}
+#endif
/* common irq stuff */
extern void (*sni_hwint)(void);
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
index fa9a587b3bf..4964c82f85f 100644
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -341,16 +341,19 @@
#define __NR_timerfd (__NR_Linux + 318)
#define __NR_eventfd (__NR_Linux + 319)
#define __NR_fallocate (__NR_Linux + 320)
+#define __NR_timerfd_create (__NR_Linux + 321)
+#define __NR_timerfd_gettime (__NR_Linux + 322)
+#define __NR_timerfd_settime (__NR_Linux + 323)
/*
* Offset of the last Linux o32 flavoured syscall
*/
-#define __NR_Linux_syscalls 320
+#define __NR_Linux_syscalls 323
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 320
+#define __NR_O32_Linux_syscalls 323
#if _MIPS_SIM == _MIPS_SIM_ABI64
@@ -638,16 +641,19 @@
#define __NR_timerfd (__NR_Linux + 277)
#define __NR_eventfd (__NR_Linux + 278)
#define __NR_fallocate (__NR_Linux + 279)
+#define __NR_timerfd_create (__NR_Linux + 280)
+#define __NR_timerfd_gettime (__NR_Linux + 281)
+#define __NR_timerfd_settime (__NR_Linux + 282)
/*
* Offset of the last Linux 64-bit flavoured syscall
*/
-#define __NR_Linux_syscalls 279
+#define __NR_Linux_syscalls 282
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 279
+#define __NR_64_Linux_syscalls 282
#if _MIPS_SIM == _MIPS_SIM_NABI32
@@ -939,16 +945,19 @@
#define __NR_timerfd (__NR_Linux + 281)
#define __NR_eventfd (__NR_Linux + 282)
#define __NR_fallocate (__NR_Linux + 283)
+#define __NR_timerfd_create (__NR_Linux + 284)
+#define __NR_timerfd_gettime (__NR_Linux + 285)
+#define __NR_timerfd_settime (__NR_Linux + 286)
/*
* Offset of the last N32 flavoured syscall
*/
-#define __NR_Linux_syscalls 283
+#define __NR_Linux_syscalls 286
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 283
+#define __NR_N32_Linux_syscalls 286
#ifdef __KERNEL__
diff --git a/include/asm-mn10300/Kbuild b/include/asm-mn10300/Kbuild
index 79384c537dc..c68e1680da0 100644
--- a/include/asm-mn10300/Kbuild
+++ b/include/asm-mn10300/Kbuild
@@ -1,5 +1 @@
include include/asm-generic/Kbuild.asm
-
-unifdef-y += termios.h
-unifdef-y += ptrace.h
-unifdef-y += page.h
diff --git a/include/asm-mn10300/param.h b/include/asm-mn10300/param.h
index 54b883ec390..789b1df41fc 100644
--- a/include/asm-mn10300/param.h
+++ b/include/asm-mn10300/param.h
@@ -12,7 +12,7 @@
#define _ASM_PARAM_H
#ifdef __KERNEL__
-#define HZ 1000 /* Internal kernel timer frequency */
+#define HZ CONFIG_HZ /* Internal kernel timer frequency */
#define USER_HZ 100 /* .. some user interfaces are in
* "ticks" */
#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
diff --git a/include/asm-mn10300/socket.h b/include/asm-mn10300/socket.h
index 99ca648b94c..80af9c4ccad 100644
--- a/include/asm-mn10300/socket.h
+++ b/include/asm-mn10300/socket.h
@@ -52,4 +52,6 @@
#define SO_TIMESTAMPNS 35
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index afabad230db..d0e7701fa1f 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -80,7 +80,6 @@ typedef unsigned int kprobe_opcode_t;
#define is_trap(instr) (IS_TW(instr) || IS_TWI(instr))
#endif
-#define ARCH_SUPPORTS_KRETPROBES
#define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0
diff --git a/include/asm-powerpc/percpu.h b/include/asm-powerpc/percpu.h
index ccb0523eb3b..f879252b7ea 100644
--- a/include/asm-powerpc/percpu.h
+++ b/include/asm-powerpc/percpu.h
@@ -13,7 +13,7 @@
#include <asm/paca.h>
#define __per_cpu_offset(cpu) (paca[cpu].data_offset)
-#define __my_cpu_offset get_paca()->data_offset
+#define __my_cpu_offset local_paca->data_offset
#define per_cpu_offset(x) (__per_cpu_offset(x))
#endif /* CONFIG_SMP */
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 0d6238987df..edc0cfd7f6e 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -153,6 +153,9 @@
#define CTRL_RUNLATCH 0x1
#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
#define DABR_TRANSLATION (1UL << 2)
+#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */
+#define DABRX_USER (1UL << 0)
+#define DABRX_KERNEL (1UL << 1)
#define SPRN_DAR 0x013 /* Data Address Register */
#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
#define DSISR_NOHPTE 0x40000000 /* no translation found */
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index f07c99ba5d1..e3c845b0f76 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -98,9 +98,8 @@
#define MFC_PRIV_ATTN_EVENT 0x00000800
#define MFC_MULTI_SRC_EVENT 0x00001000
-/* Flags indicating progress during context switch. */
+/* Flag indicating progress during context switch. */
#define SPU_CONTEXT_SWITCH_PENDING 0UL
-#define SPU_CONTEXT_SWITCH_ACTIVE 1UL
struct spu_context;
struct spu_runqueue;
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index ab83c844d04..965394e6945 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -456,16 +456,18 @@ static inline unsigned long __ffz_word_loop(const unsigned long *addr,
asm volatile(
#ifndef __s390x__
- " ahi %1,31\n"
- " srl %1,5\n"
+ " ahi %1,-1\n"
+ " sra %1,5\n"
+ " jz 1f\n"
"0: c %2,0(%0,%3)\n"
" jne 1f\n"
" la %0,4(%0)\n"
" brct %1,0b\n"
"1:\n"
#else
- " aghi %1,63\n"
- " srlg %1,%1,6\n"
+ " aghi %1,-1\n"
+ " srag %1,%1,6\n"
+ " jz 1f\n"
"0: cg %2,0(%0,%3)\n"
" jne 1f\n"
" la %0,8(%0)\n"
@@ -491,16 +493,18 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr,
asm volatile(
#ifndef __s390x__
- " ahi %1,31\n"
- " srl %1,5\n"
+ " ahi %1,-1\n"
+ " sra %1,5\n"
+ " jz 1f\n"
"0: c %2,0(%0,%3)\n"
" jne 1f\n"
" la %0,4(%0)\n"
" brct %1,0b\n"
"1:\n"
#else
- " aghi %1,63\n"
- " srlg %1,%1,6\n"
+ " aghi %1,-1\n"
+ " srag %1,%1,6\n"
+ " jz 1f\n"
"0: cg %2,0(%0,%3)\n"
" jne 1f\n"
" la %0,8(%0)\n"
diff --git a/include/asm-s390/kprobes.h b/include/asm-s390/kprobes.h
index 948db3d0d05..330f68caffe 100644
--- a/include/asm-s390/kprobes.h
+++ b/include/asm-s390/kprobes.h
@@ -46,7 +46,6 @@ typedef u16 kprobe_opcode_t;
? (MAX_STACK_SIZE) \
: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
-#define ARCH_SUPPORTS_KRETPROBES
#define kretprobe_blacklist_size 0
#define KPROBE_SWAP_INST 0x10
diff --git a/include/asm-sh/cpu-sh3/cache.h b/include/asm-sh/cpu-sh3/cache.h
index 56bd838b7db..bee2d81c56b 100644
--- a/include/asm-sh/cpu-sh3/cache.h
+++ b/include/asm-sh/cpu-sh3/cache.h
@@ -35,7 +35,7 @@
defined(CONFIG_CPU_SUBTYPE_SH7710) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define CCR3 0xa40000b4
+#define CCR3_REG 0xa40000b4
#define CCR_CACHE_16KB 0x00010000
#define CCR_CACHE_32KB 0x00020000
#endif
diff --git a/include/asm-sh/delay.h b/include/asm-sh/delay.h
index d5d46404100..4b16bf9b56b 100644
--- a/include/asm-sh/delay.h
+++ b/include/asm-sh/delay.h
@@ -15,7 +15,6 @@ extern void __ndelay(unsigned long nsecs);
extern void __const_udelay(unsigned long xloops);
extern void __delay(unsigned long loops);
-#ifdef CONFIG_SUPERH32
#define udelay(n) (__builtin_constant_p(n) ? \
((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \
__udelay(n))
@@ -23,9 +22,5 @@ extern void __delay(unsigned long loops);
#define ndelay(n) (__builtin_constant_p(n) ? \
((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
__ndelay(n))
-#else
-extern void udelay(unsigned long usecs);
-extern void ndelay(unsigned long nsecs);
-#endif
#endif /* __ASM_SH_DELAY_H */
diff --git a/include/asm-sh/entry-macros.S b/include/asm-sh/entry-macros.S
index 500030eae7a..2dab0b8d945 100644
--- a/include/asm-sh/entry-macros.S
+++ b/include/asm-sh/entry-macros.S
@@ -12,7 +12,7 @@
not r11, r11
stc sr, r10
and r11, r10
-#ifdef CONFIG_HAS_SR_RB
+#ifdef CONFIG_CPU_HAS_SR_RB
stc k_g_imask, r11
or r11, r10
#endif
@@ -20,7 +20,7 @@
.endm
.macro get_current_thread_info, ti, tmp
-#ifdef CONFIG_HAS_SR_RB
+#ifdef CONFIG_CPU_HAS_SR_RB
stc r7_bank, \ti
#else
mov #((THREAD_SIZE - 1) >> 10) ^ 0xff, \tmp
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
index 45e47c159a6..4e08210cd4c 100644
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -44,6 +44,8 @@ extern enum sparc_cpu sparc_cpu_model;
#define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */
+extern char reboot_command[];
+
extern struct thread_info *current_set[NR_CPUS];
extern unsigned long empty_bad_page;
diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h
index 7237dd87663..5879d71afda 100644
--- a/include/asm-sparc64/kprobes.h
+++ b/include/asm-sparc64/kprobes.h
@@ -14,8 +14,6 @@ typedef u32 kprobe_opcode_t;
#define arch_remove_kprobe(p) do {} while (0)
-#define ARCH_SUPPORTS_KRETPROBES
-
#define flush_insn_slot(p) \
do { flushi(&(p)->ainsn.insn[0]); \
flushi(&(p)->ainsn.insn[1]); \
diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h
index 8617c3a5143..6da197803ef 100644
--- a/include/asm-sparc64/ptrace.h
+++ b/include/asm-sparc64/ptrace.h
@@ -102,12 +102,14 @@ do { current_thread_info()->syscall_noerror = 1; \
} while (0)
#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
#define instruction_pointer(regs) ((regs)->tpc)
+#define regs_return_value(regs) ((regs)->u_regs[UREG_I0])
#ifdef CONFIG_SMP
extern unsigned long profile_pc(struct pt_regs *);
#else
#define profile_pc(regs) instruction_pointer(regs)
#endif
extern void show_regs(struct pt_regs *);
+extern void __show_regs(struct pt_regs *);
#endif
#else /* __ASSEMBLY__ */
diff --git a/include/asm-sparc64/reboot.h b/include/asm-sparc64/reboot.h
new file mode 100644
index 00000000000..3f3f43f5be5
--- /dev/null
+++ b/include/asm-sparc64/reboot.h
@@ -0,0 +1,6 @@
+#ifndef _SPARC64_REBOOT_H
+#define _SPARC64_REBOOT_H
+
+extern void machine_alt_power_off(void);
+
+#endif /* _SPARC64_REBOOT_H */
diff --git a/include/asm-sparc64/syscalls.h b/include/asm-sparc64/syscalls.h
new file mode 100644
index 00000000000..45a43f637a1
--- /dev/null
+++ b/include/asm-sparc64/syscalls.h
@@ -0,0 +1,13 @@
+#ifndef _SPARC64_SYSCALLS_H
+#define _SPARC64_SYSCALLS_H
+
+struct pt_regs;
+
+extern asmlinkage long sparc_do_fork(unsigned long clone_flags,
+ unsigned long stack_start,
+ struct pt_regs *regs,
+ unsigned long stack_size);
+
+extern asmlinkage int sparc_execve(struct pt_regs *regs);
+
+#endif /* _SPARC64_SYSCALLS_H */
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 1faefa6d370..53eae091a17 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -30,6 +30,8 @@ enum sparc_cpu {
#define ARCH_SUN4C_SUN4 0
#define ARCH_SUN4 0
+extern char reboot_command[];
+
/* These are here in an effort to more fully work around Spitfire Errata
* #51. Essentially, if a memory barrier occurs soon after a mispredicted
* branch, the chip can stop executing instructions until a trap occurs.
@@ -117,6 +119,7 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
extern void sun_do_break(void);
extern int stop_a_enabled;
+extern void fault_in_user_windows(void);
extern void synchronize_user_stack(void);
extern void __flushw_user(void);
diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild
index b04a7ff46df..3b8160a2b47 100644
--- a/include/asm-x86/Kbuild
+++ b/include/asm-x86/Kbuild
@@ -16,7 +16,6 @@ unifdef-y += ist.h
unifdef-y += mce.h
unifdef-y += msr.h
unifdef-y += mtrr.h
-unifdef-y += page.h
unifdef-y += posix_types_32.h
unifdef-y += posix_types_64.h
unifdef-y += ptrace.h
diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h
deleted file mode 100644
index 8b137891791..00000000000
--- a/include/asm-x86/desc_64.h
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/include/asm-x86/futex.h b/include/asm-x86/futex.h
index cd9f894dd2d..c9952ea9f69 100644
--- a/include/asm-x86/futex.h
+++ b/include/asm-x86/futex.h
@@ -102,6 +102,13 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
static inline int
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
+
+#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP)
+ /* Real i386 machines have no cmpxchg instruction */
+ if (boot_cpu_data.x86 == 3)
+ return -ENOSYS;
+#endif
+
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h
index 6b1895ccd6b..f377b76b2f3 100644
--- a/include/asm-x86/i387.h
+++ b/include/asm-x86/i387.h
@@ -20,7 +20,6 @@
#include <asm/uaccess.h>
extern void fpu_init(void);
-extern unsigned int mxcsr_feature_mask;
extern void mxcsr_feature_mask_init(void);
extern void init_fpu(struct task_struct *child);
extern asmlinkage void math_state_restore(void);
diff --git a/include/asm-x86/kprobes.h b/include/asm-x86/kprobes.h
index 143476a3cb5..61ad7b5d142 100644
--- a/include/asm-x86/kprobes.h
+++ b/include/asm-x86/kprobes.h
@@ -42,7 +42,6 @@ typedef u8 kprobe_opcode_t;
: (((unsigned long)current_thread_info()) + THREAD_SIZE \
- (unsigned long)(ADDR)))
-#define ARCH_SUPPORTS_KRETPROBES
#define flush_insn_slot(p) do { } while (0)
extern const int kretprobe_blacklist_size;
diff --git a/include/asm-x86/lguest.h b/include/asm-x86/lguest.h
index 4d9367b7297..9b17571e9bc 100644
--- a/include/asm-x86/lguest.h
+++ b/include/asm-x86/lguest.h
@@ -23,6 +23,17 @@
/* Found in switcher.S */
extern unsigned long default_idt_entries[];
+/* Declarations for definitions in lguest_guest.S */
+extern char lguest_noirq_start[], lguest_noirq_end[];
+extern const char lgstart_cli[], lgend_cli[];
+extern const char lgstart_sti[], lgend_sti[];
+extern const char lgstart_popf[], lgend_popf[];
+extern const char lgstart_pushf[], lgend_pushf[];
+extern const char lgstart_iret[], lgend_iret[];
+
+extern void lguest_iret(void);
+extern void lguest_init(void);
+
struct lguest_regs
{
/* Manually saved part. */
diff --git a/include/asm-x86/nops.h b/include/asm-x86/nops.h
index fec025c7f58..e3b2bce0aff 100644
--- a/include/asm-x86/nops.h
+++ b/include/asm-x86/nops.h
@@ -3,17 +3,29 @@
/* Define nops for use with alternative() */
-/* generic versions from gas */
-#define GENERIC_NOP1 ".byte 0x90\n"
-#define GENERIC_NOP2 ".byte 0x89,0xf6\n"
-#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n"
-#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n"
-#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4
-#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n"
-#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n"
-#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7
+/* generic versions from gas
+ 1: nop
+ 2: movl %esi,%esi
+ 3: leal 0x00(%esi),%esi
+ 4: leal 0x00(,%esi,1),%esi
+ 6: leal 0x00000000(%esi),%esi
+ 7: leal 0x00000000(,%esi,1),%esi
+*/
+#define GENERIC_NOP1 ".byte 0x90\n"
+#define GENERIC_NOP2 ".byte 0x89,0xf6\n"
+#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n"
+#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n"
+#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4
+#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n"
+#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n"
+#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7
-/* Opteron 64bit nops */
+/* Opteron 64bit nops
+ 1: nop
+ 2: osp nop
+ 3: osp osp nop
+ 4: osp osp osp nop
+*/
#define K8_NOP1 GENERIC_NOP1
#define K8_NOP2 ".byte 0x66,0x90\n"
#define K8_NOP3 ".byte 0x66,0x66,0x90\n"
@@ -23,19 +35,35 @@
#define K8_NOP7 K8_NOP4 K8_NOP3
#define K8_NOP8 K8_NOP4 K8_NOP4
-/* K7 nops */
-/* uses eax dependencies (arbitary choice) */
-#define K7_NOP1 GENERIC_NOP1
+/* K7 nops
+ uses eax dependencies (arbitary choice)
+ 1: nop
+ 2: movl %eax,%eax
+ 3: leal (,%eax,1),%eax
+ 4: leal 0x00(,%eax,1),%eax
+ 6: leal 0x00000000(%eax),%eax
+ 7: leal 0x00000000(,%eax,1),%eax
+*/
+#define K7_NOP1 GENERIC_NOP1
#define K7_NOP2 ".byte 0x8b,0xc0\n"
#define K7_NOP3 ".byte 0x8d,0x04,0x20\n"
#define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n"
#define K7_NOP5 K7_NOP4 ASM_NOP1
#define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n"
-#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n"
-#define K7_NOP8 K7_NOP7 ASM_NOP1
+#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n"
+#define K7_NOP8 K7_NOP7 ASM_NOP1
-/* P6 nops */
-/* uses eax dependencies (Intel-recommended choice) */
+/* P6 nops
+ uses eax dependencies (Intel-recommended choice)
+ 1: nop
+ 2: osp nop
+ 3: nopl (%eax)
+ 4: nopl 0x00(%eax)
+ 5: nopl 0x00(%eax,%eax,1)
+ 6: osp nopl 0x00(%eax,%eax,1)
+ 7: nopl 0x00000000(%eax)
+ 8: nopl 0x00000000(%eax,%eax,1)
+*/
#define P6_NOP1 GENERIC_NOP1
#define P6_NOP2 ".byte 0x66,0x90\n"
#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n"
@@ -63,9 +91,7 @@
#define ASM_NOP6 K7_NOP6
#define ASM_NOP7 K7_NOP7
#define ASM_NOP8 K7_NOP8
-#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
- defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \
- defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)
+#elif defined(CONFIG_X86_P6_NOP)
#define ASM_NOP1 P6_NOP1
#define ASM_NOP2 P6_NOP2
#define ASM_NOP3 P6_NOP3
diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h
index f7393bc516e..143546073b9 100644
--- a/include/asm-x86/page_64.h
+++ b/include/asm-x86/page_64.h
@@ -47,8 +47,12 @@
#define __PHYSICAL_MASK_SHIFT 46
#define __VIRTUAL_MASK_SHIFT 48
-#define KERNEL_TEXT_SIZE (40*1024*1024)
-#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL)
+/*
+ * Kernel image size is limited to 128 MB (see level2_kernel_pgt in
+ * arch/x86/kernel/head_64.S), and it is mapped here:
+ */
+#define KERNEL_IMAGE_SIZE (128*1024*1024)
+#define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL)
#ifndef __ASSEMBLY__
void clear_page(void *page);
diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
index bd4740a60f2..0a0b77bc736 100644
--- a/include/asm-x86/pgtable_64.h
+++ b/include/asm-x86/pgtable_64.h
@@ -188,6 +188,7 @@ static inline unsigned long pmd_bad(pmd_t pmd)
#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
#define pgd_offset_k(address) (init_level4_pgt + pgd_index(address))
#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_PRESENT)
+static inline int pgd_large(pgd_t pgd) { return 0; }
#define mk_kernel_pgd(address) ((pgd_t){ (address) | _KERNPG_TABLE })
/* PUD - Level3 access */
@@ -246,6 +247,7 @@ static inline int pud_large(pud_t pte)
#define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val })
extern int kern_addr_valid(unsigned long addr);
+extern void cleanup_highmap(void);
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h
index 149920dcd34..45a2f0ab33d 100644
--- a/include/asm-x86/processor.h
+++ b/include/asm-x86/processor.h
@@ -302,10 +302,6 @@ union i387_union {
};
#ifdef CONFIG_X86_32
-/*
- * the following now lives in the per cpu area:
- * extern int cpu_llc_id[NR_CPUS];
- */
DECLARE_PER_CPU(u8, cpu_llc_id);
#else
DECLARE_PER_CPU(struct orig_ist, orig_ist);
@@ -671,7 +667,6 @@ extern void init_gdt(int cpu);
extern unsigned int machine_id;
extern unsigned int machine_submodel_id;
extern unsigned int BIOS_revision;
-extern unsigned int mca_pentium_flag;
/* Boot loader type from the setup header */
extern int bootloader_type;
diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h
index 81a8ee4c55f..f224eb3c315 100644
--- a/include/asm-x86/ptrace-abi.h
+++ b/include/asm-x86/ptrace-abi.h
@@ -89,13 +89,13 @@
*/
struct ptrace_bts_config {
/* requested or actual size of BTS buffer in bytes */
- u32 size;
+ __u32 size;
/* bitmask of below flags */
- u32 flags;
+ __u32 flags;
/* buffer overflow signal */
- u32 signal;
+ __u32 signal;
/* actual size of bts_struct in bytes */
- u32 bts_size;
+ __u32 bts_size;
};
#endif
diff --git a/include/asm-xtensa/cacheflush.h b/include/asm-xtensa/cacheflush.h
index b773c57e75a..94c4c53a099 100644
--- a/include/asm-xtensa/cacheflush.h
+++ b/include/asm-xtensa/cacheflush.h
@@ -70,6 +70,8 @@ extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long);
#endif
#if (ICACHE_WAY_SIZE > PAGE_SIZE)
extern void __invalidate_icache_page_alias(unsigned long, unsigned long);
+#else
+# define __invalidate_icache_page_alias(v,p) do { } while(0)
#endif
/*
diff --git a/include/asm-xtensa/coprocessor.h b/include/asm-xtensa/coprocessor.h
index aa212103455..1cbcf9001a4 100644
--- a/include/asm-xtensa/coprocessor.h
+++ b/include/asm-xtensa/coprocessor.h
@@ -5,81 +5,173 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2003 - 2005 Tensilica Inc.
+ * Copyright (C) 2003 - 2007 Tensilica Inc.
*/
+
#ifndef _XTENSA_COPROCESSOR_H
#define _XTENSA_COPROCESSOR_H
-#include <asm/variant/core.h>
+#include <linux/stringify.h>
#include <asm/variant/tie.h>
+#include <asm/types.h>
+
+#ifdef __ASSEMBLY__
+# include <asm/variant/tie-asm.h>
+
+.macro xchal_sa_start a b
+ .set .Lxchal_pofs_, 0
+ .set .Lxchal_ofs_, 0
+.endm
+
+.macro xchal_sa_align ptr minofs maxofs ofsalign totalign
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + .Lxchal_pofs_ + \totalign - 1
+ .set .Lxchal_ofs_, (.Lxchal_ofs_ & -\totalign) - .Lxchal_pofs_
+.endm
+
+#define _SELECT ( XTHAL_SAS_TIE | XTHAL_SAS_OPT \
+ | XTHAL_SAS_CC \
+ | XTHAL_SAS_CALR | XTHAL_SAS_CALE )
+
+.macro save_xtregs_opt ptr clb at1 at2 at3 at4 offset
+ .if XTREGS_OPT_SIZE > 0
+ addi \clb, \ptr, \offset
+ xchal_ncp_store \clb \at1 \at2 \at3 \at4 select=_SELECT
+ .endif
+.endm
+
+.macro load_xtregs_opt ptr clb at1 at2 at3 at4 offset
+ .if XTREGS_OPT_SIZE > 0
+ addi \clb, \ptr, \offset
+ xchal_ncp_load \clb \at1 \at2 \at3 \at4 select=_SELECT
+ .endif
+.endm
+#undef _SELECT
+
+#define _SELECT ( XTHAL_SAS_TIE | XTHAL_SAS_OPT \
+ | XTHAL_SAS_NOCC \
+ | XTHAL_SAS_CALR | XTHAL_SAS_CALE | XTHAL_SAS_GLOB )
+
+.macro save_xtregs_user ptr clb at1 at2 at3 at4 offset
+ .if XTREGS_USER_SIZE > 0
+ addi \clb, \ptr, \offset
+ xchal_ncp_store \clb \at1 \at2 \at3 \at4 select=_SELECT
+ .endif
+.endm
+
+.macro load_xtregs_user ptr clb at1 at2 at3 at4 offset
+ .if XTREGS_USER_SIZE > 0
+ addi \clb, \ptr, \offset
+ xchal_ncp_load \clb \at1 \at2 \at3 \at4 select=_SELECT
+ .endif
+.endm
+#undef _SELECT
+
+
+
+#endif /* __ASSEMBLY__ */
-#if !XCHAL_HAVE_CP
-
-#define XTENSA_CP_EXTRA_OFFSET 0
-#define XTENSA_CP_EXTRA_ALIGN 1 /* must be a power of 2 */
-#define XTENSA_CP_EXTRA_SIZE 0
-
-#else
-
-#define XTOFS(last_start,last_size,align) \
- ((last_start+last_size+align-1) & -align)
-
-#define XTENSA_CP_EXTRA_OFFSET 0
-#define XTENSA_CP_EXTRA_ALIGN XCHAL_EXTRA_SA_ALIGN
-
-#define XTENSA_CPE_CP0_OFFSET \
- XTOFS(XTENSA_CP_EXTRA_OFFSET, XCHAL_EXTRA_SA_SIZE, XCHAL_CP0_SA_ALIGN)
-#define XTENSA_CPE_CP1_OFFSET \
- XTOFS(XTENSA_CPE_CP0_OFFSET, XCHAL_CP0_SA_SIZE, XCHAL_CP1_SA_ALIGN)
-#define XTENSA_CPE_CP2_OFFSET \
- XTOFS(XTENSA_CPE_CP1_OFFSET, XCHAL_CP1_SA_SIZE, XCHAL_CP2_SA_ALIGN)
-#define XTENSA_CPE_CP3_OFFSET \
- XTOFS(XTENSA_CPE_CP2_OFFSET, XCHAL_CP2_SA_SIZE, XCHAL_CP3_SA_ALIGN)
-#define XTENSA_CPE_CP4_OFFSET \
- XTOFS(XTENSA_CPE_CP3_OFFSET, XCHAL_CP3_SA_SIZE, XCHAL_CP4_SA_ALIGN)
-#define XTENSA_CPE_CP5_OFFSET \
- XTOFS(XTENSA_CPE_CP4_OFFSET, XCHAL_CP4_SA_SIZE, XCHAL_CP5_SA_ALIGN)
-#define XTENSA_CPE_CP6_OFFSET \
- XTOFS(XTENSA_CPE_CP5_OFFSET, XCHAL_CP5_SA_SIZE, XCHAL_CP6_SA_ALIGN)
-#define XTENSA_CPE_CP7_OFFSET \
- XTOFS(XTENSA_CPE_CP6_OFFSET, XCHAL_CP6_SA_SIZE, XCHAL_CP7_SA_ALIGN)
-#define XTENSA_CP_EXTRA_SIZE \
- XTOFS(XTENSA_CPE_CP7_OFFSET, XCHAL_CP7_SA_SIZE, 16)
-
-#if XCHAL_CP_NUM > 0
-# ifndef __ASSEMBLY__
/*
- * Tasks that own contents of (last user) each coprocessor.
- * Entries are 0 for not-owned or non-existent coprocessors.
- * Note: The size of this structure is fixed to 8 bytes in entry.S
+ * XTENSA_HAVE_COPROCESSOR(x) returns 1 if coprocessor x is configured.
+ *
+ * XTENSA_HAVE_IO_PORT(x) returns 1 if io-port x is configured.
+ *
*/
-typedef struct {
- struct task_struct *owner; /* owner */
- int offset; /* offset in cpextra space. */
-} coprocessor_info_t;
-# else
-# define COPROCESSOR_INFO_OWNER 0
-# define COPROCESSOR_INFO_OFFSET 4
-# define COPROCESSOR_INFO_SIZE 8
-# endif
-#endif
-#endif /* XCHAL_HAVE_CP */
+#define XTENSA_HAVE_COPROCESSOR(x) \
+ ((XCHAL_CP_MASK ^ XCHAL_CP_PORT_MASK) & (1 << (x)))
+#define XTENSA_HAVE_COPROCESSORS \
+ (XCHAL_CP_MASK ^ XCHAL_CP_PORT_MASK)
+#define XTENSA_HAVE_IO_PORT(x) \
+ (XCHAL_CP_PORT_MASK & (1 << (x)))
+#define XTENSA_HAVE_IO_PORTS \
+ XCHAL_CP_PORT_MASK
#ifndef __ASSEMBLY__
-# if XCHAL_CP_NUM > 0
-struct task_struct;
-extern void release_coprocessors (struct task_struct*);
-extern void save_coprocessor_registers(void*, int);
-# else
-# define release_coprocessors(task)
-# endif
-typedef unsigned char cp_state_t[XTENSA_CP_EXTRA_SIZE]
- __attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN)));
-#endif /* !__ASSEMBLY__ */
+#if XCHAL_HAVE_CP
+
+#define RSR_CPENABLE(x) do { \
+ __asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
+ } while(0);
+#define WSR_CPENABLE(x) do { \
+ __asm__ __volatile__("wsr %0," __stringify(CPENABLE) "; rsync" \
+ :: "a" (x)); \
+ } while(0);
+#endif /* XCHAL_HAVE_CP */
+
+/*
+ * Additional registers.
+ * We define three types of additional registers:
+ * ext: extra registers that are used by the compiler
+ * cpn: optional registers that can be used by a user application
+ * cpX: coprocessor registers that can only be used if the corresponding
+ * CPENABLE bit is set.
+ */
+
+#define XCHAL_SA_REG(list,cc,abi,type,y,name,z,align,size,...) \
+ __REG ## list (cc, abi, type, name, size, align)
+
+#define __REG0(cc,abi,t,name,s,a) __REG0_ ## cc (abi,name)
+#define __REG1(cc,abi,t,name,s,a) __REG1_ ## cc (name)
+#define __REG2(cc,abi,type,...) __REG2_ ## type (__VA_ARGS__)
+
+#define __REG0_0(abi,name)
+#define __REG0_1(abi,name) __REG0_1 ## abi (name)
+#define __REG0_10(name) __u32 name;
+#define __REG0_11(name) __u32 name;
+#define __REG0_12(name)
+
+#define __REG1_0(name) __u32 name;
+#define __REG1_1(name)
+
+#define __REG2_0(n,s,a) __u32 name;
+#define __REG2_1(n,s,a) unsigned char n[s] __attribute__ ((aligned(a)));
+#define __REG2_2(n,s,a) unsigned char n[s] __attribute__ ((aligned(a)));
+
+typedef struct { XCHAL_NCP_SA_LIST(0) } xtregs_opt_t
+ __attribute__ ((aligned (XCHAL_NCP_SA_ALIGN)));
+typedef struct { XCHAL_NCP_SA_LIST(1) } xtregs_user_t
+ __attribute__ ((aligned (XCHAL_NCP_SA_ALIGN)));
+
+#if XTENSA_HAVE_COPROCESSORS
+
+typedef struct { XCHAL_CP0_SA_LIST(2) } xtregs_cp0_t
+ __attribute__ ((aligned (XCHAL_CP0_SA_ALIGN)));
+typedef struct { XCHAL_CP1_SA_LIST(2) } xtregs_cp1_t
+ __attribute__ ((aligned (XCHAL_CP1_SA_ALIGN)));
+typedef struct { XCHAL_CP2_SA_LIST(2) } xtregs_cp2_t
+ __attribute__ ((aligned (XCHAL_CP2_SA_ALIGN)));
+typedef struct { XCHAL_CP3_SA_LIST(2) } xtregs_cp3_t
+ __attribute__ ((aligned (XCHAL_CP3_SA_ALIGN)));
+typedef struct { XCHAL_CP4_SA_LIST(2) } xtregs_cp4_t
+ __attribute__ ((aligned (XCHAL_CP4_SA_ALIGN)));
+typedef struct { XCHAL_CP5_SA_LIST(2) } xtregs_cp5_t
+ __attribute__ ((aligned (XCHAL_CP5_SA_ALIGN)));
+typedef struct { XCHAL_CP6_SA_LIST(2) } xtregs_cp6_t
+ __attribute__ ((aligned (XCHAL_CP6_SA_ALIGN)));
+typedef struct { XCHAL_CP7_SA_LIST(2) } xtregs_cp7_t
+ __attribute__ ((aligned (XCHAL_CP7_SA_ALIGN)));
+
+extern struct thread_info* coprocessor_owner[XCHAL_CP_MAX];
+extern void coprocessor_save(void*, int);
+extern void coprocessor_load(void*, int);
+extern void coprocessor_flush(struct thread_info*, int);
+extern void coprocessor_restore(struct thread_info*, int);
+
+extern void coprocessor_release_all(struct thread_info*);
+extern void coprocessor_flush_all(struct thread_info*);
+
+static inline void coprocessor_clear_cpenable(void)
+{
+ unsigned long i = 0;
+ WSR_CPENABLE(i);
+}
+
+#endif /* XTENSA_HAVE_COPROCESSORS */
+
+#endif /* !__ASSEMBLY__ */
#endif /* _XTENSA_COPROCESSOR_H */
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
index 46738454250..ca6e5101a2c 100644
--- a/include/asm-xtensa/elf.h
+++ b/include/asm-xtensa/elf.h
@@ -72,115 +72,32 @@
/* ELF register definitions. This is needed for core dump support. */
-/*
- * elf_gregset_t contains the application-level state in the following order:
- * Processor info: config_version, cpuxy
- * Processor state: pc, ps, exccause, excvaddr, wb, ws,
- * lbeg, lend, lcount, sar
- * GP regs: ar0 - arXX
- */
-
typedef unsigned long elf_greg_t;
typedef struct {
- elf_greg_t xchal_config_id0;
- elf_greg_t xchal_config_id1;
- elf_greg_t cpux;
- elf_greg_t cpuy;
elf_greg_t pc;
elf_greg_t ps;
- elf_greg_t exccause;
- elf_greg_t excvaddr;
- elf_greg_t windowbase;
- elf_greg_t windowstart;
elf_greg_t lbeg;
elf_greg_t lend;
elf_greg_t lcount;
elf_greg_t sar;
- elf_greg_t syscall;
- elf_greg_t ar[64];
+ elf_greg_t windowstart;
+ elf_greg_t windowbase;
+ elf_greg_t reserved[8+48];
+ elf_greg_t a[64];
} xtensa_gregset_t;
#define ELF_NGREG (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-/*
- * Compute the size of the coprocessor and extra state layout (register info)
- * table (in bytes).
- * This is actually the maximum size of the table, as opposed to the size,
- * which is available from the _xtensa_reginfo_table_size global variable.
- *
- * (See also arch/xtensa/kernel/coprocessor.S)
- *
- */
-
-#ifndef XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM
-# define XTENSA_CPE_LTABLE_SIZE 0
-#else
-# define XTENSA_CPE_SEGMENT(num) (num ? (1+num) : 0)
-# define XTENSA_CPE_LTABLE_ENTRIES \
- ( XTENSA_CPE_SEGMENT(XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM) \
- + XTENSA_CPE_SEGMENT(XCHAL_CP0_SA_CONTENTS_LIBDB_NUM) \
- + XTENSA_CPE_SEGMENT(XCHAL_CP1_SA_CONTENTS_LIBDB_NUM) \
- + XTENSA_CPE_SEGMENT(XCHAL_CP2_SA_CONTENTS_LIBDB_NUM) \
- + XTENSA_CPE_SEGMENT(XCHAL_CP3_SA_CONTENTS_LIBDB_NUM) \
- + XTENSA_CPE_SEGMENT(XCHAL_CP4_SA_CONTENTS_LIBDB_NUM) \
- + XTENSA_CPE_SEGMENT(XCHAL_CP5_SA_CONTENTS_LIBDB_NUM) \
- + XTENSA_CPE_SEGMENT(XCHAL_CP6_SA_CONTENTS_LIBDB_NUM) \
- + XTENSA_CPE_SEGMENT(XCHAL_CP7_SA_CONTENTS_LIBDB_NUM) \
- + 1 /* final entry */ \
- )
-# define XTENSA_CPE_LTABLE_SIZE (XTENSA_CPE_LTABLE_ENTRIES * 8)
-#endif
-
-
-/*
- * Instantiations of the elf_fpregset_t type contain, in most
- * architectures, the floating point (FPU) register set.
- * For Xtensa, this type is extended to contain all custom state,
- * ie. coprocessor and "extra" (non-coprocessor) state (including,
- * for example, TIE-defined states and register files; as well
- * as other optional processor state).
- * This includes FPU state if a floating-point coprocessor happens
- * to have been configured within the Xtensa processor.
- *
- * TOTAL_FPREGS_SIZE is the required size (without rounding)
- * of elf_fpregset_t. It provides space for the following:
- *
- * a) 32-bit mask of active coprocessors for this task (similar
- * to CPENABLE in single-threaded Xtensa processor systems)
- *
- * b) table describing the layout of custom states (ie. of
- * individual registers, etc) within the save areas
- *
- * c) save areas for each coprocessor and for non-coprocessor
- * ("extra") state
- *
- * Note that save areas may require up to 16-byte alignment when
- * accessed by save/restore sequences. We do not need to ensure
- * such alignment in an elf_fpregset_t structure because custom
- * state is not directly loaded/stored into it; rather, save area
- * contents are copied to elf_fpregset_t from the active save areas
- * (see 'struct task_struct' definition in processor.h for that)
- * using memcpy(). But we do allow space for such alignment,
- * to allow optimizations of layout and copying.
- */
-#if 0
-#define TOTAL_FPREGS_SIZE \
- (4 + XTENSA_CPE_LTABLE_SIZE + XTENSA_CP_EXTRA_SIZE)
-#define ELF_NFPREG \
- ((TOTAL_FPREGS_SIZE + sizeof(elf_fpreg_t) - 1) / sizeof(elf_fpreg_t))
-#else
-#define TOTAL_FPREGS_SIZE 0
-#define ELF_NFPREG 0
-#endif
+#define ELF_NFPREG 18
typedef unsigned int elf_fpreg_t;
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_CORE_COPY_REGS(_eregs, _pregs) \
- xtensa_elf_core_copy_regs (&_eregs, _pregs);
+ xtensa_elf_core_copy_regs ((xtensa_gregset_t*)&(_eregs), _pregs);
extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
@@ -257,6 +174,21 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
_r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \
} while (0)
+typedef struct {
+ xtregs_opt_t opt;
+ xtregs_user_t user;
+#if XTENSA_HAVE_COPROCESSORS
+ xtregs_cp0_t cp0;
+ xtregs_cp1_t cp1;
+ xtregs_cp2_t cp2;
+ xtregs_cp3_t cp3;
+ xtregs_cp4_t cp4;
+ xtregs_cp5_t cp5;
+ xtregs_cp6_t cp6;
+ xtregs_cp7_t cp7;
+#endif
+} elf_xtregs_t;
+
#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
struct task_struct;
diff --git a/include/asm-xtensa/module.h b/include/asm-xtensa/module.h
index ffb25bfdf6a..d9b34bee4d4 100644
--- a/include/asm-xtensa/module.h
+++ b/include/asm-xtensa/module.h
@@ -15,9 +15,11 @@
struct mod_arch_specific
{
- /* Module support is not completely implemented. */
+ /* No special elements, yet. */
};
+#define MODULE_ARCH_VERMAGIC "xtensa-" __stringify(XCHAL_CORE_ID) " "
+
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
diff --git a/include/asm-xtensa/pgalloc.h b/include/asm-xtensa/pgalloc.h
index 8d1544eb461..4f4a7987ede 100644
--- a/include/asm-xtensa/pgalloc.h
+++ b/include/asm-xtensa/pgalloc.h
@@ -47,7 +47,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT);
}
-static inline pte_token_t pte_alloc_one(struct mm_struct *mm,
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
unsigned long addr)
{
struct page *page;
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
index c0fcc1c9660..c8b024a48b4 100644
--- a/include/asm-xtensa/pgtable.h
+++ b/include/asm-xtensa/pgtable.h
@@ -66,11 +66,9 @@
*/
#define VMALLOC_START 0xC0000000
-#define VMALLOC_END 0xC6FEFFFF
-#define TLBTEMP_BASE_1 0xC6FF0000
-#define TLBTEMP_BASE_2 0xC6FF8000
-#define MODULE_START 0xC7000000
-#define MODULE_END 0xC7FFFFFF
+#define VMALLOC_END 0xC7FEFFFF
+#define TLBTEMP_BASE_1 0xC7FF0000
+#define TLBTEMP_BASE_2 0xC7FF8000
/*
* Xtensa Linux config PTE layout (when present):
diff --git a/include/asm-xtensa/processor.h b/include/asm-xtensa/processor.h
index 96408f43662..4918a4e96d4 100644
--- a/include/asm-xtensa/processor.h
+++ b/include/asm-xtensa/processor.h
@@ -103,10 +103,6 @@ struct thread_struct {
unsigned long dbreaka[XCHAL_NUM_DBREAK];
unsigned long dbreakc[XCHAL_NUM_DBREAK];
- /* Allocate storage for extra state and coprocessor state. */
- unsigned char cp_save[XTENSA_CP_EXTRA_SIZE]
- __attribute__ ((aligned(XTENSA_CP_EXTRA_ALIGN)));
-
/* Make structure 16 bytes aligned. */
int align[0] __attribute__ ((aligned(16)));
};
@@ -162,21 +158,16 @@ struct thread_struct {
struct task_struct;
struct mm_struct;
-// FIXME: do we need release_thread for CP??
/* Free all resources held by a thread. */
#define release_thread(thread) do { } while(0)
-// FIXME: do we need prepare_to_copy (lazy status) for CP??
/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk) do { } while (0)
+extern void prepare_to_copy(struct task_struct*);
-/*
- * create a kernel thread without removing it from tasklists
- */
+/* Create a kernel thread without removing it from tasklists */
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/* Copy and release all segment info associated with a VM */
-
#define copy_segments(p, mm) do { } while(0)
#define release_segments(mm) do { } while(0)
#define forget_segments() do { } while (0)
diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h
index 77ff02d307b..422c73e2693 100644
--- a/include/asm-xtensa/ptrace.h
+++ b/include/asm-xtensa/ptrace.h
@@ -53,33 +53,30 @@
/* Registers used by strace */
-#define REG_A_BASE 0xfc000000
-#define REG_AR_BASE 0x04000000
-#define REG_PC 0x14000000
-#define REG_PS 0x080000e6
-#define REG_WB 0x08000048
-#define REG_WS 0x08000049
-#define REG_LBEG 0x08000000
-#define REG_LEND 0x08000001
-#define REG_LCOUNT 0x08000002
-#define REG_SAR 0x08000003
-#define REG_DEPC 0x080000c0
-#define REG_EXCCAUSE 0x080000e8
-#define REG_EXCVADDR 0x080000ee
-#define SYSCALL_NR 0x1
-
-#define AR_REGNO_TO_A_REGNO(ar, wb) (ar - wb*4) & ~(XCHAL_NUM_AREGS - 1)
+#define REG_A_BASE 0x0000
+#define REG_AR_BASE 0x0100
+#define REG_PC 0x0020
+#define REG_PS 0x02e6
+#define REG_WB 0x0248
+#define REG_WS 0x0249
+#define REG_LBEG 0x0200
+#define REG_LEND 0x0201
+#define REG_LCOUNT 0x0202
+#define REG_SAR 0x0203
+
+#define SYSCALL_NR 0x00ff
/* Other PTRACE_ values defined in <linux/ptrace.h> using values 0-9,16,17,24 */
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-#define PTRACE_GETFPREGSIZE 18
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETXTREGS 18
+#define PTRACE_SETXTREGS 19
#ifndef __ASSEMBLY__
+#ifdef __KERNEL__
+
/*
* This struct defines the way the registers are stored on the
* kernel stack during a system call or other kernel entry.
@@ -102,6 +99,9 @@ struct pt_regs {
unsigned long icountlevel; /* 60 */
int reserved[1]; /* 64 */
+ /* Additional configurable registers that are used by the compiler. */
+ xtregs_opt_t xtregs_opt;
+
/* Make sure the areg field is 16 bytes aligned. */
int align[0] __attribute__ ((aligned(16)));
@@ -111,8 +111,6 @@ struct pt_regs {
unsigned long areg[16]; /* 128 (64) */
};
-#ifdef __KERNEL__
-
#include <asm/variant/core.h>
# define task_pt_regs(tsk) ((struct pt_regs*) \
diff --git a/include/asm-xtensa/regs.h b/include/asm-xtensa/regs.h
index c913d259faa..d4baed24692 100644
--- a/include/asm-xtensa/regs.h
+++ b/include/asm-xtensa/regs.h
@@ -100,7 +100,14 @@
#define EXCCAUSE_DTLB_SIZE_RESTRICTION 27
#define EXCCAUSE_LOAD_CACHE_ATTRIBUTE 28
#define EXCCAUSE_STORE_CACHE_ATTRIBUTE 29
-#define EXCCAUSE_FLOATING_POINT 40
+#define EXCCAUSE_COPROCESSOR0_DISABLED 32
+#define EXCCAUSE_COPROCESSOR1_DISABLED 33
+#define EXCCAUSE_COPROCESSOR2_DISABLED 34
+#define EXCCAUSE_COPROCESSOR3_DISABLED 35
+#define EXCCAUSE_COPROCESSOR4_DISABLED 36
+#define EXCCAUSE_COPROCESSOR5_DISABLED 37
+#define EXCCAUSE_COPROCESSOR6_DISABLED 38
+#define EXCCAUSE_COPROCESSOR7_DISABLED 39
/* PS register fields. */
diff --git a/include/asm-xtensa/sigcontext.h b/include/asm-xtensa/sigcontext.h
index e3381cee505..03383af8c3b 100644
--- a/include/asm-xtensa/sigcontext.h
+++ b/include/asm-xtensa/sigcontext.h
@@ -13,9 +13,6 @@
struct sigcontext {
- unsigned long oldmask;
-
- /* CPU registers */
unsigned long sc_pc;
unsigned long sc_ps;
unsigned long sc_lbeg;
@@ -25,6 +22,7 @@ struct sigcontext {
unsigned long sc_acclo;
unsigned long sc_acchi;
unsigned long sc_a[16];
+ void *sc_xtregs;
};
#endif /* _XTENSA_SIGCONTEXT_H */
diff --git a/include/asm-xtensa/stat.h b/include/asm-xtensa/stat.h
index 149f4bce092..c4992038cee 100644
--- a/include/asm-xtensa/stat.h
+++ b/include/asm-xtensa/stat.h
@@ -5,25 +5,23 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2007 Tensilica Inc.
*/
#ifndef _XTENSA_STAT_H
#define _XTENSA_STAT_H
-#include <linux/types.h>
-
#define STAT_HAVE_NSEC 1
struct stat {
unsigned long st_dev;
- ino_t st_ino;
- mode_t st_mode;
- nlink_t st_nlink;
- uid_t st_uid;
- gid_t st_gid;
- unsigned int st_rdev;
- off_t st_size;
+ unsigned long st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+ unsigned int st_uid;
+ unsigned int st_gid;
+ unsigned long st_rdev;
+ long st_size;
unsigned long st_blksize;
unsigned long st_blocks;
unsigned long st_atime;
@@ -36,8 +34,6 @@ struct stat {
unsigned long __unused5;
};
-/* This matches struct stat64 in glibc-2.3 */
-
struct stat64 {
unsigned long long st_dev; /* Device */
unsigned long long st_ino; /* File serial number */
@@ -47,20 +43,14 @@ struct stat64 {
unsigned int st_gid; /* Group ID of the file's group. */
unsigned long long st_rdev; /* Device number, if device. */
long long st_size; /* Size of file, in bytes. */
- long st_blksize; /* Optimal block size for I/O. */
+ unsigned long st_blksize; /* Optimal block size for I/O. */
unsigned long __unused2;
-#ifdef __XTENSA_EB__
- unsigned long __unused3;
- long st_blocks; /* Number 512-byte blocks allocated. */
-#else
- long st_blocks; /* Number 512-byte blocks allocated. */
- unsigned long __unused3;
-#endif
- long st_atime; /* Time of last access. */
+ unsigned long long st_blocks; /* Number 512-byte blocks allocated. */
+ unsigned long st_atime; /* Time of last access. */
unsigned long st_atime_nsec;
- long st_mtime; /* Time of last modification. */
+ unsigned long st_mtime; /* Time of last modification. */
unsigned long st_mtime_nsec;
- long st_ctime; /* Time of last status change. */
+ unsigned long st_ctime; /* Time of last status change. */
unsigned long st_ctime_nsec;
unsigned long __unused4;
unsigned long __unused5;
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
index e0cb9116d8a..62b1e8f3c13 100644
--- a/include/asm-xtensa/system.h
+++ b/include/asm-xtensa/system.h
@@ -46,42 +46,6 @@ static inline int irqs_disabled(void)
return flags & 0xf;
}
-#define RSR_CPENABLE(x) do { \
- __asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
- } while(0);
-#define WSR_CPENABLE(x) do { \
- __asm__ __volatile__("wsr %0," __stringify(CPENABLE)";rsync" \
- :: "a" (x));} while(0);
-
-#define clear_cpenable() __clear_cpenable()
-
-static inline void __clear_cpenable(void)
-{
-#if XCHAL_HAVE_CP
- unsigned long i = 0;
- WSR_CPENABLE(i);
-#endif
-}
-
-static inline void enable_coprocessor(int i)
-{
-#if XCHAL_HAVE_CP
- int cp;
- RSR_CPENABLE(cp);
- cp |= 1 << i;
- WSR_CPENABLE(cp);
-#endif
-}
-
-static inline void disable_coprocessor(int i)
-{
-#if XCHAL_HAVE_CP
- int cp;
- RSR_CPENABLE(cp);
- cp &= ~(1 << i);
- WSR_CPENABLE(cp);
-#endif
-}
#define smp_read_barrier_depends() do { } while(0)
#define read_barrier_depends() do { } while(0)
@@ -111,7 +75,6 @@ extern void *_switch_to(void *last, void *next);
#define switch_to(prev,next,last) \
do { \
- clear_cpenable(); \
(last) = _switch_to(prev, next); \
} while(0)
@@ -244,7 +207,7 @@ static inline void spill_registers(void)
"wsr a13," __stringify(SAR) "\n\t"
"wsr a14," __stringify(PS) "\n\t"
:: "a" (&a0), "a" (&ps)
- : "a2", "a3", "a12", "a13", "a14", "a15", "memory");
+ : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory");
}
#define arch_align_stack(x) (x)
diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h
index 52c958285bc..a2c640682ed 100644
--- a/include/asm-xtensa/thread_info.h
+++ b/include/asm-xtensa/thread_info.h
@@ -27,6 +27,21 @@
#ifndef __ASSEMBLY__
+#if XTENSA_HAVE_COPROCESSORS
+
+typedef struct xtregs_coprocessor {
+ xtregs_cp0_t cp0;
+ xtregs_cp1_t cp1;
+ xtregs_cp2_t cp2;
+ xtregs_cp3_t cp3;
+ xtregs_cp4_t cp4;
+ xtregs_cp5_t cp5;
+ xtregs_cp6_t cp6;
+ xtregs_cp7_t cp7;
+} xtregs_coprocessor_t;
+
+#endif
+
struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
@@ -38,7 +53,13 @@ struct thread_info {
mm_segment_t addr_limit; /* thread address space */
struct restart_block restart_block;
+ unsigned long cpenable;
+ /* Allocate storage for extra user states and coprocessor states. */
+#if XTENSA_HAVE_COPROCESSORS
+ xtregs_coprocessor_t xtregs_cp;
+#endif
+ xtregs_user_t xtregs_user;
};
#else /* !__ASSEMBLY__ */
diff --git a/include/asm-xtensa/timex.h b/include/asm-xtensa/timex.h
index a5fca59fba9..b83a8181d44 100644
--- a/include/asm-xtensa/timex.h
+++ b/include/asm-xtensa/timex.h
@@ -63,10 +63,10 @@ extern cycles_t cacheflush_time;
* Register access.
*/
-#define WSR_CCOUNT(r) __asm__("wsr %0,"__stringify(CCOUNT) :: "a" (r))
-#define RSR_CCOUNT(r) __asm__("rsr %0,"__stringify(CCOUNT) : "=a" (r))
-#define WSR_CCOMPARE(x,r) __asm__("wsr %0,"__stringify(CCOMPARE)"+"__stringify(x) :: "a"(r))
-#define RSR_CCOMPARE(x,r) __asm__("rsr %0,"__stringify(CCOMPARE)"+"__stringify(x) : "=a"(r))
+#define WSR_CCOUNT(r) asm volatile ("wsr %0,"__stringify(CCOUNT) :: "a" (r))
+#define RSR_CCOUNT(r) asm volatile ("rsr %0,"__stringify(CCOUNT) : "=a" (r))
+#define WSR_CCOMPARE(x,r) asm volatile ("wsr %0,"__stringify(CCOMPARE)"+"__stringify(x) :: "a"(r))
+#define RSR_CCOMPARE(x,r) asm volatile ("rsr %0,"__stringify(CCOMPARE)"+"__stringify(x) : "=a"(r))
static inline unsigned long get_ccount (void)
{
diff --git a/include/asm-xtensa/uaccess.h b/include/asm-xtensa/uaccess.h
index d6352da05b1..b8528426ab1 100644
--- a/include/asm-xtensa/uaccess.h
+++ b/include/asm-xtensa/uaccess.h
@@ -26,6 +26,7 @@
#include <asm/current.h>
#include <asm/asm-offsets.h>
#include <asm/processor.h>
+#include <asm/types.h>
/*
* These assembly macros mirror the C macros that follow below. They
@@ -118,7 +119,7 @@
* <at> destroyed (actually, (TASK_SIZE + 1 - size))
*/
.macro user_ok aa, as, at, error
- movi \at, (TASK_SIZE+1)
+ movi \at, __XTENSA_UL_CONST(TASK_SIZE)
bgeu \as, \at, \error
sub \at, \at, \as
bgeu \aa, \at, \error
@@ -226,20 +227,21 @@ extern long __put_user_bad(void);
__pu_err; \
})
-#define __put_user_size(x,ptr,size,retval) \
-do { \
- retval = 0; \
- switch (size) { \
- case 1: __put_user_asm(x,ptr,retval,1,"s8i"); break; \
- case 2: __put_user_asm(x,ptr,retval,2,"s16i"); break; \
- case 4: __put_user_asm(x,ptr,retval,4,"s32i"); break; \
- case 8: { \
- __typeof__(*ptr) __v64 = x; \
- retval = __copy_to_user(ptr,&__v64,8); \
- break; \
- } \
- default: __put_user_bad(); \
- } \
+#define __put_user_size(x,ptr,size,retval) \
+do { \
+ int __cb; \
+ retval = 0; \
+ switch (size) { \
+ case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \
+ case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \
+ case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \
+ case 8: { \
+ __typeof__(*ptr) __v64 = x; \
+ retval = __copy_to_user(ptr,&__v64,8); \
+ break; \
+ } \
+ default: __put_user_bad(); \
+ } \
} while (0)
@@ -267,14 +269,14 @@ do { \
#define __check_align_1 ""
#define __check_align_2 \
- " _bbci.l %2, 0, 1f \n" \
- " movi %0, %3 \n" \
+ " _bbci.l %3, 0, 1f \n" \
+ " movi %0, %4 \n" \
" _j 2f \n"
#define __check_align_4 \
- " _bbsi.l %2, 0, 0f \n" \
- " _bbci.l %2, 1, 1f \n" \
- "0: movi %0, %3 \n" \
+ " _bbsi.l %3, 0, 0f \n" \
+ " _bbci.l %3, 1, 1f \n" \
+ "0: movi %0, %4 \n" \
" _j 2f \n"
@@ -286,24 +288,24 @@ do { \
* WARNING: If you modify this macro at all, verify that the
* __check_align_* macros still work.
*/
-#define __put_user_asm(x, addr, err, align, insn) \
- __asm__ __volatile__( \
- __check_align_##align \
- "1: "insn" %1, %2, 0 \n" \
- "2: \n" \
- " .section .fixup,\"ax\" \n" \
- " .align 4 \n" \
- "4: \n" \
- " .long 2b \n" \
- "5: \n" \
- " l32r %2, 4b \n" \
- " movi %0, %3 \n" \
- " jx %2 \n" \
- " .previous \n" \
- " .section __ex_table,\"a\" \n" \
- " .long 1b, 5b \n" \
- " .previous" \
- :"=r" (err) \
+#define __put_user_asm(x, addr, err, align, insn, cb) \
+ __asm__ __volatile__( \
+ __check_align_##align \
+ "1: "insn" %2, %3, 0 \n" \
+ "2: \n" \
+ " .section .fixup,\"ax\" \n" \
+ " .align 4 \n" \
+ "4: \n" \
+ " .long 2b \n" \
+ "5: \n" \
+ " l32r %1, 4b \n" \
+ " movi %0, %4 \n" \
+ " jx %1 \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " .long 1b, 5b \n" \
+ " .previous" \
+ :"=r" (err), "=r" (cb) \
:"r" ((int)(x)), "r" (addr), "i" (-EFAULT), "0" (err))
#define __get_user_nocheck(x,ptr,size) \
@@ -328,11 +330,12 @@ extern long __get_user_bad(void);
#define __get_user_size(x,ptr,size,retval) \
do { \
+ int __cb; \
retval = 0; \
switch (size) { \
- case 1: __get_user_asm(x,ptr,retval,1,"l8ui"); break; \
- case 2: __get_user_asm(x,ptr,retval,2,"l16ui"); break; \
- case 4: __get_user_asm(x,ptr,retval,4,"l32i"); break; \
+ case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \
+ case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \
+ case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \
case 8: retval = __copy_from_user(&x,ptr,8); break; \
default: (x) = __get_user_bad(); \
} \
@@ -343,25 +346,25 @@ do { \
* WARNING: If you modify this macro at all, verify that the
* __check_align_* macros still work.
*/
-#define __get_user_asm(x, addr, err, align, insn) \
+#define __get_user_asm(x, addr, err, align, insn, cb) \
__asm__ __volatile__( \
__check_align_##align \
- "1: "insn" %1, %2, 0 \n" \
+ "1: "insn" %2, %3, 0 \n" \
"2: \n" \
" .section .fixup,\"ax\" \n" \
" .align 4 \n" \
"4: \n" \
" .long 2b \n" \
"5: \n" \
- " l32r %2, 4b \n" \
- " movi %1, 0 \n" \
- " movi %0, %3 \n" \
- " jx %2 \n" \
+ " l32r %1, 4b \n" \
+ " movi %2, 0 \n" \
+ " movi %0, %4 \n" \
+ " jx %1 \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
" .long 1b, 5b \n" \
" .previous" \
- :"=r" (err), "=r" (x) \
+ :"=r" (err), "=r" (cb), "=r" (x) \
:"r" (addr), "i" (-EFAULT), "0" (err))
diff --git a/include/asm-xtensa/variant-fsf/tie-asm.h b/include/asm-xtensa/variant-fsf/tie-asm.h
new file mode 100644
index 00000000000..68a73bf4ffc
--- /dev/null
+++ b/include/asm-xtensa/variant-fsf/tie-asm.h
@@ -0,0 +1,70 @@
+/*
+ * This header file contains assembly-language definitions (assembly
+ * macros, etc.) for this specific Xtensa processor's TIE extensions
+ * and options. It is customized to this Xtensa processor configuration.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_ASM_H
+#define _XTENSA_CORE_TIE_ASM_H
+
+/* Selection parameter values for save-area save/restore macros: */
+/* Option vs. TIE: */
+#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */
+#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */
+/* Whether used automatically by compiler: */
+#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */
+#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */
+/* ABI handling across function calls: */
+#define XTHAL_SAS_CALR 0x0010 /* caller-saved */
+#define XTHAL_SAS_CALE 0x0020 /* callee-saved */
+#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */
+/* Misc */
+#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */
+
+
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered): ptr (1 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+ .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select
+ xchal_sa_align \ptr, 0, 1024-4, 4, 4
+ rur \at1, THREADPTR // threadptr option
+ s32i \at1, \ptr, .Lxchal_ofs_ + 0
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 4
+ .endif
+ .endm // xchal_ncp_store
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered): ptr (1 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+ .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select
+ xchal_sa_align \ptr, 0, 1024-4, 4, 4
+ l32i \at1, \ptr, .Lxchal_ofs_ + 0
+ wur \at1, THREADPTR // threadptr option
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 4
+ .endif
+ .endm // xchal_ncp_load
+
+
+
+#define XCHAL_NCP_NUM_ATMPS 1
+
+
+#define XCHAL_SA_NUM_ATMPS 1
+
+#endif /*_XTENSA_CORE_TIE_ASM_H*/
+
diff --git a/include/asm-xtensa/variant-fsf/tie.h b/include/asm-xtensa/variant-fsf/tie.h
index a73c7166491..bf4020116df 100644
--- a/include/asm-xtensa/variant-fsf/tie.h
+++ b/include/asm-xtensa/variant-fsf/tie.h
@@ -1,22 +1,77 @@
/*
- * Xtensa processor core configuration information.
+ * This header file describes this specific Xtensa processor's TIE extensions
+ * that extend basic Xtensa core functionality. It is customized to this
+ * Xtensa processor configuration.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1999-2006 Tensilica Inc.
+ * Copyright (C) 1999-2007 Tensilica Inc.
*/
-#ifndef XTENSA_TIE_H
-#define XTENSA_TIE_H
-
-/*----------------------------------------------------------------------
- COPROCESSORS and EXTRA STATE
- ----------------------------------------------------------------------*/
+#ifndef _XTENSA_CORE_TIE_H
+#define _XTENSA_CORE_TIE_H
#define XCHAL_CP_NUM 0 /* number of coprocessors */
-#define XCHAL_CP_MASK 0x00
+#define XCHAL_CP_MAX 0 /* max CP ID + 1 (0 if none) */
+#define XCHAL_CP_MASK 0x00 /* bitmask of all CPs by ID */
+#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */
+
+/* Basic parameters of each coprocessor: */
+#define XCHAL_CP7_NAME "XTIOP"
+#define XCHAL_CP7_IDENT XTIOP
+#define XCHAL_CP7_SA_SIZE 0 /* size of state save area */
+#define XCHAL_CP7_SA_ALIGN 1 /* min alignment of save area */
+#define XCHAL_CP_ID_XTIOP 7 /* coprocessor ID (0..7) */
+
+/* Filler info for unassigned coprocessors, to simplify arrays etc: */
+#define XCHAL_NCP_SA_SIZE 0
+#define XCHAL_NCP_SA_ALIGN 1
+#define XCHAL_CP0_SA_SIZE 0
+#define XCHAL_CP0_SA_ALIGN 1
+#define XCHAL_CP1_SA_SIZE 0
+#define XCHAL_CP1_SA_ALIGN 1
+#define XCHAL_CP2_SA_SIZE 0
+#define XCHAL_CP2_SA_ALIGN 1
+#define XCHAL_CP3_SA_SIZE 0
+#define XCHAL_CP3_SA_ALIGN 1
+#define XCHAL_CP4_SA_SIZE 0
+#define XCHAL_CP4_SA_ALIGN 1
+#define XCHAL_CP5_SA_SIZE 0
+#define XCHAL_CP5_SA_ALIGN 1
+#define XCHAL_CP6_SA_SIZE 0
+#define XCHAL_CP6_SA_ALIGN 1
+
+/* Save area for non-coprocessor optional and custom (TIE) state: */
+#define XCHAL_NCP_SA_SIZE 0
+#define XCHAL_NCP_SA_ALIGN 1
+
+/* Total save area for optional and custom state (NCP + CPn): */
+#define XCHAL_TOTAL_SA_SIZE 0 /* with 16-byte align padding */
+#define XCHAL_TOTAL_SA_ALIGN 1 /* actual minimum alignment */
+
+#define XCHAL_NCP_SA_NUM 0
+#define XCHAL_NCP_SA_LIST(s)
+#define XCHAL_CP0_SA_NUM 0
+#define XCHAL_CP0_SA_LIST(s)
+#define XCHAL_CP1_SA_NUM 0
+#define XCHAL_CP1_SA_LIST(s)
+#define XCHAL_CP2_SA_NUM 0
+#define XCHAL_CP2_SA_LIST(s)
+#define XCHAL_CP3_SA_NUM 0
+#define XCHAL_CP3_SA_LIST(s)
+#define XCHAL_CP4_SA_NUM 0
+#define XCHAL_CP4_SA_LIST(s)
+#define XCHAL_CP5_SA_NUM 0
+#define XCHAL_CP5_SA_LIST(s)
+#define XCHAL_CP6_SA_NUM 0
+#define XCHAL_CP6_SA_LIST(s)
+#define XCHAL_CP7_SA_NUM 0
+#define XCHAL_CP7_SA_LIST(s)
+
+/* Byte length of instruction from its first nibble (op0 field), per FLIX. */
+#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3
-#endif /*XTENSA_CONFIG_TIE_H*/
+#endif /*_XTENSA_CORE_TIE_H*/
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 5cae9b5960e..994df378000 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -61,6 +61,7 @@ header-y += efs_fs_sb.h
header-y += elf-fdpic.h
header-y += elf-em.h
header-y += fadvise.h
+header-y += falloc.h
header-y += fd.h
header-y += fdreg.h
header-y += fib_rules.h
@@ -70,7 +71,6 @@ header-y += fuse.h
header-y += genetlink.h
header-y += gen_stats.h
header-y += gigaset_dev.h
-header-y += hdsmart.h
header-y += hysdn_if.h
header-y += i2o-dev.h
header-y += i8k.h
@@ -211,6 +211,7 @@ unifdef-y += hayesesp.h
unifdef-y += hdlcdrv.h
unifdef-y += hdlc.h
unifdef-y += hdreg.h
+unifdef-y += hdsmart.h
unifdef-y += hiddev.h
unifdef-y += hpet.h
unifdef-y += i2c.h
diff --git a/include/linux/aio.h b/include/linux/aio.h
index a9931e2e562..0d0b7f629bd 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -105,7 +105,6 @@ struct kiocb {
wait_queue_t ki_wait;
loff_t ki_pos;
- atomic_t ki_bio_count; /* num bio used for this iocb */
void *private;
/* State that we remember to be able to restart/retry */
unsigned short ki_opcode;
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 78bbacaed8c..1c622e2b050 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -659,6 +659,11 @@ static inline int atapi_command_packet_set(const u16 *dev_id)
return (dev_id[0] >> 8) & 0x1f;
}
+static inline int atapi_id_dmadir(const u16 *dev_id)
+{
+ return ata_id_major_version(dev_id) >= 7 && (dev_id[62] & 0x8000);
+}
+
static inline int is_multi_taskfile(struct ata_taskfile *tf)
{
return (tf->command == ATA_CMD_READ_MULTI) ||
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 4da441337d6..4c59bdccd3e 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -326,7 +326,6 @@ extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
gfp_t);
extern void bio_set_pages_dirty(struct bio *bio);
extern void bio_check_pages_dirty(struct bio *bio);
-extern void bio_release_pages(struct bio *bio);
extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int);
extern int bio_uncopy_user(struct bio *);
void zero_fill_bio(struct bio *bio);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e1888cc5b8a..6f79d40dd3c 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -217,6 +217,7 @@ struct request {
unsigned char cmd[BLK_MAX_CDB];
unsigned int data_len;
+ unsigned int extra_len; /* length of alignment and padding */
unsigned int sense_len;
void *data;
void *sense;
@@ -258,6 +259,7 @@ struct bio_vec;
typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *);
typedef void (prepare_flush_fn) (struct request_queue *, struct request *);
typedef void (softirq_done_fn)(struct request *);
+typedef int (dma_drain_needed_fn)(struct request *);
enum blk_queue_state {
Queue_down,
@@ -294,6 +296,7 @@ struct request_queue
merge_bvec_fn *merge_bvec_fn;
prepare_flush_fn *prepare_flush_fn;
softirq_done_fn *softirq_done_fn;
+ dma_drain_needed_fn *dma_drain_needed;
/*
* Dispatch queue sorting
@@ -359,6 +362,7 @@ struct request_queue
unsigned long seg_boundary_mask;
void *dma_drain_buffer;
unsigned int dma_drain_size;
+ unsigned int dma_pad_mask;
unsigned int dma_alignment;
struct blk_queue_tag *queue_tags;
@@ -698,8 +702,10 @@ extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
extern void blk_queue_hardsect_size(struct request_queue *, unsigned short);
extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b);
-extern int blk_queue_dma_drain(struct request_queue *q, void *buf,
- unsigned int size);
+extern void blk_queue_dma_pad(struct request_queue *, unsigned int);
+extern int blk_queue_dma_drain(struct request_queue *q,
+ dma_drain_needed_fn *dma_drain_needed,
+ void *buf, unsigned int size);
extern void blk_queue_segment_boundary(struct request_queue *, unsigned long);
extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn);
extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *);
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index ff9055fc3d2..028ba3b523b 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -175,7 +175,7 @@ struct css_set {
*
*
* When reading/writing to a file:
- * - the cgroup to use in file->f_dentry->d_parent->d_fsdata
+ * - the cgroup to use is file->f_dentry->d_parent->d_fsdata
* - the 'cftype' of the file is file->f_dentry->d_fsdata
*/
@@ -186,15 +186,15 @@ struct cftype {
char name[MAX_CFTYPE_NAME];
int private;
int (*open) (struct inode *inode, struct file *file);
- ssize_t (*read) (struct cgroup *cont, struct cftype *cft,
+ ssize_t (*read) (struct cgroup *cgrp, struct cftype *cft,
struct file *file,
char __user *buf, size_t nbytes, loff_t *ppos);
/*
* read_uint() is a shortcut for the common case of returning a
* single integer. Use it in place of read()
*/
- u64 (*read_uint) (struct cgroup *cont, struct cftype *cft);
- ssize_t (*write) (struct cgroup *cont, struct cftype *cft,
+ u64 (*read_uint) (struct cgroup *cgrp, struct cftype *cft);
+ ssize_t (*write) (struct cgroup *cgrp, struct cftype *cft,
struct file *file,
const char __user *buf, size_t nbytes, loff_t *ppos);
@@ -203,7 +203,7 @@ struct cftype {
* a single integer (as parsed by simple_strtoull) from
* userspace. Use in place of write(); return 0 or error.
*/
- int (*write_uint) (struct cgroup *cont, struct cftype *cft, u64 val);
+ int (*write_uint) (struct cgroup *cgrp, struct cftype *cft, u64 val);
int (*release) (struct inode *inode, struct file *file);
};
@@ -218,41 +218,41 @@ struct cgroup_scanner {
/* Add a new file to the given cgroup directory. Should only be
* called by subsystems from within a populate() method */
-int cgroup_add_file(struct cgroup *cont, struct cgroup_subsys *subsys,
+int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
const struct cftype *cft);
/* Add a set of new files to the given cgroup directory. Should
* only be called by subsystems from within a populate() method */
-int cgroup_add_files(struct cgroup *cont,
+int cgroup_add_files(struct cgroup *cgrp,
struct cgroup_subsys *subsys,
const struct cftype cft[],
int count);
-int cgroup_is_removed(const struct cgroup *cont);
+int cgroup_is_removed(const struct cgroup *cgrp);
-int cgroup_path(const struct cgroup *cont, char *buf, int buflen);
+int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen);
-int cgroup_task_count(const struct cgroup *cont);
+int cgroup_task_count(const struct cgroup *cgrp);
/* Return true if the cgroup is a descendant of the current cgroup */
-int cgroup_is_descendant(const struct cgroup *cont);
+int cgroup_is_descendant(const struct cgroup *cgrp);
/* Control Group subsystem type. See Documentation/cgroups.txt for details */
struct cgroup_subsys {
struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss,
- struct cgroup *cont);
- void (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cont);
- void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cont);
+ struct cgroup *cgrp);
+ void (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
+ void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
int (*can_attach)(struct cgroup_subsys *ss,
- struct cgroup *cont, struct task_struct *tsk);
- void (*attach)(struct cgroup_subsys *ss, struct cgroup *cont,
- struct cgroup *old_cont, struct task_struct *tsk);
+ struct cgroup *cgrp, struct task_struct *tsk);
+ void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
+ struct cgroup *old_cgrp, struct task_struct *tsk);
void (*fork)(struct cgroup_subsys *ss, struct task_struct *task);
void (*exit)(struct cgroup_subsys *ss, struct task_struct *task);
int (*populate)(struct cgroup_subsys *ss,
- struct cgroup *cont);
- void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cont);
+ struct cgroup *cgrp);
+ void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp);
void (*bind)(struct cgroup_subsys *ss, struct cgroup *root);
int subsys_id;
int active;
@@ -273,9 +273,9 @@ struct cgroup_subsys {
#undef SUBSYS
static inline struct cgroup_subsys_state *cgroup_subsys_state(
- struct cgroup *cont, int subsys_id)
+ struct cgroup *cgrp, int subsys_id)
{
- return cont->subsys[subsys_id];
+ return cgrp->subsys[subsys_id];
}
static inline struct cgroup_subsys_state *task_subsys_state(
@@ -290,8 +290,6 @@ static inline struct cgroup* task_cgroup(struct task_struct *task,
return task_subsys_state(task, subsys_id)->cgroup;
}
-int cgroup_path(const struct cgroup *cont, char *buf, int buflen);
-
int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *ss);
/* A cgroup_iter should be treated as an opaque object */
@@ -313,10 +311,10 @@ struct cgroup_iter {
* - cgroup_scan_tasks() holds the css_set_lock when calling the test_task()
* callback, but not while calling the process_task() callback.
*/
-void cgroup_iter_start(struct cgroup *cont, struct cgroup_iter *it);
-struct task_struct *cgroup_iter_next(struct cgroup *cont,
+void cgroup_iter_start(struct cgroup *cgrp, struct cgroup_iter *it);
+struct task_struct *cgroup_iter_next(struct cgroup *cgrp,
struct cgroup_iter *it);
-void cgroup_iter_end(struct cgroup *cont, struct cgroup_iter *it);
+void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it);
int cgroup_scan_tasks(struct cgroup_scanner *scan);
int cgroup_attach_task(struct cgroup *, struct task_struct *);
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index ac6aad98b60..1ddebfc5256 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -37,7 +37,7 @@ SUBSYS(cpuacct)
/* */
-#ifdef CONFIG_CGROUP_MEM_CONT
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
SUBSYS(mem_cgroup)
#endif
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index d0e17e1657d..dcae0c8d97e 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -138,6 +138,12 @@ extern void __chk_io_ptr(const volatile void __iomem *);
#define noinline
#endif
+/*
+ * Rather then using noinline to prevent stack consumption, use
+ * noinline_for_stack instead. For documentaiton reasons.
+ */
+#define noinline_for_stack noinline
+
#ifndef __always_inline
#define __always_inline inline
#endif
diff --git a/include/linux/connector.h b/include/linux/connector.h
index da6dd957f90..96a89d3d672 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -170,7 +170,5 @@ int cn_cb_equal(struct cb_id *, struct cb_id *);
void cn_queue_wrapper(struct work_struct *work);
-extern int cn_already_initialized;
-
#endif /* __KERNEL__ */
#endif /* __CONNECTOR_H */
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index f592d6de3b9..7266124361b 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -27,6 +27,11 @@ struct debugfs_blob_wrapper {
};
#if defined(CONFIG_DEBUG_FS)
+
+/* declared over in file.c */
+extern const struct file_operations debugfs_file_operations;
+extern const struct inode_operations debugfs_link_operations;
+
struct dentry *debugfs_create_file(const char *name, mode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);
diff --git a/include/linux/delay.h b/include/linux/delay.h
index 17ddb55430a..54552d21296 100644
--- a/include/linux/delay.h
+++ b/include/linux/delay.h
@@ -7,6 +7,8 @@
* Delay routines, using a pre-computed "loops_per_jiffy" value.
*/
+#include <linux/kernel.h>
+
extern unsigned long loops_per_jiffy;
#include <asm/delay.h>
@@ -32,7 +34,11 @@ extern unsigned long loops_per_jiffy;
#endif
#ifndef ndelay
-#define ndelay(x) udelay(((x)+999)/1000)
+static inline void ndelay(unsigned long x)
+{
+ udelay(DIV_ROUND_UP(x, 1000));
+}
+#define ndelay(x) ndelay(x)
#endif
void calibrate_delay(void);
diff --git a/include/linux/dm9000.h b/include/linux/dm9000.h
index 0008e2ad0c9..a3750462f9e 100644
--- a/include/linux/dm9000.h
+++ b/include/linux/dm9000.h
@@ -19,6 +19,8 @@
#define DM9000_PLATF_8BITONLY (0x0001)
#define DM9000_PLATF_16BITONLY (0x0002)
#define DM9000_PLATF_32BITONLY (0x0004)
+#define DM9000_PLATF_EXT_PHY (0x0008)
+#define DM9000_PLATF_NO_EEPROM (0x0010)
/* platfrom data for platfrom device structure's platfrom_data field */
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index acbb364674f..261e43a4c87 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -366,7 +366,7 @@ __dma_has_cap(enum dma_transaction_type tx_type, dma_cap_mask_t *srcp)
*/
static inline void dma_async_issue_pending(struct dma_chan *chan)
{
- return chan->device->device_issue_pending(chan);
+ chan->device->device_issue_pending(chan);
}
#define dma_async_memcpy_issue_pending(chan) dma_async_issue_pending(chan)
diff --git a/include/linux/efs_dir.h b/include/linux/efs_dir.h
deleted file mode 100644
index a09ec010569..00000000000
--- a/include/linux/efs_dir.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * efs_dir.h
- *
- * Copyright (c) 1999 Al Smith
- */
-
-#ifndef __EFS_DIR_H__
-#define __EFS_DIR_H__
-
-#define EFS_DIRBSIZE_BITS EFS_BLOCKSIZE_BITS
-#define EFS_DIRBSIZE (1 << EFS_DIRBSIZE_BITS)
-
-struct efs_dentry {
- __be32 inode;
- unsigned char namelen;
- char name[3];
-};
-
-#define EFS_DENTSIZE (sizeof(struct efs_dentry) - 3 + 1)
-#define EFS_MAXNAMELEN ((1 << (sizeof(char) * 8)) - 1)
-
-#define EFS_DIRBLK_HEADERSIZE 4
-#define EFS_DIRBLK_MAGIC 0xbeef /* moo */
-
-struct efs_dir {
- __be16 magic;
- unsigned char firstused;
- unsigned char slots;
-
- unsigned char space[EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE];
-};
-
-#define EFS_MAXENTS \
- ((EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE) / \
- (EFS_DENTSIZE + sizeof(char)))
-
-#define EFS_SLOTAT(dir, slot) EFS_REALOFF((dir)->space[slot])
-
-#define EFS_REALOFF(offset) ((offset << 1))
-
-#endif /* __EFS_DIR_H__ */
-
diff --git a/include/linux/efs_fs.h b/include/linux/efs_fs.h
deleted file mode 100644
index a695d63a07a..00000000000
--- a/include/linux/efs_fs.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * efs_fs.h
- *
- * Copyright (c) 1999 Al Smith
- *
- * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
- */
-
-#ifndef __EFS_FS_H__
-#define __EFS_FS_H__
-
-#define EFS_VERSION "1.0a"
-
-static const char cprt[] = "EFS: "EFS_VERSION" - (c) 1999 Al Smith <Al.Smith@aeschi.ch.eu.org>";
-
-#include <asm/uaccess.h>
-
-/* 1 block is 512 bytes */
-#define EFS_BLOCKSIZE_BITS 9
-#define EFS_BLOCKSIZE (1 << EFS_BLOCKSIZE_BITS)
-
-#include <linux/fs.h>
-#include <linux/efs_fs_i.h>
-#include <linux/efs_fs_sb.h>
-#include <linux/efs_dir.h>
-
-static inline struct efs_inode_info *INODE_INFO(struct inode *inode)
-{
- return container_of(inode, struct efs_inode_info, vfs_inode);
-}
-
-static inline struct efs_sb_info *SUPER_INFO(struct super_block *sb)
-{
- return sb->s_fs_info;
-}
-
-struct statfs;
-struct fid;
-
-extern const struct inode_operations efs_dir_inode_operations;
-extern const struct file_operations efs_dir_operations;
-extern const struct address_space_operations efs_symlink_aops;
-
-extern struct inode *efs_iget(struct super_block *, unsigned long);
-extern efs_block_t efs_map_block(struct inode *, efs_block_t);
-extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
-
-extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *);
-extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
- int fh_len, int fh_type);
-extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
- int fh_len, int fh_type);
-extern struct dentry *efs_get_parent(struct dentry *);
-extern int efs_bmap(struct inode *, int);
-
-#endif /* __EFS_FS_H__ */
diff --git a/include/linux/efs_fs_i.h b/include/linux/efs_fs_i.h
deleted file mode 100644
index 617c474ca65..00000000000
--- a/include/linux/efs_fs_i.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * efs_fs_i.h
- *
- * Copyright (c) 1999 Al Smith
- *
- * Portions derived from IRIX header files (c) 1988 Silicon Graphics
- */
-
-#ifndef __EFS_FS_I_H__
-#define __EFS_FS_I_H__
-
-typedef int32_t efs_block_t;
-typedef uint32_t efs_ino_t;
-
-#define EFS_DIRECTEXTENTS 12
-
-/*
- * layout of an extent, in memory and on disk. 8 bytes exactly.
- */
-typedef union extent_u {
- unsigned char raw[8];
- struct extent_s {
- unsigned int ex_magic:8; /* magic # (zero) */
- unsigned int ex_bn:24; /* basic block */
- unsigned int ex_length:8; /* numblocks in this extent */
- unsigned int ex_offset:24; /* logical offset into file */
- } cooked;
-} efs_extent;
-
-typedef struct edevs {
- __be16 odev;
- __be32 ndev;
-} efs_devs;
-
-/*
- * extent based filesystem inode as it appears on disk. The efs inode
- * is exactly 128 bytes long.
- */
-struct efs_dinode {
- __be16 di_mode; /* mode and type of file */
- __be16 di_nlink; /* number of links to file */
- __be16 di_uid; /* owner's user id */
- __be16 di_gid; /* owner's group id */
- __be32 di_size; /* number of bytes in file */
- __be32 di_atime; /* time last accessed */
- __be32 di_mtime; /* time last modified */
- __be32 di_ctime; /* time created */
- __be32 di_gen; /* generation number */
- __be16 di_numextents; /* # of extents */
- u_char di_version; /* version of inode */
- u_char di_spare; /* spare - used by AFS */
- union di_addr {
- efs_extent di_extents[EFS_DIRECTEXTENTS];
- efs_devs di_dev; /* device for IFCHR/IFBLK */
- } di_u;
-};
-
-/* efs inode storage in memory */
-struct efs_inode_info {
- int numextents;
- int lastextent;
-
- efs_extent extents[EFS_DIRECTEXTENTS];
- struct inode vfs_inode;
-};
-
-#endif /* __EFS_FS_I_H__ */
-
diff --git a/include/linux/elfcore-compat.h b/include/linux/elfcore-compat.h
index 532d13adabc..0a90e1c3a42 100644
--- a/include/linux/elfcore-compat.h
+++ b/include/linux/elfcore-compat.h
@@ -45,8 +45,8 @@ struct compat_elf_prpsinfo
char pr_zomb;
char pr_nice;
compat_ulong_t pr_flag;
- compat_uid_t pr_uid;
- compat_gid_t pr_gid;
+ __compat_uid_t pr_uid;
+ __compat_gid_t pr_gid;
compat_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
char pr_fname[16];
char pr_psargs[ELF_PRARGSZ];
diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h
index 697da4bce6c..1285c583b2d 100644
--- a/include/linux/ext4_fs_extents.h
+++ b/include/linux/ext4_fs_extents.h
@@ -227,5 +227,6 @@ extern int ext4_ext_search_left(struct inode *, struct ext4_ext_path *,
ext4_lblk_t *, ext4_fsblk_t *);
extern int ext4_ext_search_right(struct inode *, struct ext4_ext_path *,
ext4_lblk_t *, ext4_fsblk_t *);
+extern void ext4_ext_drop_refs(struct ext4_ext_path *);
#endif /* _LINUX_EXT4_EXTENTS */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 98ffb6ead43..b84b848431f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1590,7 +1590,6 @@ extern void bd_set_size(struct block_device *, loff_t size);
extern void bd_forget(struct inode *inode);
extern void bdput(struct block_device *);
extern struct block_device *open_by_devnum(dev_t, unsigned);
-extern const struct address_space_operations def_blk_aops;
#else
static inline void bd_forget(struct inode *inode) {}
#endif
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 90048fb28a3..586ab56a3ec 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -167,6 +167,7 @@ union futex_key {
#ifdef CONFIG_FUTEX
extern void exit_robust_list(struct task_struct *curr);
extern void exit_pi_state_list(struct task_struct *curr);
+extern int futex_cmpxchg_enabled;
#else
static inline void exit_robust_list(struct task_struct *curr)
{
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 09a3b18918c..32c2ac49a07 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -18,11 +18,13 @@
#define dev_to_disk(device) container_of(device, struct gendisk, dev)
#define dev_to_part(device) container_of(device, struct hd_struct, dev)
-extern struct device_type disk_type;
extern struct device_type part_type;
extern struct kobject *block_depr;
extern struct class block_class;
+extern const struct seq_operations partitions_op;
+extern const struct seq_operations diskstats_op;
+
enum {
/* These three have identical behaviour; use the second one if DOS FDISK gets
confused about extended/logical partitions starting past cylinder 1023. */
@@ -556,7 +558,6 @@ extern struct gendisk *alloc_disk_node(int minors, int node_id);
extern struct gendisk *alloc_disk(int minors);
extern struct kobject *get_disk(struct gendisk *disk);
extern void put_disk(struct gendisk *disk);
-extern void genhd_media_change_notify(struct gendisk *disk);
extern void blk_register_region(dev_t devt, unsigned long range,
struct module *module,
struct kobject *(*probe)(dev_t, int *, void *),
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
new file mode 100644
index 00000000000..4987a84078e
--- /dev/null
+++ b/include/linux/gpio.h
@@ -0,0 +1,95 @@
+#ifndef __LINUX_GPIO_H
+#define __LINUX_GPIO_H
+
+/* see Documentation/gpio.txt */
+
+#ifdef CONFIG_GENERIC_GPIO
+#include <asm/gpio.h>
+
+#else
+
+/*
+ * Some platforms don't support the GPIO programming interface.
+ *
+ * In case some driver uses it anyway (it should normally have
+ * depended on GENERIC_GPIO), these routines help the compiler
+ * optimize out much GPIO-related code ... or trigger a runtime
+ * warning when something is wrongly called.
+ */
+
+static inline int gpio_is_valid(int number)
+{
+ return 0;
+}
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+ return -ENOSYS;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+ /* GPIO can never have been requested */
+ WARN_ON(1);
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+ return -ENOSYS;
+}
+
+static inline int gpio_direction_output(unsigned gpio, int value)
+{
+ return -ENOSYS;
+}
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ /* GPIO can never have been requested or set as {in,out}put */
+ WARN_ON(1);
+ return 0;
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ /* GPIO can never have been requested or set as output */
+ WARN_ON(1);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ /* GPIO can never have been requested or set as {in,out}put */
+ WARN_ON(1);
+ return 0;
+}
+
+static inline int gpio_get_value_cansleep(unsigned gpio)
+{
+ /* GPIO can never have been requested or set as {in,out}put */
+ WARN_ON(1);
+ return 0;
+}
+
+static inline void gpio_set_value_cansleep(unsigned gpio, int value)
+{
+ /* GPIO can never have been requested or set as output */
+ WARN_ON(1);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ /* GPIO can never have been requested or set as input */
+ WARN_ON(1);
+ return -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+ /* irq can never have been returned from gpio_to_irq() */
+ WARN_ON(1);
+ return -EINVAL;
+}
+
+#endif
+
+#endif /* __LINUX_GPIO_H */
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 2961ec78804..49829988bfa 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -109,6 +109,14 @@ static inline void account_system_vtime(struct task_struct *tsk)
}
#endif
+#if defined(CONFIG_PREEMPT_RCU) && defined(CONFIG_NO_HZ)
+extern void rcu_irq_enter(void);
+extern void rcu_irq_exit(void);
+#else
+# define rcu_irq_enter() do { } while (0)
+# define rcu_irq_exit() do { } while (0)
+#endif /* CONFIG_PREEMPT_RCU */
+
/*
* It is safe to do non-atomic ops on ->hardirq_context,
* because NMI handlers may not preempt and the ops are
@@ -117,6 +125,7 @@ static inline void account_system_vtime(struct task_struct *tsk)
*/
#define __irq_enter() \
do { \
+ rcu_irq_enter(); \
account_system_vtime(current); \
add_preempt_count(HARDIRQ_OFFSET); \
trace_hardirq_enter(); \
@@ -135,6 +144,7 @@ extern void irq_enter(void);
trace_hardirq_exit(); \
account_system_vtime(current); \
sub_preempt_count(HARDIRQ_OFFSET); \
+ rcu_irq_exit(); \
} while (0)
/*
diff --git a/include/linux/hdsmart.h b/include/linux/hdsmart.h
index e69192159d4..4f4faf9d423 100644
--- a/include/linux/hdsmart.h
+++ b/include/linux/hdsmart.h
@@ -17,7 +17,7 @@
#ifndef _LINUX_HDSMART_H
#define _LINUX_HDSMART_H
-#ifndef __KERNEL
+#ifndef __KERNEL__
#define OFFLINE_FULL_SCAN 0
#define SHORT_SELF_TEST 1
#define EXTEND_SELF_TEST 2
@@ -121,6 +121,6 @@ typedef struct ata_smart_selftestlog_s {
unsigned char resevered[2];
unsigned char chksum;
} __attribute__ ((packed)) ata_smart_selftestlog_t;
-#endif /* __KERNEL__ *
+#endif /* __KERNEL__ */
#endif /* _LINUX_HDSMART_H */
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 76014f8f3c6..365e0df3646 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -271,9 +271,16 @@ extern void i2c_unregister_device(struct i2c_client *);
* This is done at arch_initcall time, before declaring any i2c adapters.
* Modules for add-on boards must use other calls.
*/
+#ifdef CONFIG_I2C_BOARDINFO
extern int
i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n);
-
+#else
+static inline int
+i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n)
+{
+ return 0;
+}
+#endif
/*
* The following structs are for those who like to implement new bus drivers:
@@ -598,7 +605,7 @@ I2C_CLIENT_MODULE_PARM(probe, "List of adapter,address pairs to scan " \
"additionally"); \
I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to " \
"scan"); \
-const static struct i2c_client_address_data addr_data = { \
+static const struct i2c_client_address_data addr_data = { \
.normal_i2c = normal_i2c, \
.probe = probe, \
.ignore = ignore, \
diff --git a/include/linux/init.h b/include/linux/init.h
index a404a0055dd..fb58c0493cf 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -42,6 +42,7 @@
discard it in modules) */
#define __init __section(.init.text) __cold
#define __initdata __section(.init.data)
+#define __initconst __section(.init.rodata)
#define __exitdata __section(.exit.data)
#define __exit_call __used __section(.exitcall.exit)
@@ -106,6 +107,7 @@
#define __memexitconst __section(.memexit.rodata)
/* For assembly routines */
+#define __HEAD .section ".head.text","ax"
#define __INIT .section ".init.text","ax"
#define __FINIT .previous
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
index 593b222d9dc..1b4ccf25b4d 100644
--- a/include/linux/iocontext.h
+++ b/include/linux/iocontext.h
@@ -50,6 +50,7 @@ struct cfq_io_context {
sector_t seek_mean;
struct list_head queue_list;
+ struct hlist_node cic_list;
void (*dtor)(struct io_context *); /* destructor */
void (*exit)(struct io_context *); /* called on task exit */
@@ -77,6 +78,7 @@ struct io_context {
struct as_io_context *aic;
struct radix_tree_root radix_root;
+ struct hlist_head cic_list;
void *ioc_data;
};
diff --git a/include/linux/iommu-helper.h b/include/linux/iommu-helper.h
index 4dd4c04ff2f..c975caf7538 100644
--- a/include/linux/iommu-helper.h
+++ b/include/linux/iommu-helper.h
@@ -1,3 +1,6 @@
+extern int iommu_is_span_boundary(unsigned int index, unsigned int nr,
+ unsigned long shift,
+ unsigned long boundary_size);
extern unsigned long iommu_area_alloc(unsigned long *map, unsigned long size,
unsigned long start, unsigned int nr,
unsigned long shift,
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 4a6ce82ba03..0f28486f636 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -125,11 +125,11 @@ struct jprobe {
DECLARE_PER_CPU(struct kprobe *, current_kprobe);
DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
-#ifdef ARCH_SUPPORTS_KRETPROBES
+#ifdef CONFIG_KRETPROBES
extern void arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs);
extern int arch_trampoline_kprobe(struct kprobe *p);
-#else /* ARCH_SUPPORTS_KRETPROBES */
+#else /* CONFIG_KRETPROBES */
static inline void arch_prepare_kretprobe(struct kretprobe *rp,
struct pt_regs *regs)
{
@@ -138,7 +138,7 @@ static inline int arch_trampoline_kprobe(struct kprobe *p)
{
return 0;
}
-#endif /* ARCH_SUPPORTS_KRETPROBES */
+#endif /* CONFIG_KRETPROBES */
/*
* Function-return probe -
* Note:
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 4de4fd2d860..c1ec04fd000 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -221,6 +221,7 @@ struct kvm_vapic_addr {
* Get size for mmap(vcpu_fd)
*/
#define KVM_GET_VCPU_MMAP_SIZE _IO(KVMIO, 0x04) /* in bytes */
+#define KVM_GET_SUPPORTED_CPUID _IOWR(KVMIO, 0x05, struct kvm_cpuid2)
/*
* Extension capability list.
@@ -230,8 +231,8 @@ struct kvm_vapic_addr {
#define KVM_CAP_MMU_SHADOW_CACHE_CONTROL 2
#define KVM_CAP_USER_MEMORY 3
#define KVM_CAP_SET_TSS_ADDR 4
-#define KVM_CAP_EXT_CPUID 5
#define KVM_CAP_VAPIC 6
+#define KVM_CAP_EXT_CPUID 7
/*
* ioctls for VM fds
@@ -249,7 +250,6 @@ struct kvm_vapic_addr {
#define KVM_CREATE_VCPU _IO(KVMIO, 0x41)
#define KVM_GET_DIRTY_LOG _IOW(KVMIO, 0x42, struct kvm_dirty_log)
#define KVM_SET_MEMORY_ALIAS _IOW(KVMIO, 0x43, struct kvm_memory_alias)
-#define KVM_GET_SUPPORTED_CPUID _IOWR(KVMIO, 0x48, struct kvm_cpuid2)
/* Device model IOC */
#define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60)
#define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index ea4764b0a2f..928b0d59e9b 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -107,6 +107,7 @@ struct kvm_memory_slot {
struct kvm {
struct mutex lock; /* protects the vcpus array and APIC accesses */
spinlock_t mmu_lock;
+ struct rw_semaphore slots_lock;
struct mm_struct *mm; /* userspace tied to this vm */
int nmemslots;
struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS +
diff --git a/include/linux/libata.h b/include/linux/libata.h
index bc5a8d0c709..a05f6001364 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -138,6 +138,7 @@ enum {
ATA_DFLAG_AN = (1 << 7), /* AN configured */
ATA_DFLAG_HIPM = (1 << 8), /* device supports HIPM */
ATA_DFLAG_DIPM = (1 << 9), /* device supports DIPM */
+ ATA_DFLAG_DMADIR = (1 << 10), /* device requires DMADIR */
ATA_DFLAG_CFG_MASK = (1 << 12) - 1,
ATA_DFLAG_PIO = (1 << 12), /* device limited to PIO mode */
@@ -278,7 +279,6 @@ enum {
/* size of buffer to pad xfers ending on unaligned boundaries */
ATA_DMA_PAD_SZ = 4,
- ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE,
/* ering size */
ATA_ERING_SIZE = 32,
@@ -457,24 +457,18 @@ struct ata_queued_cmd {
unsigned long flags; /* ATA_QCFLAG_xxx */
unsigned int tag;
unsigned int n_elem;
- unsigned int mapped_n_elem;
int dma_dir;
- unsigned int pad_len;
unsigned int sect_size;
unsigned int nbytes;
- unsigned int raw_nbytes;
unsigned int curbytes;
struct scatterlist *cursg;
unsigned int cursg_ofs;
- struct scatterlist *last_sg;
- struct scatterlist saved_last_sg;
struct scatterlist sgent;
- struct scatterlist extra_sg[2];
struct scatterlist *sg;
@@ -619,9 +613,6 @@ struct ata_port {
struct ata_prd *prd; /* our SG list */
dma_addr_t prd_dma; /* and its DMA mapping */
- void *pad; /* array of DMA pad buffers */
- dma_addr_t pad_dma;
-
struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */
u8 ctl; /* cache of ATA control register */
@@ -1207,7 +1198,7 @@ static inline struct ata_link *ata_port_next_link(struct ata_link *link)
return ap->pmp_link;
}
- if (++link - ap->pmp_link < ap->nr_pmp_links)
+ if (++link < ap->nr_pmp_links + ap->pmp_link)
return link;
return NULL;
}
@@ -1363,12 +1354,9 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
qc->flags = 0;
qc->cursg = NULL;
qc->cursg_ofs = 0;
- qc->nbytes = qc->raw_nbytes = qc->curbytes = 0;
+ qc->nbytes = qc->curbytes = 0;
qc->n_elem = 0;
- qc->mapped_n_elem = 0;
qc->err_mask = 0;
- qc->pad_len = 0;
- qc->last_sg = NULL;
qc->sect_size = ATA_SECT_SIZE;
ata_tf_init(qc->dev, &qc->tf);
@@ -1423,19 +1411,6 @@ static inline unsigned int __ac_err_mask(u8 status)
return mask;
}
-static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev)
-{
- ap->pad_dma = 0;
- ap->pad = dmam_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ,
- &ap->pad_dma, GFP_KERNEL);
- return (ap->pad == NULL) ? -ENOMEM : 0;
-}
-
-static inline void ata_pad_free(struct ata_port *ap, struct device *dev)
-{
- dmam_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);
-}
-
static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host)
{
return *(struct ata_port **)&host->hostdata[0];
diff --git a/include/linux/maple.h b/include/linux/maple.h
index 3f01e2bae1a..d31e36ebb43 100644
--- a/include/linux/maple.h
+++ b/include/linux/maple.h
@@ -64,7 +64,6 @@ struct maple_driver {
int (*connect) (struct maple_device * dev);
void (*disconnect) (struct maple_device * dev);
struct device_driver drv;
- int registered;
};
void maple_getcond_callback(struct maple_device *dev,
diff --git a/include/linux/marker.h b/include/linux/marker.h
index 5df879dc377..430f6adf976 100644
--- a/include/linux/marker.h
+++ b/include/linux/marker.h
@@ -104,10 +104,16 @@ static inline void marker_update_probe_range(struct marker *begin,
#define MARK_NOARGS " "
/* To be used for string format validity checking with gcc */
-static inline void __printf(1, 2) __mark_check_format(const char *fmt, ...)
+static inline void __printf(1, 2) ___mark_check_format(const char *fmt, ...)
{
}
+#define __mark_check_format(format, args...) \
+ do { \
+ if (0) \
+ ___mark_check_format(format, ## args); \
+ } while (0)
+
extern marker_probe_func __mark_empty_function;
extern void marker_probe_cb(const struct marker *mdata,
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 925d57b236a..8b1c4295848 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -20,26 +20,25 @@
#ifndef _LINUX_MEMCONTROL_H
#define _LINUX_MEMCONTROL_H
-#include <linux/rcupdate.h>
-#include <linux/mm.h>
-
struct mem_cgroup;
struct page_cgroup;
struct page;
struct mm_struct;
-#ifdef CONFIG_CGROUP_MEM_CONT
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
extern void mm_init_cgroup(struct mm_struct *mm, struct task_struct *p);
extern void mm_free_cgroup(struct mm_struct *mm);
-extern void page_assign_page_cgroup(struct page *page,
- struct page_cgroup *pc);
+
+#define page_reset_bad_cgroup(page) ((page)->page_cgroup = 0)
+
extern struct page_cgroup *page_get_page_cgroup(struct page *page);
extern int mem_cgroup_charge(struct page *page, struct mm_struct *mm,
gfp_t gfp_mask);
-extern void mem_cgroup_uncharge(struct page_cgroup *pc);
+extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
+ gfp_t gfp_mask);
extern void mem_cgroup_uncharge_page(struct page *page);
-extern void mem_cgroup_move_lists(struct page_cgroup *pc, bool active);
+extern void mem_cgroup_move_lists(struct page *page, bool active);
extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
struct list_head *dst,
unsigned long *scanned, int order,
@@ -47,11 +46,9 @@ extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
struct mem_cgroup *mem_cont,
int active);
extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask);
-extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
- gfp_t gfp_mask);
int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem);
-#define vm_match_cgroup(mm, cgroup) \
+#define mm_match_cgroup(mm, cgroup) \
((cgroup) == rcu_dereference((mm)->mem_cgroup))
extern int mem_cgroup_prepare_migration(struct page *page);
@@ -75,7 +72,7 @@ extern long mem_cgroup_calc_reclaim_active(struct mem_cgroup *mem,
extern long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem,
struct zone *zone, int priority);
-#else /* CONFIG_CGROUP_MEM_CONT */
+#else /* CONFIG_CGROUP_MEM_RES_CTLR */
static inline void mm_init_cgroup(struct mm_struct *mm,
struct task_struct *p)
{
@@ -85,8 +82,7 @@ static inline void mm_free_cgroup(struct mm_struct *mm)
{
}
-static inline void page_assign_page_cgroup(struct page *page,
- struct page_cgroup *pc)
+static inline void page_reset_bad_cgroup(struct page *page)
{
}
@@ -95,33 +91,27 @@ static inline struct page_cgroup *page_get_page_cgroup(struct page *page)
return NULL;
}
-static inline int mem_cgroup_charge(struct page *page, struct mm_struct *mm,
- gfp_t gfp_mask)
+static inline int mem_cgroup_charge(struct page *page,
+ struct mm_struct *mm, gfp_t gfp_mask)
{
return 0;
}
-static inline void mem_cgroup_uncharge(struct page_cgroup *pc)
+static inline int mem_cgroup_cache_charge(struct page *page,
+ struct mm_struct *mm, gfp_t gfp_mask)
{
+ return 0;
}
static inline void mem_cgroup_uncharge_page(struct page *page)
{
}
-static inline void mem_cgroup_move_lists(struct page_cgroup *pc,
- bool active)
+static inline void mem_cgroup_move_lists(struct page *page, bool active)
{
}
-static inline int mem_cgroup_cache_charge(struct page *page,
- struct mm_struct *mm,
- gfp_t gfp_mask)
-{
- return 0;
-}
-
-static inline int vm_match_cgroup(struct mm_struct *mm, struct mem_cgroup *mem)
+static inline int mm_match_cgroup(struct mm_struct *mm, struct mem_cgroup *mem)
{
return 1;
}
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 26c7124b841..3f3ccfe42de 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -235,6 +235,7 @@ static inline int get_page_unless_zero(struct page *page)
struct page *vmalloc_to_page(const void *addr);
unsigned long vmalloc_to_pfn(const void *addr);
+#ifdef CONFIG_MMU
/* Determine if an address is within the vmalloc range */
static inline int is_vmalloc_addr(const void *x)
{
@@ -242,6 +243,7 @@ static inline int is_vmalloc_addr(const void *x)
return addr >= VMALLOC_START && addr < VMALLOC_END;
}
+#endif
static inline struct page *compound_head(struct page *page)
{
@@ -1171,12 +1173,18 @@ static inline void enable_debug_pagealloc(void)
{
debug_pagealloc_enabled = 1;
}
+#ifdef CONFIG_HIBERNATION
+extern bool kernel_page_present(struct page *page);
+#endif /* CONFIG_HIBERNATION */
#else
static inline void
kernel_map_pages(struct page *page, int numpages, int enable) {}
static inline void enable_debug_pagealloc(void)
{
}
+#ifdef CONFIG_HIBERNATION
+static inline bool kernel_page_present(struct page *page) { return true; }
+#endif /* CONFIG_HIBERNATION */
#endif
extern struct vm_area_struct *get_gate_vma(struct task_struct *tsk);
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index bfee0bd1d43..af190ceab97 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -64,10 +64,7 @@ struct page {
#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
spinlock_t ptl;
#endif
- struct {
- struct kmem_cache *slab; /* SLUB: Pointer to slab */
- void *end; /* SLUB: end marker */
- };
+ struct kmem_cache *slab; /* SLUB: Pointer to slab */
struct page *first_page; /* Compound tail pages */
};
union {
@@ -91,7 +88,7 @@ struct page {
void *virtual; /* Kernel virtual address (NULL if
not kmapped, ie. highmem) */
#endif /* WANT_PAGE_VIRTUAL */
-#ifdef CONFIG_CGROUP_MEM_CONT
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
unsigned long page_cgroup;
#endif
};
@@ -225,7 +222,7 @@ struct mm_struct {
/* aio bits */
rwlock_t ioctx_list_lock;
struct kioctx *ioctx_list;
-#ifdef CONFIG_CGROUP_MEM_CONT
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
struct mem_cgroup *mem_cgroup;
#endif
};
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7128a02f1d3..a2f003239c8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -604,6 +604,10 @@ struct net_device
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
+ /* ingress path synchronizer */
+ spinlock_t ingress_lock;
+ struct Qdisc *qdisc_ingress;
+
/*
* Cache line mostly used on queue transmit path (qdisc)
*/
@@ -617,10 +621,6 @@ struct net_device
/* Partially transmitted GSO packet. */
struct sk_buff *gso_skb;
- /* ingress path synchronizer */
- spinlock_t ingress_lock;
- struct Qdisc *qdisc_ingress;
-
/*
* One part is mostly used on xmit path (device)
*/
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index d74e79bacd2..f0680c2bee7 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -31,7 +31,7 @@
#define NF_VERDICT_QMASK 0xffff0000
#define NF_VERDICT_QBITS 16
-#define NF_QUEUE_NR(x) (((x << NF_VERDICT_QBITS) & NF_VERDICT_QMASK) | NF_QUEUE)
+#define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE)
/* only for userspace compatibility */
#ifndef __KERNEL__
@@ -51,7 +51,7 @@ enum nf_inet_hooks {
};
union nf_inet_addr {
- u_int32_t all[4];
+ __u32 all[4];
__be32 ip;
__be32 ip6[4];
struct in_addr in;
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index 91fef0cae42..3aff513d12c 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -30,7 +30,6 @@ header-y += xt_mark.h
header-y += xt_multiport.h
header-y += xt_owner.h
header-y += xt_pkttype.h
-header-y += xt_policy.h
header-y += xt_rateest.h
header-y += xt_realm.h
header-y += xt_sctp.h
@@ -47,3 +46,4 @@ unifdef-y += nfnetlink.h
unifdef-y += nfnetlink_compat.h
unifdef-y += x_tables.h
unifdef-y += xt_physdev.h
+unifdef-y += xt_policy.h
diff --git a/include/linux/netfilter/xt_hashlimit.h b/include/linux/netfilter/xt_hashlimit.h
index 58b818ee41c..51b18d83b47 100644
--- a/include/linux/netfilter/xt_hashlimit.h
+++ b/include/linux/netfilter/xt_hashlimit.h
@@ -61,7 +61,6 @@ struct xt_hashlimit_mtinfo1 {
/* Used internally by the kernel */
struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
- struct xt_hashlimit_mtinfo1 *master __attribute__((aligned(8)));
};
#endif /*_XT_HASHLIMIT_H*/
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index a0525a1f471..e3d79593fb3 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -25,6 +25,7 @@ struct netpoll {
struct netpoll_info {
atomic_t refcnt;
+ int rx_flags;
spinlock_t rx_lock;
struct netpoll *rx_np; /* netpoll that registered an rx_hook */
struct sk_buff_head arp_tx; /* list of arp requests to reply to */
@@ -50,12 +51,12 @@ static inline int netpoll_rx(struct sk_buff *skb)
unsigned long flags;
int ret = 0;
- if (!npinfo || !npinfo->rx_np)
+ if (!npinfo || (!npinfo->rx_np && !npinfo->rx_flags))
return 0;
spin_lock_irqsave(&npinfo->rx_lock, flags);
- /* check rx_np again with the lock held */
- if (npinfo->rx_np && __netpoll_rx(skb))
+ /* check rx_flags again with the lock held */
+ if (npinfo->rx_flags && __netpoll_rx(skb))
ret = 1;
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index a69ba80f2df..f4a0e4c218d 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -195,6 +195,7 @@ struct nfs_inode {
#define NFS_INO_ADVISE_RDPLUS (1) /* advise readdirplus */
#define NFS_INO_STALE (2) /* possible stale inode */
#define NFS_INO_ACL_LRU_SET (3) /* Inode is on the LRU list */
+#define NFS_INO_MOUNTPOINT (4) /* inode is remote mountpoint */
static inline struct nfs_inode *NFS_I(const struct inode *inode)
{
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index bbad43fb818..b5b30f1c1e5 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -266,7 +266,7 @@ static inline void SetPageUptodate(struct page *page)
#define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim))
-#define PageTail(page) ((page->flags & PG_head_tail_mask) \
+#define PageTail(page) (((page)->flags & PG_head_tail_mask) \
== PG_head_tail_mask)
static inline void __SetPageTail(struct page *page)
@@ -279,7 +279,7 @@ static inline void __ClearPageTail(struct page *page)
page->flags &= ~PG_head_tail_mask;
}
-#define PageHead(page) ((page->flags & PG_head_tail_mask) \
+#define PageHead(page) (((page)->flags & PG_head_tail_mask) \
== (1L << PG_compound))
#define __SetPageHead(page) __SetPageCompound(page)
#define __ClearPageHead(page) __ClearPageCompound(page)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 87195b62de5..f3165e7ac43 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -389,6 +389,16 @@ struct pci_driver {
#define to_pci_driver(drv) container_of(drv, struct pci_driver, driver)
/**
+ * DECLARE_PCI_DEVICE_TABLE - macro used to describe a pci device table
+ * @_table: device table name
+ *
+ * This macro is used to create a struct pci_device_id array (a device table)
+ * in a generic manner.
+ */
+#define DECLARE_PCI_DEVICE_TABLE(_table) \
+ const struct pci_device_id _table[] __devinitconst
+
+/**
* PCI_DEVICE - macro used to describe a specific pci device
* @vend: the 16 bit PCI Vendor ID
* @dev: the 16 bit PCI Device ID
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index df6dd79a0d3..effdb558a58 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1351,6 +1351,7 @@
#define PCI_DEVICE_ID_VIA_8231_4 0x8235
#define PCI_DEVICE_ID_VIA_8365_1 0x8305
#define PCI_DEVICE_ID_VIA_CX700 0x8324
+#define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581
#define PCI_DEVICE_ID_VIA_VX800 0x8353
#define PCI_DEVICE_ID_VIA_8371_1 0x8391
#define PCI_DEVICE_ID_VIA_82C598_1 0x8598
@@ -2373,6 +2374,12 @@
#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a
#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e
#define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b
+#define PCI_DEVICE_ID_INTEL_ICH10_0 0x3a14
+#define PCI_DEVICE_ID_INTEL_ICH10_1 0x3a16
+#define PCI_DEVICE_ID_INTEL_ICH10_2 0x3a18
+#define PCI_DEVICE_ID_INTEL_ICH10_3 0x3a1a
+#define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a30
+#define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60
#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f
#define PCI_DEVICE_ID_INTEL_IOAT_SCNB 0x65ff
#define PCI_DEVICE_ID_INTEL_TOLAPAI_0 0x5031
diff --git a/include/linux/pm.h b/include/linux/pm.h
index eccf59ea2a7..015b735811b 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -143,6 +143,9 @@ typedef struct pm_message {
* the upcoming system state (such as PCI_D3hot), and enable
* wakeup events as appropriate.
*
+ * HIBERNATE Enter a low power device state appropriate for the hibernation
+ * state (eg. ACPI S4) and enable wakeup events as appropriate.
+ *
* FREEZE Quiesce operations so that a consistent image can be saved;
* but do NOT otherwise enter a low power device state, and do
* NOT emit system wakeup events.
@@ -166,11 +169,15 @@ typedef struct pm_message {
#define PM_EVENT_ON 0
#define PM_EVENT_FREEZE 1
#define PM_EVENT_SUSPEND 2
-#define PM_EVENT_PRETHAW 3
+#define PM_EVENT_HIBERNATE 4
+#define PM_EVENT_PRETHAW 8
+
+#define PM_EVENT_SLEEP (PM_EVENT_SUSPEND | PM_EVENT_HIBERNATE)
#define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, })
#define PMSG_PRETHAW ((struct pm_message){ .event = PM_EVENT_PRETHAW, })
#define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, })
+#define PMSG_HIBERNATE ((struct pm_message){ .event = PM_EVENT_HIBERNATE, })
#define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, })
struct dev_pm_info {
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index e51b531cd0b..47fbcba1185 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -235,6 +235,8 @@ struct bitmap {
unsigned long flags;
+ int allclean;
+
unsigned long max_write_behind; /* write-behind mode */
atomic_t behind_writes;
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 85a068bab62..7bb6d1abf71 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -83,6 +83,7 @@ struct mdk_rdev_s
#define BarriersNotsupp 5 /* BIO_RW_BARRIER is not supported */
#define AllReserved 6 /* If whole device is reserved for
* one array */
+#define AutoDetected 7 /* added by auto-detect */
int desc_nr; /* descriptor index in the superblock */
int raid_disk; /* role of device in array */
diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h
index 4d6624260b4..b3dccd68629 100644
--- a/include/linux/rcuclassic.h
+++ b/include/linux/rcuclassic.h
@@ -160,5 +160,8 @@ extern void rcu_restart_cpu(int cpu);
extern long rcu_batches_completed(void);
extern long rcu_batches_completed_bh(void);
+#define rcu_enter_nohz() do { } while (0)
+#define rcu_exit_nohz() do { } while (0)
+
#endif /* __KERNEL__ */
#endif /* __LINUX_RCUCLASSIC_H */
diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h
index 60c2a033b19..01152ed532c 100644
--- a/include/linux/rcupreempt.h
+++ b/include/linux/rcupreempt.h
@@ -82,5 +82,27 @@ extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu);
struct softirq_action;
+#ifdef CONFIG_NO_HZ
+DECLARE_PER_CPU(long, dynticks_progress_counter);
+
+static inline void rcu_enter_nohz(void)
+{
+ __get_cpu_var(dynticks_progress_counter)++;
+ WARN_ON(__get_cpu_var(dynticks_progress_counter) & 0x1);
+ mb();
+}
+
+static inline void rcu_exit_nohz(void)
+{
+ mb();
+ __get_cpu_var(dynticks_progress_counter)++;
+ WARN_ON(!(__get_cpu_var(dynticks_progress_counter) & 0x1));
+}
+
+#else /* CONFIG_NO_HZ */
+#define rcu_enter_nohz() do { } while (0)
+#define rcu_exit_nohz() do { } while (0)
+#endif /* CONFIG_NO_HZ */
+
#endif /* __KERNEL__ */
#endif /* __LINUX_RCUPREEMPT_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index e217d188a10..11d8e9a74ef 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -242,6 +242,7 @@ struct task_struct;
extern void sched_init(void);
extern void sched_init_smp(void);
+extern asmlinkage void schedule_tail(struct task_struct *prev);
extern void init_idle(struct task_struct *idle, int cpu);
extern void init_idle_bootup_task(struct task_struct *idle);
@@ -898,6 +899,10 @@ struct sched_class {
int running);
void (*prio_changed) (struct rq *this_rq, struct task_struct *task,
int oldprio, int running);
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ void (*moved_group) (struct task_struct *p);
+#endif
};
struct load_weight {
@@ -1189,7 +1194,7 @@ struct task_struct {
int softirq_context;
#endif
#ifdef CONFIG_LOCKDEP
-# define MAX_LOCK_DEPTH 30UL
+# define MAX_LOCK_DEPTH 48UL
u64 curr_chain_key;
int lockdep_depth;
struct held_lock held_locks[MAX_LOCK_DEPTH];
@@ -1541,10 +1546,6 @@ extern unsigned int sysctl_sched_child_runs_first;
extern unsigned int sysctl_sched_features;
extern unsigned int sysctl_sched_migration_cost;
extern unsigned int sysctl_sched_nr_migrate;
-#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP)
-extern unsigned int sysctl_sched_min_bal_int_shares;
-extern unsigned int sysctl_sched_max_bal_int_shares;
-#endif
int sched_nr_latency_handler(struct ctl_table *table, int write,
struct file *file, void __user *buffer, size_t *length,
diff --git a/include/linux/security.h b/include/linux/security.h
index fe52cdeab0a..b07357ca213 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -34,12 +34,6 @@
#include <linux/xfrm.h>
#include <net/flow.h>
-/* only a char in selinux superblock security struct flags */
-#define FSCONTEXT_MNT 0x01
-#define CONTEXT_MNT 0x02
-#define ROOTCONTEXT_MNT 0x04
-#define DEFCONTEXT_MNT 0x08
-
extern unsigned securebits;
struct ctl_table;
@@ -114,6 +108,32 @@ struct request_sock;
#ifdef CONFIG_SECURITY
+struct security_mnt_opts {
+ char **mnt_opts;
+ int *mnt_opts_flags;
+ int num_mnt_opts;
+};
+
+static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
+{
+ opts->mnt_opts = NULL;
+ opts->mnt_opts_flags = NULL;
+ opts->num_mnt_opts = 0;
+}
+
+static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
+{
+ int i;
+ if (opts->mnt_opts)
+ for(i = 0; i < opts->num_mnt_opts; i++)
+ kfree(opts->mnt_opts[i]);
+ kfree(opts->mnt_opts);
+ opts->mnt_opts = NULL;
+ kfree(opts->mnt_opts_flags);
+ opts->mnt_opts_flags = NULL;
+ opts->num_mnt_opts = 0;
+}
+
/**
* struct security_operations - main security structure
*
@@ -262,19 +282,19 @@ struct request_sock;
* @sb_get_mnt_opts:
* Get the security relevant mount options used for a superblock
* @sb the superblock to get security mount options from
- * @mount_options array for pointers to mount options
- * @mount_flags array of ints specifying what each mount options is
- * @num_opts number of options in the arrays
+ * @opts binary data structure containing all lsm mount data
* @sb_set_mnt_opts:
* Set the security relevant mount options used for a superblock
* @sb the superblock to set security mount options for
- * @mount_options array for pointers to mount options
- * @mount_flags array of ints specifying what each mount options is
- * @num_opts number of options in the arrays
+ * @opts binary data structure containing all lsm mount data
* @sb_clone_mnt_opts:
* Copy all security options from a given superblock to another
* @oldsb old superblock which contain information to clone
* @newsb new superblock which needs filled in
+ * @sb_parse_opts_str:
+ * Parse a string of security data filling in the opts structure
+ * @options string containing all mount options known by the LSM
+ * @opts binary data structure usable by the LSM
*
* Security hooks for inode operations.
*
@@ -1238,8 +1258,7 @@ struct security_operations {
int (*sb_alloc_security) (struct super_block * sb);
void (*sb_free_security) (struct super_block * sb);
- int (*sb_copy_data)(struct file_system_type *type,
- void *orig, void *copy);
+ int (*sb_copy_data)(char *orig, char *copy);
int (*sb_kern_mount) (struct super_block *sb, void *data);
int (*sb_statfs) (struct dentry *dentry);
int (*sb_mount) (char *dev_name, struct nameidata * nd,
@@ -1257,12 +1276,12 @@ struct security_operations {
void (*sb_post_pivotroot) (struct nameidata * old_nd,
struct nameidata * new_nd);
int (*sb_get_mnt_opts) (const struct super_block *sb,
- char ***mount_options, int **flags,
- int *num_opts);
- int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options,
- int *flags, int num_opts);
+ struct security_mnt_opts *opts);
+ int (*sb_set_mnt_opts) (struct super_block *sb,
+ struct security_mnt_opts *opts);
void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
struct super_block *newsb);
+ int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts);
int (*inode_alloc_security) (struct inode *inode);
void (*inode_free_security) (struct inode *inode);
@@ -1507,7 +1526,7 @@ int security_bprm_check(struct linux_binprm *bprm);
int security_bprm_secureexec(struct linux_binprm *bprm);
int security_sb_alloc(struct super_block *sb);
void security_sb_free(struct super_block *sb);
-int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy);
+int security_sb_copy_data(char *orig, char *copy);
int security_sb_kern_mount(struct super_block *sb, void *data);
int security_sb_statfs(struct dentry *dentry);
int security_sb_mount(char *dev_name, struct nameidata *nd,
@@ -1520,12 +1539,12 @@ void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *d
void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd);
int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
-int security_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options,
- int **flags, int *num_opts);
-int security_sb_set_mnt_opts(struct super_block *sb, char **mount_options,
- int *flags, int num_opts);
+int security_sb_get_mnt_opts(const struct super_block *sb,
+ struct security_mnt_opts *opts);
+int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts);
void security_sb_clone_mnt_opts(const struct super_block *oldsb,
struct super_block *newsb);
+int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
int security_inode_alloc(struct inode *inode);
void security_inode_free(struct inode *inode);
@@ -1635,6 +1654,16 @@ int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid);
void security_release_secctx(char *secdata, u32 seclen);
#else /* CONFIG_SECURITY */
+struct security_mnt_opts {
+};
+
+static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
+{
+}
+
+static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
+{
+}
/*
* This is the default capabilities functionality. Most of these functions
@@ -1762,8 +1791,7 @@ static inline int security_sb_alloc (struct super_block *sb)
static inline void security_sb_free (struct super_block *sb)
{ }
-static inline int security_sb_copy_data (struct file_system_type *type,
- void *orig, void *copy)
+static inline int security_sb_copy_data (char *orig, char *copy)
{
return 0;
}
@@ -1819,6 +1847,27 @@ static inline int security_sb_pivotroot (struct nameidata *old_nd,
static inline void security_sb_post_pivotroot (struct nameidata *old_nd,
struct nameidata *new_nd)
{ }
+static inline int security_sb_get_mnt_opts(const struct super_block *sb,
+ struct security_mnt_opts *opts)
+{
+ security_init_mnt_opts(opts);
+ return 0;
+}
+
+static inline int security_sb_set_mnt_opts(struct super_block *sb,
+ struct security_mnt_opts *opts)
+{
+ return 0;
+}
+
+static inline void security_sb_clone_mnt_opts(const struct super_block *oldsb,
+ struct super_block *newsb)
+{ }
+
+static inline int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
+{
+ return 0;
+}
static inline int security_inode_alloc (struct inode *inode)
{
diff --git a/include/asm-sh/sci.h b/include/linux/serial_sci.h
index 52e73660c12..893cc53486b 100644
--- a/include/asm-sh/sci.h
+++ b/include/linux/serial_sci.h
@@ -1,12 +1,10 @@
-#ifndef __ASM_SH_SCI_H
-#define __ASM_SH_SCI_H
+#ifndef __LINUX_SERIAL_SCI_H
+#define __LINUX_SERIAL_SCI_H
#include <linux/serial_core.h>
/*
- * Generic header for SuperH SCI(F)
- *
- * Do not place SH-specific parts in here, sh64 and h8300 depend on this too.
+ * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts)
*/
/* Offsets into the sci_port->irqs array */
@@ -31,4 +29,4 @@ struct plat_sci_port {
int early_sci_setup(struct uart_port *port);
-#endif /* __ASM_SH_SCI_H */
+#endif /* __LINUX_SERIAL_SCI_H */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 412672a79e8..bbd8d0027e2 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -232,6 +232,8 @@ typedef unsigned char *sk_buff_data_t;
* @mark: Generic packet mark
* @nfct: Associated connection, if any
* @ipvs_property: skbuff is owned by ipvs
+ * @peeked: this packet has been seen already, so stats have been
+ * done for it, don't do them again
* @nf_trace: netfilter packet trace flag
* @nfctinfo: Relationship of this skb to the connection
* @nfct_reasm: netfilter conntrack re-assembly pointer
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index fcc48096ee6..39c3a5eb8eb 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -41,7 +41,7 @@ static inline void *kmalloc(size_t size, gfp_t flags)
goto found; \
else \
i++;
-#include "kmalloc_sizes.h"
+#include <linux/kmalloc_sizes.h>
#undef CACHE
{
extern void __you_cannot_kmalloc_that_much(void);
@@ -75,7 +75,7 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
goto found; \
else \
i++;
-#include "kmalloc_sizes.h"
+#include <linux/kmalloc_sizes.h>
#undef CACHE
{
extern void __you_cannot_kmalloc_that_much(void);
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 57deecc79d5..b00c1c73eb0 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -61,7 +61,7 @@ struct kmem_cache {
int size; /* The size of an object including meta data */
int objsize; /* The size of an object without meta data */
int offset; /* Free pointer offset. */
- int order;
+ int order; /* Current preferred allocation order */
/*
* Avoid an extra cache line for UP, SMP and for the node local to
@@ -138,11 +138,11 @@ static __always_inline int kmalloc_index(size_t size)
if (size <= 512) return 9;
if (size <= 1024) return 10;
if (size <= 2 * 1024) return 11;
+ if (size <= 4 * 1024) return 12;
/*
* The following is only needed to support architectures with a larger page
* size than 4k.
*/
- if (size <= 4 * 1024) return 12;
if (size <= 8 * 1024) return 13;
if (size <= 16 * 1024) return 14;
if (size <= 32 * 1024) return 15;
diff --git a/include/linux/sm501-regs.h b/include/linux/sm501-regs.h
index 64236b73c72..d53642d2d89 100644
--- a/include/linux/sm501-regs.h
+++ b/include/linux/sm501-regs.h
@@ -129,11 +129,14 @@
#define SM501_DEVICEID_SM501 (0x05010000)
#define SM501_DEVICEID_IDMASK (0xffff0000)
+#define SM501_DEVICEID_REVMASK (0x000000ff)
#define SM501_PLLCLOCK_COUNT (0x000064)
#define SM501_MISC_TIMING (0x000068)
#define SM501_CURRENT_SDRAM_CLOCK (0x00006C)
+#define SM501_PROGRAMMABLE_PLL_CONTROL (0x000074)
+
/* GPIO base */
#define SM501_GPIO (0x010000)
#define SM501_GPIO_DATA_LOW (0x00)
diff --git a/include/linux/sm501.h b/include/linux/sm501.h
index 932a9efee8a..bca13454470 100644
--- a/include/linux/sm501.h
+++ b/include/linux/sm501.h
@@ -24,7 +24,8 @@ extern int sm501_unit_power(struct device *dev,
extern unsigned long sm501_set_clock(struct device *dev,
int clksrc, unsigned long freq);
-extern unsigned long sm501_find_clock(int clksrc, unsigned long req_freq);
+extern unsigned long sm501_find_clock(struct device *dev,
+ int clksrc, unsigned long req_freq);
/* sm501_misc_control
*
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 9d5da8b2ccf..20add65215a 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -282,6 +282,13 @@ struct ssb_bus {
struct ssb_boardinfo boardinfo;
/* Contents of the SPROM. */
struct ssb_sprom sprom;
+ /* If the board has a cardbus slot, this is set to true. */
+ bool has_cardbus_slot;
+
+#ifdef CONFIG_SSB_EMBEDDED
+ /* Lock for GPIO register access. */
+ spinlock_t gpio_lock;
+#endif /* EMBEDDED */
/* Internal-only stuff follows. Do not touch. */
struct list_head list;
@@ -294,8 +301,13 @@ struct ssb_bus {
/* The initialization-invariants. */
struct ssb_init_invariants {
+ /* Versioning information about the PCB. */
struct ssb_boardinfo boardinfo;
+ /* The SPROM information. That's either stored in an
+ * EEPROM or NVRAM on the board. */
struct ssb_sprom sprom;
+ /* If the board has a cardbus slot, this is set to true. */
+ bool has_cardbus_slot;
};
/* Type of function to fetch the invariants. */
typedef int (*ssb_invariants_func_t)(struct ssb_bus *bus,
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index 4cb99549466..536851b946f 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -51,9 +51,12 @@
#define SSB_CHIPCO_CAP_JTAGM 0x00400000 /* JTAG master present */
#define SSB_CHIPCO_CAP_BROM 0x00800000 /* Internal boot ROM active */
#define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */
+#define SSB_CHIPCO_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */
+#define SSB_CHIPCO_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */
#define SSB_CHIPCO_CORECTL 0x0008
#define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
#define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
+#define SSB_CHIPCO_CORECTL_UARTCLKEN 0x00000008 /* UART clock enable (rev >= 21) */
#define SSB_CHIPCO_BIST 0x000C
#define SSB_CHIPCO_OTPS 0x0010 /* OTP status */
#define SSB_CHIPCO_OTPS_PROGFAIL 0x80000000
@@ -357,6 +360,11 @@ struct ssb_chipcommon {
u16 fast_pwrup_delay;
};
+static inline bool ssb_chipco_available(struct ssb_chipcommon *cc)
+{
+ return (cc->dev != NULL);
+}
+
extern void ssb_chipcommon_init(struct ssb_chipcommon *cc);
#include <linux/pm.h>
@@ -382,11 +390,13 @@ extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc,
u32 ticks);
+/* Chipcommon GPIO pin access. */
u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask);
-
-void ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value);
-
-void ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value);
+u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value);
+u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value);
+u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value);
+u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value);
+u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value);
#ifdef CONFIG_SSB_SERIAL
extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
diff --git a/include/linux/ssb/ssb_driver_extif.h b/include/linux/ssb/ssb_driver_extif.h
index a9164357b5a..91161f0aa22 100644
--- a/include/linux/ssb/ssb_driver_extif.h
+++ b/include/linux/ssb/ssb_driver_extif.h
@@ -171,11 +171,15 @@ extern void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
extern void ssb_extif_timing_init(struct ssb_extif *extif,
unsigned long ns);
-u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask);
-
-void ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value);
+extern void ssb_extif_watchdog_timer_set(struct ssb_extif *extif,
+ u32 ticks);
-void ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value);
+/* Extif GPIO pin access */
+u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask);
+u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value);
+u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value);
+u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value);
+u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value);
#ifdef CONFIG_SSB_SERIAL
extern int ssb_extif_serial_init(struct ssb_extif *extif,
@@ -200,5 +204,11 @@ void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
{
}
+static inline
+void ssb_extif_watchdog_timer_set(struct ssb_extif *extif,
+ u32 ticks)
+{
+}
+
#endif /* CONFIG_SSB_DRIVER_EXTIF */
#endif /* LINUX_SSB_EXTIFCORE_H_ */
diff --git a/include/linux/ssb/ssb_driver_pci.h b/include/linux/ssb/ssb_driver_pci.h
index 9cfffb7b1a2..5e25bac4ed3 100644
--- a/include/linux/ssb/ssb_driver_pci.h
+++ b/include/linux/ssb/ssb_driver_pci.h
@@ -51,6 +51,11 @@
#define SSB_PCICORE_SBTOPCI1_MASK 0xFC000000
#define SSB_PCICORE_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */
#define SSB_PCICORE_SBTOPCI2_MASK 0xC0000000
+#define SSB_PCICORE_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */
+#define SSB_PCICORE_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */
+#define SSB_PCICORE_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */
+#define SSB_PCICORE_PCICFG3 0x0700 /* PCI config space 3 (rev >= 8) */
+#define SSB_PCICORE_SPROM(wordoffset) (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */
/* SBtoPCIx */
#define SSB_PCICORE_SBTOPCI_MEM 0x00000000
diff --git a/include/linux/ssb/ssb_embedded.h b/include/linux/ssb/ssb_embedded.h
new file mode 100644
index 00000000000..8d8dedff059
--- /dev/null
+++ b/include/linux/ssb/ssb_embedded.h
@@ -0,0 +1,18 @@
+#ifndef LINUX_SSB_EMBEDDED_H_
+#define LINUX_SSB_EMBEDDED_H_
+
+#include <linux/types.h>
+#include <linux/ssb/ssb.h>
+
+
+extern int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks);
+
+/* Generic GPIO API */
+u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask);
+u32 ssb_gpio_out(struct ssb_bus *bus, u32 mask, u32 value);
+u32 ssb_gpio_outen(struct ssb_bus *bus, u32 mask, u32 value);
+u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value);
+u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value);
+u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value);
+
+#endif /* LINUX_SSB_EMBEDDED_H_ */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 2372e2e6b52..583e0481dfa 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -94,10 +94,9 @@ enum usb_interface_condition {
* @altsetting: array of interface structures, one for each alternate
* setting that may be selected. Each one includes a set of
* endpoint configurations. They will be in no particular order.
- * @num_altsetting: number of altsettings defined.
* @cur_altsetting: the current altsetting.
+ * @num_altsetting: number of altsettings defined.
* @intf_assoc: interface association descriptor
- * @driver: the USB driver that is bound to this interface.
* @minor: the minor number assigned to this interface, if this
* interface is bound to a driver that uses the USB major number.
* If this interface does not use the USB major, this field should
@@ -781,8 +780,7 @@ static inline int usb_endpoint_is_isoc_out(
.idVendor = (vend), \
.idProduct = (prod)
/**
- * USB_DEVICE_VER - macro used to describe a specific usb device with a
- * version range
+ * USB_DEVICE_VER - describe a specific usb device with a version range
* @vend: the 16 bit USB Vendor ID
* @prod: the 16 bit USB Product ID
* @lo: the bcdDevice_lo value
@@ -799,8 +797,7 @@ static inline int usb_endpoint_is_isoc_out(
.bcdDevice_hi = (hi)
/**
- * USB_DEVICE_INTERFACE_PROTOCOL - macro used to describe a usb
- * device with a specific interface protocol
+ * USB_DEVICE_INTERFACE_PROTOCOL - describe a usb device with a specific interface protocol
* @vend: the 16 bit USB Vendor ID
* @prod: the 16 bit USB Product ID
* @pr: bInterfaceProtocol value
@@ -846,8 +843,7 @@ static inline int usb_endpoint_is_isoc_out(
.bInterfaceProtocol = (pr)
/**
- * USB_DEVICE_AND_INTERFACE_INFO - macro used to describe a specific usb device
- * with a class of usb interfaces
+ * USB_DEVICE_AND_INTERFACE_INFO - describe a specific usb device with a class of usb interfaces
* @vend: the 16 bit USB Vendor ID
* @prod: the 16 bit USB Product ID
* @cl: bInterfaceClass value
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 52e3d5fd5be..9385a566aed 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -12,6 +12,7 @@
#ifndef __LINUX_VIDEODEV_H
#define __LINUX_VIDEODEV_H
+#include <linux/ioctl.h>
#include <linux/videodev2.h>
#if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__)
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 439474f24e3..17a80177a67 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -62,6 +62,7 @@
#define __user
#include <sys/time.h>
#endif
+#include <linux/ioctl.h>
#include <linux/types.h>
/*
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 75370ec0923..9f1b4b46151 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -246,8 +246,7 @@ static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
static inline void __dec_zone_page_state(struct page *page,
enum zone_stat_item item)
{
- atomic_long_dec(&page_zone(page)->vm_stat[item]);
- atomic_long_dec(&vm_stat[item]);
+ __dec_zone_state(page_zone(page), item);
}
/*
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 831547d7968..a4274203f25 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -142,6 +142,7 @@ extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE];
#endif
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 475d0d8275e..316a5845313 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -61,8 +61,6 @@
v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
} while (0)
-/* Prints the ioctl in a human-readable format */
-extern void v4l_printk_ioctl(unsigned int cmd);
/* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */
#define v4l_print_ioctl(name, cmd) \
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index c544c6f9089..f2114459995 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -44,6 +44,8 @@ extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
extern char *v4l2_norm_to_name(v4l2_std_id id);
extern int v4l2_video_std_construct(struct v4l2_standard *vs,
int id, char *name);
+/* Prints the ioctl in a human-readable format */
+extern void v4l_printk_ioctl(unsigned int cmd);
/* prority handling */
struct v4l2_prio_state {
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
index 97f14d46959..99033945cde 100644
--- a/include/media/videobuf-core.h
+++ b/include/media/videobuf-core.h
@@ -149,7 +149,7 @@ struct videobuf_qtype_ops {
};
struct videobuf_queue {
- struct mutex lock;
+ struct mutex vb_lock;
spinlock_t *irqlock;
void *dev; /* on pci, points to struct pci_dev */
diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h
index 26a8958d23d..ec63ab0fab9 100644
--- a/include/media/videobuf-vmalloc.h
+++ b/include/media/videobuf-vmalloc.h
@@ -17,7 +17,7 @@
/* --------------------------------------------------------------------- */
-struct videbuf_vmalloc_memory
+struct videobuf_vmalloc_memory
{
u32 magic;
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 32a57e1dee3..717e2192d52 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -324,6 +324,7 @@ extern void ax25_dama_on(ax25_cb *);
extern void ax25_dama_off(ax25_cb *);
/* ax25_ds_timer.c */
+extern void ax25_ds_setup_timer(ax25_dev *);
extern void ax25_ds_set_timer(ax25_dev *);
extern void ax25_ds_del_timer(ax25_dev *);
extern void ax25_ds_timer(ax25_cb *);
@@ -416,6 +417,7 @@ extern void ax25_calculate_rtt(ax25_cb *);
extern void ax25_disconnect(ax25_cb *, int);
/* ax25_timer.c */
+extern void ax25_setup_timers(ax25_cb *);
extern void ax25_start_heartbeat(ax25_cb *);
extern void ax25_start_t1timer(ax25_cb *);
extern void ax25_start_t2timer(ax25_cb *);
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 70013c5f4e5..89cd011edb9 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -175,7 +175,8 @@ extern void build_ehash_secret(void);
static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport,
const __be32 faddr, const __be16 fport)
{
- return jhash_2words((__force __u32) laddr ^ (__force __u32) faddr,
+ return jhash_3words((__force __u32) laddr,
+ (__force __u32) faddr,
((__u32) lport) << 16 | (__force __u32)fport,
inet_ehash_secret);
}
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index c17fa1fdc35..6512d85f11b 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -14,8 +14,6 @@
/* capable of receiving packets */
#define IP6_TNL_F_CAP_RCV 0x20000
-#define IP6_TNL_MAX 128
-
/* IPv6 tunnel */
struct ip6_tnl {
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 6684f7efbee..59b70624b05 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -103,7 +103,6 @@ extern void ndisc_send_redirect(struct sk_buff *skb,
extern int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir);
-struct rt6_info * dflt_rt_lookup(void);
/*
* IGMP
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index 9462d6ae2f3..9619b9d35c9 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -411,6 +411,7 @@ struct sctp_event_subscribe {
__u8 sctp_shutdown_event;
__u8 sctp_partial_delivery_event;
__u8 sctp_adaptation_layer_event;
+ __u8 sctp_authentication_event;
};
/*
@@ -587,7 +588,7 @@ struct sctp_authchunk {
* endpoint requires the peer to use.
*/
struct sctp_hmacalgo {
- __u16 shmac_num_idents;
+ __u32 shmac_num_idents;
__u16 shmac_idents[];
};
@@ -600,7 +601,7 @@ struct sctp_hmacalgo {
struct sctp_authkey {
sctp_assoc_t sca_assoc_id;
__u16 sca_keynumber;
- __u16 sca_keylen;
+ __u16 sca_keylength;
__u8 sca_key[];
};
@@ -693,8 +694,9 @@ struct sctp_status {
* the peer requires to be received authenticated only.
*/
struct sctp_authchunks {
- sctp_assoc_t gauth_assoc_id;
- uint8_t gauth_chunks[];
+ sctp_assoc_t gauth_assoc_id;
+ __u32 gauth_number_of_chunks;
+ uint8_t gauth_chunks[];
};
/*
diff --git a/include/net/sock.h b/include/net/sock.h
index 8a7889b3581..fd987608765 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -180,6 +180,7 @@ struct sock_common {
* @sk_sndmsg_off: cached offset for sendmsg
* @sk_send_head: front of stuff to transmit
* @sk_security: used by security modules
+ * @sk_mark: generic packet mark
* @sk_write_pending: a write to stream socket waits to start
* @sk_state_change: callback to indicate change in the state of the sock
* @sk_data_ready: callback to indicate there is data to be processed
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index ac72116636c..eea7785cc75 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -508,7 +508,10 @@ struct xfrm_skb_cb {
} header;
/* Sequence number for replay protection. */
- u64 seq;
+ union {
+ u64 output;
+ __be32 input;
+ } seq;
};
#define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 3ffd6b582a9..39e1cac24bb 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -675,5 +675,6 @@ extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
struct ssp_response_iu *iu);
+struct sas_phy *sas_find_local_phy(struct domain_device *dev);
#endif /* _SASLIB_H_ */
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index dbc96ef4cc7..aab1eae2ec4 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -177,6 +177,8 @@ struct iscsi_cls_session {
struct list_head host_list;
struct iscsi_transport *transport;
spinlock_t lock;
+ struct work_struct block_work;
+ struct work_struct unblock_work;
struct work_struct scan_work;
struct work_struct unbind_work;
diff --git a/include/sound/opl3.h b/include/sound/opl3.h
index a0c5febdc4e..6ba67070783 100644
--- a/include/sound/opl3.h
+++ b/include/sound/opl3.h
@@ -370,12 +370,13 @@ int snd_opl3_hwdep_new(struct snd_opl3 * opl3, int device, int seq_device,
int snd_opl3_open(struct snd_hwdep * hw, struct file *file);
int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
unsigned int cmd, unsigned long arg);
-long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count,
- loff_t *offset);
int snd_opl3_release(struct snd_hwdep * hw, struct file *file);
void snd_opl3_reset(struct snd_opl3 * opl3);
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count,
+ loff_t *offset);
int snd_opl3_load_patch(struct snd_opl3 *opl3,
int prog, int bank, int type,
const char *name,
@@ -384,5 +385,9 @@ int snd_opl3_load_patch(struct snd_opl3 *opl3,
struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank,
int create_patch);
void snd_opl3_clear_patches(struct snd_opl3 *opl3);
+#else
+#define snd_opl3_write NULL
+static inline void snd_opl3_clear_patches(struct snd_opl3 *opl3) {}
+#endif
#endif /* __SOUND_OPL3_H */
diff --git a/init/Kconfig b/init/Kconfig
index dcef8b55011..074ac97f55e 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -366,10 +366,29 @@ config RESOURCE_COUNTERS
infrastructure that works with cgroups
depends on CGROUPS
+config CGROUP_MEM_RES_CTLR
+ bool "Memory Resource Controller for Control Groups"
+ depends on CGROUPS && RESOURCE_COUNTERS
+ help
+ Provides a memory resource controller that manages both page cache and
+ RSS memory.
+
+ Note that setting this option increases fixed memory overhead
+ associated with each page of memory in the system by 4/8 bytes
+ and also increases cache misses because struct page on many 64bit
+ systems will not fit into a single cache line anymore.
+
+ Only enable when you're ok with these trade offs and really
+ sure you need the memory resource controller.
+
config SYSFS_DEPRECATED
+ bool
+
+config SYSFS_DEPRECATED_V2
bool "Create deprecated sysfs files"
depends on SYSFS
default y
+ select SYSFS_DEPRECATED
help
This option creates deprecated symlinks such as the
"device"-link, the <subsystem>:<name>-link, and the
@@ -382,17 +401,11 @@ config SYSFS_DEPRECATED
If enabled, this option will also move any device structures
that belong to a class, back into the /sys/class hierarchy, in
- order to support older versions of udev.
-
- If you are using a distro that was released in 2006 or later,
- it should be safe to say N here.
+ order to support older versions of udev and some userspace
+ programs.
-config CGROUP_MEM_CONT
- bool "Memory controller for cgroups"
- depends on CGROUPS && RESOURCE_COUNTERS
- help
- Provides a memory controller that manages both page cache and
- RSS memory.
+ If you are using a distro with the most recent userspace
+ packages, it should be safe to say N here.
config PROC_PID_CPUSET
bool "Include legacy /proc/<pid>/cpuset file"
diff --git a/init/main.c b/init/main.c
index 8b1982082ad..fbb0167c6b8 100644
--- a/init/main.c
+++ b/init/main.c
@@ -254,7 +254,7 @@ early_param("quiet", quiet_kernel);
static int __init loglevel(char *str)
{
get_option(&str, &console_loglevel);
- return 1;
+ return 0;
}
early_param("loglevel", loglevel);
diff --git a/kernel/audit.c b/kernel/audit.c
index 2eeea9a1424..10c4930c2bb 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -170,7 +170,9 @@ void audit_panic(const char *message)
printk(KERN_ERR "audit: %s\n", message);
break;
case AUDIT_FAIL_PANIC:
- panic("audit: %s\n", message);
+ /* test audit_pid since printk is always losey, why bother? */
+ if (audit_pid)
+ panic("audit: %s\n", message);
break;
}
}
@@ -352,6 +354,7 @@ static int kauditd_thread(void *dummy)
if (err < 0) {
BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */
printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
+ audit_log_lost("auditd dissapeared\n");
audit_pid = 0;
}
} else {
@@ -1350,17 +1353,19 @@ void audit_log_end(struct audit_buffer *ab)
if (!audit_rate_check()) {
audit_log_lost("rate limit exceeded");
} else {
+ struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
if (audit_pid) {
- struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
skb_queue_tail(&audit_skb_queue, ab->skb);
ab->skb = NULL;
wake_up_interruptible(&kauditd_wait);
- } else if (printk_ratelimit()) {
- struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
- printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, ab->skb->data + NLMSG_SPACE(0));
- } else {
- audit_log_lost("printk limit exceeded\n");
+ } else if (nlh->nlmsg_type != AUDIT_EOE) {
+ if (printk_ratelimit()) {
+ printk(KERN_NOTICE "type=%d %s\n",
+ nlh->nlmsg_type,
+ ab->skb->data + NLMSG_SPACE(0));
+ } else
+ audit_log_lost("printk limit exceeded\n");
}
}
audit_buffer_free(ab);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index ac6d9b23b01..782262e4107 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1000,9 +1000,10 @@ static int audit_log_single_execve_arg(struct audit_context *context,
* for strings that are too long, we should not have created
* any.
*/
- if (unlikely((len = -1) || len > MAX_ARG_STRLEN - 1)) {
+ if (unlikely((len == -1) || len > MAX_ARG_STRLEN - 1)) {
WARN_ON(1);
send_sig(SIGKILL, current, 0);
+ return -1;
}
/* walk the whole argument looking for non-ascii chars */
@@ -1020,6 +1021,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
if (ret) {
WARN_ON(1);
send_sig(SIGKILL, current, 0);
+ return -1;
}
buf[to_send] = '\0';
has_cntl = audit_string_contains_control(buf, to_send);
@@ -1068,7 +1070,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
* so we can be sure nothing was lost.
*/
if ((i == 0) && (too_long))
- audit_log_format(*ab, "a%d_len=%ld ", arg_num,
+ audit_log_format(*ab, "a%d_len=%zu ", arg_num,
has_cntl ? 2*len : len);
/*
@@ -1083,6 +1085,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
if (ret) {
WARN_ON(1);
send_sig(SIGKILL, current, 0);
+ return -1;
}
buf[to_send] = '\0';
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 4766bb65e4d..e9c2fb01e89 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -113,9 +113,9 @@ static int root_count;
#define dummytop (&rootnode.top_cgroup)
/* This flag indicates whether tasks in the fork and exit paths should
- * take callback_mutex and check for fork/exit handlers to call. This
- * avoids us having to do extra work in the fork/exit path if none of the
- * subsystems need to be called.
+ * check for fork/exit handlers to call. This avoids us having to do
+ * extra work in the fork/exit path if none of the subsystems need to
+ * be called.
*/
static int need_forkexit_callback;
@@ -307,7 +307,6 @@ static inline void put_css_set_taskexit(struct css_set *cg)
* template: location in which to build the desired set of subsystem
* state objects for the new cgroup group
*/
-
static struct css_set *find_existing_css_set(
struct css_set *oldcg,
struct cgroup *cgrp,
@@ -320,7 +319,7 @@ static struct css_set *find_existing_css_set(
/* Built the set of subsystem state objects that we want to
* see in the new css_set */
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- if (root->subsys_bits & (1ull << i)) {
+ if (root->subsys_bits & (1UL << i)) {
/* Subsystem is in this hierarchy. So we want
* the subsystem state from the new
* cgroup */
@@ -354,7 +353,6 @@ static struct css_set *find_existing_css_set(
* and chains them on tmp through their cgrp_link_list fields. Returns 0 on
* success or a negative error
*/
-
static int allocate_cg_links(int count, struct list_head *tmp)
{
struct cg_cgroup_link *link;
@@ -396,7 +394,6 @@ static void free_cg_links(struct list_head *tmp)
* substituted into the appropriate hierarchy. Must be called with
* cgroup_mutex held
*/
-
static struct css_set *find_css_set(
struct css_set *oldcg, struct cgroup *cgrp)
{
@@ -473,7 +470,6 @@ static struct css_set *find_css_set(
/* Link this cgroup group into the list */
list_add(&res->list, &init_css_set.list);
css_set_count++;
- INIT_LIST_HEAD(&res->tasks);
write_unlock(&css_set_lock);
return res;
@@ -507,8 +503,8 @@ static struct css_set *find_css_set(
* critical pieces of code here. The exception occurs on cgroup_exit(),
* when a task in a notify_on_release cgroup exits. Then cgroup_mutex
* is taken, and if the cgroup count is zero, a usermode call made
- * to /sbin/cgroup_release_agent with the name of the cgroup (path
- * relative to the root of cgroup file system) as the argument.
+ * to the release agent with the name of the cgroup (path relative to
+ * the root of cgroup file system) as the argument.
*
* A cgroup can only be deleted if both its 'count' of using tasks
* is zero, and its list of 'children' cgroups is empty. Since all
@@ -521,7 +517,7 @@ static struct css_set *find_css_set(
*
* The need for this exception arises from the action of
* cgroup_attach_task(), which overwrites one tasks cgroup pointer with
- * another. It does so using cgroup_mutexe, however there are
+ * another. It does so using cgroup_mutex, however there are
* several performance critical places that need to reference
* task->cgroup without the expense of grabbing a system global
* mutex. Therefore except as noted below, when dereferencing or, as
@@ -537,7 +533,6 @@ static struct css_set *find_css_set(
* cgroup_lock - lock out any changes to cgroup structures
*
*/
-
void cgroup_lock(void)
{
mutex_lock(&cgroup_mutex);
@@ -548,7 +543,6 @@ void cgroup_lock(void)
*
* Undo the lock taken in a previous cgroup_lock() call.
*/
-
void cgroup_unlock(void)
{
mutex_unlock(&cgroup_mutex);
@@ -590,7 +584,6 @@ static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb)
* Call subsys's pre_destroy handler.
* This is called before css refcnt check.
*/
-
static void cgroup_call_pre_destroy(struct cgroup *cgrp)
{
struct cgroup_subsys *ss;
@@ -600,7 +593,6 @@ static void cgroup_call_pre_destroy(struct cgroup *cgrp)
return;
}
-
static void cgroup_diput(struct dentry *dentry, struct inode *inode)
{
/* is dentry a directory ? if so, kfree() associated cgroup */
@@ -696,7 +688,7 @@ static int rebind_subsystems(struct cgroupfs_root *root,
added_bits = final_bits & ~root->actual_subsys_bits;
/* Check that any added subsystems are currently free */
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- unsigned long long bit = 1ull << i;
+ unsigned long bit = 1UL << i;
struct cgroup_subsys *ss = subsys[i];
if (!(bit & added_bits))
continue;
@@ -927,7 +919,6 @@ static int cgroup_get_rootdir(struct super_block *sb)
if (!inode)
return -ENOMEM;
- inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
inode->i_op = &cgroup_dir_inode_operations;
/* directories start off with i_nlink == 2 (for "." entry) */
@@ -961,8 +952,11 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
}
root = kzalloc(sizeof(*root), GFP_KERNEL);
- if (!root)
+ if (!root) {
+ if (opts.release_agent)
+ kfree(opts.release_agent);
return -ENOMEM;
+ }
init_cgroup_root(root);
root->subsys_bits = opts.subsys_bits;
@@ -1129,8 +1123,13 @@ static inline struct cftype *__d_cft(struct dentry *dentry)
return dentry->d_fsdata;
}
-/*
- * Called with cgroup_mutex held. Writes path of cgroup into buf.
+/**
+ * cgroup_path - generate the path of a cgroup
+ * @cgrp: the cgroup in question
+ * @buf: the buffer to write the path into
+ * @buflen: the length of the buffer
+ *
+ * Called with cgroup_mutex held. Writes path of cgroup into buf.
* Returns 0 on success, -errno on error.
*/
int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
@@ -1188,11 +1187,13 @@ static void get_first_subsys(const struct cgroup *cgrp,
*subsys_id = test_ss->subsys_id;
}
-/*
- * Attach task 'tsk' to cgroup 'cgrp'
+/**
+ * cgroup_attach_task - attach task 'tsk' to cgroup 'cgrp'
+ * @cgrp: the cgroup the task is attaching to
+ * @tsk: the task to be attached
*
- * Call holding cgroup_mutex. May take task_lock of
- * the task 'pid' during call.
+ * Call holding cgroup_mutex. May take task_lock of
+ * the task 'tsk' during call.
*/
int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
{
@@ -1293,7 +1294,6 @@ static int attach_task_by_pid(struct cgroup *cgrp, char *pidbuf)
}
/* The various types of files and directories in a cgroup file system */
-
enum cgroup_filetype {
FILE_ROOT,
FILE_DIR,
@@ -1584,12 +1584,11 @@ static int cgroup_create_file(struct dentry *dentry, int mode,
}
/*
- * cgroup_create_dir - create a directory for an object.
- * cgrp: the cgroup we create the directory for.
- * It must have a valid ->parent field
- * And we are going to fill its ->dentry field.
- * dentry: dentry of the new cgroup
- * mode: mode to set on new directory.
+ * cgroup_create_dir - create a directory for an object.
+ * @cgrp: the cgroup we create the directory for. It must have a valid
+ * ->parent field. And we are going to fill its ->dentry field.
+ * @dentry: dentry of the new cgroup
+ * @mode: mode to set on new directory.
*/
static int cgroup_create_dir(struct cgroup *cgrp, struct dentry *dentry,
int mode)
@@ -1651,8 +1650,12 @@ int cgroup_add_files(struct cgroup *cgrp,
return 0;
}
-/* Count the number of tasks in a cgroup. */
-
+/**
+ * cgroup_task_count - count the number of tasks in a cgroup.
+ * @cgrp: the cgroup in question
+ *
+ * Return the number of tasks in the cgroup.
+ */
int cgroup_task_count(const struct cgroup *cgrp)
{
int count = 0;
@@ -1962,12 +1965,13 @@ static int pid_array_load(pid_t *pidarray, int npids, struct cgroup *cgrp)
}
/**
- * Build and fill cgroupstats so that taskstats can export it to user
- * space.
- *
+ * cgroupstats_build - build and fill cgroupstats
* @stats: cgroupstats to fill information into
* @dentry: A dentry entry belonging to the cgroup for which stats have
* been requested.
+ *
+ * Build and fill cgroupstats so that taskstats can export it to user
+ * space.
*/
int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry)
{
@@ -2199,14 +2203,13 @@ static void init_cgroup_css(struct cgroup_subsys_state *css,
}
/*
- * cgroup_create - create a cgroup
- * parent: cgroup that will be parent of the new cgroup.
- * name: name of the new cgroup. Will be strcpy'ed.
- * mode: mode to set on new inode
+ * cgroup_create - create a cgroup
+ * @parent: cgroup that will be parent of the new cgroup
+ * @dentry: dentry of the new cgroup
+ * @mode: mode to set on new inode
*
- * Must be called with the mutex on the parent inode held
+ * Must be called with the mutex on the parent inode held
*/
-
static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
int mode)
{
@@ -2229,7 +2232,6 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
mutex_lock(&cgroup_mutex);
- cgrp->flags = 0;
INIT_LIST_HEAD(&cgrp->sibling);
INIT_LIST_HEAD(&cgrp->children);
INIT_LIST_HEAD(&cgrp->css_sets);
@@ -2239,6 +2241,9 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
cgrp->root = parent->root;
cgrp->top_cgroup = parent->top_cgroup;
+ if (notify_on_release(parent))
+ set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
+
for_each_subsys(root, ss) {
struct cgroup_subsys_state *css = ss->create(ss, cgrp);
if (IS_ERR(css)) {
@@ -2349,13 +2354,12 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
parent = cgrp->parent;
root = cgrp->root;
sb = root->sb;
+
/*
- * Call pre_destroy handlers of subsys
+ * Call pre_destroy handlers of subsys. Notify subsystems
+ * that rmdir() request comes.
*/
cgroup_call_pre_destroy(cgrp);
- /*
- * Notify subsyses that rmdir() request comes.
- */
if (cgroup_has_css_refs(cgrp)) {
mutex_unlock(&cgroup_mutex);
@@ -2431,8 +2435,10 @@ static void cgroup_init_subsys(struct cgroup_subsys *ss)
}
/**
- * cgroup_init_early - initialize cgroups at system boot, and
- * initialize any subsystems that request early init.
+ * cgroup_init_early - cgroup initialization at system boot
+ *
+ * Initialize cgroups at system boot, and initialize any
+ * subsystems that request early init.
*/
int __init cgroup_init_early(void)
{
@@ -2474,8 +2480,10 @@ int __init cgroup_init_early(void)
}
/**
- * cgroup_init - register cgroup filesystem and /proc file, and
- * initialize any subsystems that didn't request early init.
+ * cgroup_init - cgroup initialization
+ *
+ * Register cgroup filesystem and /proc file, and initialize
+ * any subsystems that didn't request early init.
*/
int __init cgroup_init(void)
{
@@ -2618,7 +2626,7 @@ static struct file_operations proc_cgroupstats_operations = {
/**
* cgroup_fork - attach newly forked task to its parents cgroup.
- * @tsk: pointer to task_struct of forking parent process.
+ * @child: pointer to task_struct of forking parent process.
*
* Description: A task inherits its parent's cgroup at fork().
*
@@ -2642,9 +2650,12 @@ void cgroup_fork(struct task_struct *child)
}
/**
- * cgroup_fork_callbacks - called on a new task very soon before
- * adding it to the tasklist. No need to take any locks since no-one
- * can be operating on this task
+ * cgroup_fork_callbacks - run fork callbacks
+ * @child: the new task
+ *
+ * Called on a new task very soon before adding it to the
+ * tasklist. No need to take any locks since no-one can
+ * be operating on this task.
*/
void cgroup_fork_callbacks(struct task_struct *child)
{
@@ -2659,11 +2670,14 @@ void cgroup_fork_callbacks(struct task_struct *child)
}
/**
- * cgroup_post_fork - called on a new task after adding it to the
- * task list. Adds the task to the list running through its css_set
- * if necessary. Has to be after the task is visible on the task list
- * in case we race with the first call to cgroup_iter_start() - to
- * guarantee that the new task ends up on its list. */
+ * cgroup_post_fork - called on a new task after adding it to the task list
+ * @child: the task in question
+ *
+ * Adds the task to the list running through its css_set if necessary.
+ * Has to be after the task is visible on the task list in case we race
+ * with the first call to cgroup_iter_start() - to guarantee that the
+ * new task ends up on its list.
+ */
void cgroup_post_fork(struct task_struct *child)
{
if (use_task_css_set_links) {
@@ -2676,6 +2690,7 @@ void cgroup_post_fork(struct task_struct *child)
/**
* cgroup_exit - detach cgroup from exiting task
* @tsk: pointer to task_struct of exiting process
+ * @run_callback: run exit callbacks?
*
* Description: Detach cgroup from @tsk and release it.
*
@@ -2706,7 +2721,6 @@ void cgroup_post_fork(struct task_struct *child)
* top_cgroup isn't going away, and either task has PF_EXITING set,
* which wards off any cgroup_attach_task() attempts, or task is a failed
* fork, never visible to cgroup_attach_task.
- *
*/
void cgroup_exit(struct task_struct *tsk, int run_callbacks)
{
@@ -2743,9 +2757,13 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks)
}
/**
- * cgroup_clone - duplicate the current cgroup in the hierarchy
- * that the given subsystem is attached to, and move this task into
- * the new child
+ * cgroup_clone - clone the cgroup the given subsystem is attached to
+ * @tsk: the task to be moved
+ * @subsys: the given subsystem
+ *
+ * Duplicate the current cgroup in the hierarchy that the given
+ * subsystem is attached to, and move this task into the new
+ * child.
*/
int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys)
{
@@ -2858,9 +2876,12 @@ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys)
return ret;
}
-/*
- * See if "cgrp" is a descendant of the current task's cgroup in
- * the appropriate hierarchy
+/**
+ * cgroup_is_descendant - see if @cgrp is a descendant of current task's cgrp
+ * @cgrp: the cgroup in question
+ *
+ * See if @cgrp is a descendant of the current task's cgroup in
+ * the appropriate hierarchy.
*
* If we are sending in dummytop, then presumably we are creating
* the top cgroup in the subsystem.
@@ -2939,9 +2960,7 @@ void __css_put(struct cgroup_subsys_state *css)
* release agent task. We don't bother to wait because the caller of
* this routine has no use for the exit status of the release agent
* task, so no sense holding our caller up for that.
- *
*/
-
static void cgroup_release_agent(struct work_struct *work)
{
BUG_ON(work != &release_agent_work);
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 3e296ed81d4..a1b61f41422 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -322,8 +322,8 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
* Call without callback_mutex or task_lock() held. May be
* called with or without cgroup_mutex held. Thanks in part to
* 'the_top_cpuset_hack', the task's cpuset pointer will never
- * be NULL. This routine also might acquire callback_mutex and
- * current->mm->mmap_sem during call.
+ * be NULL. This routine also might acquire callback_mutex during
+ * call.
*
* Reading current->cpuset->mems_generation doesn't need task_lock
* to guard the current->cpuset derefence, because it is guarded
diff --git a/kernel/exit.c b/kernel/exit.c
index 506a957b665..53872bf993f 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -214,20 +214,19 @@ struct pid *session_of_pgrp(struct pid *pgrp)
static int will_become_orphaned_pgrp(struct pid *pgrp, struct task_struct *ignored_task)
{
struct task_struct *p;
- int ret = 1;
do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
- if (p == ignored_task
- || p->exit_state
- || is_global_init(p->real_parent))
+ if ((p == ignored_task) ||
+ (p->exit_state && thread_group_empty(p)) ||
+ is_global_init(p->real_parent))
continue;
+
if (task_pgrp(p->real_parent) != pgrp &&
- task_session(p->real_parent) == task_session(p)) {
- ret = 0;
- break;
- }
+ task_session(p->real_parent) == task_session(p))
+ return 0;
} while_each_pid_task(pgrp, PIDTYPE_PGID, p);
- return ret; /* (sighing) "Often!" */
+
+ return 1;
}
int is_current_pgrp_orphaned(void)
@@ -255,6 +254,37 @@ static int has_stopped_jobs(struct pid *pgrp)
return retval;
}
+/*
+ * Check to see if any process groups have become orphaned as
+ * a result of our exiting, and if they have any stopped jobs,
+ * send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2)
+ */
+static void
+kill_orphaned_pgrp(struct task_struct *tsk, struct task_struct *parent)
+{
+ struct pid *pgrp = task_pgrp(tsk);
+ struct task_struct *ignored_task = tsk;
+
+ if (!parent)
+ /* exit: our father is in a different pgrp than
+ * we are and we were the only connection outside.
+ */
+ parent = tsk->real_parent;
+ else
+ /* reparent: our child is in a different pgrp than
+ * we are, and it was the only connection outside.
+ */
+ ignored_task = NULL;
+
+ if (task_pgrp(parent) != pgrp &&
+ task_session(parent) == task_session(tsk) &&
+ will_become_orphaned_pgrp(pgrp, ignored_task) &&
+ has_stopped_jobs(pgrp)) {
+ __kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp);
+ __kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp);
+ }
+}
+
/**
* reparent_to_kthreadd - Reparent the calling kernel thread to kthreadd
*
@@ -635,22 +665,7 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
p->exit_signal != -1 && thread_group_empty(p))
do_notify_parent(p, p->exit_signal);
- /*
- * process group orphan check
- * Case ii: Our child is in a different pgrp
- * than we are, and it was the only connection
- * outside, so the child pgrp is now orphaned.
- */
- if ((task_pgrp(p) != task_pgrp(father)) &&
- (task_session(p) == task_session(father))) {
- struct pid *pgrp = task_pgrp(p);
-
- if (will_become_orphaned_pgrp(pgrp, NULL) &&
- has_stopped_jobs(pgrp)) {
- __kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp);
- __kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp);
- }
- }
+ kill_orphaned_pgrp(p, father);
}
/*
@@ -735,11 +750,9 @@ static void forget_original_parent(struct task_struct *father)
* Send signals to all our closest relatives so that they know
* to properly mourn us..
*/
-static void exit_notify(struct task_struct *tsk)
+static void exit_notify(struct task_struct *tsk, int group_dead)
{
int state;
- struct task_struct *t;
- struct pid *pgrp;
/*
* This does two things:
@@ -753,25 +766,8 @@ static void exit_notify(struct task_struct *tsk)
exit_task_namespaces(tsk);
write_lock_irq(&tasklist_lock);
- /*
- * Check to see if any process groups have become orphaned
- * as a result of our exiting, and if they have any stopped
- * jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2)
- *
- * Case i: Our father is in a different pgrp than we are
- * and we were the only connection outside, so our pgrp
- * is about to become orphaned.
- */
- t = tsk->real_parent;
-
- pgrp = task_pgrp(tsk);
- if ((task_pgrp(t) != pgrp) &&
- (task_session(t) == task_session(tsk)) &&
- will_become_orphaned_pgrp(pgrp, tsk) &&
- has_stopped_jobs(pgrp)) {
- __kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp);
- __kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp);
- }
+ if (group_dead)
+ kill_orphaned_pgrp(tsk->group_leader, NULL);
/* Let father know we died
*
@@ -788,8 +784,8 @@ static void exit_notify(struct task_struct *tsk)
* the same after a fork.
*/
if (tsk->exit_signal != SIGCHLD && tsk->exit_signal != -1 &&
- ( tsk->parent_exec_id != t->self_exec_id ||
- tsk->self_exec_id != tsk->parent_exec_id)
+ (tsk->parent_exec_id != tsk->real_parent->self_exec_id ||
+ tsk->self_exec_id != tsk->parent_exec_id)
&& !capable(CAP_KILL))
tsk->exit_signal = SIGCHLD;
@@ -986,7 +982,7 @@ NORET_TYPE void do_exit(long code)
module_put(tsk->binfmt->module);
proc_exit_connector(tsk);
- exit_notify(tsk);
+ exit_notify(tsk, group_dead);
#ifdef CONFIG_NUMA
mpol_free(tsk->mempolicy);
tsk->mempolicy = NULL;
@@ -1382,7 +1378,7 @@ unlock_sig:
if (!retval && infop)
retval = put_user(0, &infop->si_errno);
if (!retval && infop)
- retval = put_user(why, &infop->si_code);
+ retval = put_user((short)why, &infop->si_code);
if (!retval && infop)
retval = put_user(exit_code, &infop->si_status);
if (!retval && infop)
diff --git a/kernel/futex.c b/kernel/futex.c
index 221f2128a43..06968cd7920 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -60,6 +60,8 @@
#include "rtmutex_common.h"
+int __read_mostly futex_cmpxchg_enabled;
+
#define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8)
/*
@@ -469,6 +471,8 @@ void exit_pi_state_list(struct task_struct *curr)
struct futex_hash_bucket *hb;
union futex_key key;
+ if (!futex_cmpxchg_enabled)
+ return;
/*
* We are a ZOMBIE and nobody can enqueue itself on
* pi_state_list anymore, but we have to be careful
@@ -1870,6 +1874,8 @@ asmlinkage long
sys_set_robust_list(struct robust_list_head __user *head,
size_t len)
{
+ if (!futex_cmpxchg_enabled)
+ return -ENOSYS;
/*
* The kernel knows only one size for now:
*/
@@ -1894,6 +1900,9 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
struct robust_list_head __user *head;
unsigned long ret;
+ if (!futex_cmpxchg_enabled)
+ return -ENOSYS;
+
if (!pid)
head = current->robust_list;
else {
@@ -1997,6 +2006,9 @@ void exit_robust_list(struct task_struct *curr)
unsigned long futex_offset;
int rc;
+ if (!futex_cmpxchg_enabled)
+ return;
+
/*
* Fetch the list head (which was registered earlier, via
* sys_set_robust_list()):
@@ -2051,7 +2063,7 @@ void exit_robust_list(struct task_struct *curr)
long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
u32 __user *uaddr2, u32 val2, u32 val3)
{
- int ret;
+ int ret = -ENOSYS;
int cmd = op & FUTEX_CMD_MASK;
struct rw_semaphore *fshared = NULL;
@@ -2083,13 +2095,16 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
ret = futex_wake_op(uaddr, fshared, uaddr2, val, val2, val3);
break;
case FUTEX_LOCK_PI:
- ret = futex_lock_pi(uaddr, fshared, val, timeout, 0);
+ if (futex_cmpxchg_enabled)
+ ret = futex_lock_pi(uaddr, fshared, val, timeout, 0);
break;
case FUTEX_UNLOCK_PI:
- ret = futex_unlock_pi(uaddr, fshared);
+ if (futex_cmpxchg_enabled)
+ ret = futex_unlock_pi(uaddr, fshared);
break;
case FUTEX_TRYLOCK_PI:
- ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1);
+ if (futex_cmpxchg_enabled)
+ ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1);
break;
default:
ret = -ENOSYS;
@@ -2145,8 +2160,29 @@ static struct file_system_type futex_fs_type = {
static int __init init(void)
{
- int i = register_filesystem(&futex_fs_type);
+ u32 curval;
+ int i;
+
+ /*
+ * This will fail and we want it. Some arch implementations do
+ * runtime detection of the futex_atomic_cmpxchg_inatomic()
+ * functionality. We want to know that before we call in any
+ * of the complex code paths. Also we want to prevent
+ * registration of robust lists in that case. NULL is
+ * guaranteed to fault and we get -EFAULT on functional
+ * implementation, the non functional ones will return
+ * -ENOSYS.
+ */
+ curval = cmpxchg_futex_value_locked(NULL, 0, 0);
+ if (curval == -EFAULT)
+ futex_cmpxchg_enabled = 1;
+ for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
+ plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock);
+ spin_lock_init(&futex_queues[i].lock);
+ }
+
+ i = register_filesystem(&futex_fs_type);
if (i)
return i;
@@ -2156,10 +2192,6 @@ static int __init init(void)
return PTR_ERR(futex_mnt);
}
- for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
- plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock);
- spin_lock_init(&futex_queues[i].lock);
- }
return 0;
}
__initcall(init);
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index 7d5e4b016f3..ff90f049f8f 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -54,6 +54,9 @@ void compat_exit_robust_list(struct task_struct *curr)
compat_long_t futex_offset;
int rc;
+ if (!futex_cmpxchg_enabled)
+ return;
+
/*
* Fetch the list head (which was registered earlier, via
* sys_set_robust_list()):
@@ -115,6 +118,9 @@ asmlinkage long
compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
compat_size_t len)
{
+ if (!futex_cmpxchg_enabled)
+ return -ENOSYS;
+
if (unlikely(len != sizeof(*head)))
return -EINVAL;
@@ -130,6 +136,9 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
struct compat_robust_list_head __user *head;
unsigned long ret;
+ if (!futex_cmpxchg_enabled)
+ return -ENOSYS;
+
if (!pid)
head = current->compat_robust_list;
else {
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index cc54c627635..fdb3fbe2b0c 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -246,6 +246,17 @@ static unsigned int default_startup(unsigned int irq)
}
/*
+ * default shutdown function
+ */
+static void default_shutdown(unsigned int irq)
+{
+ struct irq_desc *desc = irq_desc + irq;
+
+ desc->chip->mask(irq);
+ desc->status |= IRQ_MASKED;
+}
+
+/*
* Fixup enable/disable function pointers
*/
void irq_chip_set_defaults(struct irq_chip *chip)
@@ -256,8 +267,15 @@ void irq_chip_set_defaults(struct irq_chip *chip)
chip->disable = default_disable;
if (!chip->startup)
chip->startup = default_startup;
+ /*
+ * We use chip->disable, when the user provided its own. When
+ * we have default_disable set for chip->disable, then we need
+ * to use default_shutdown, otherwise the irq line is not
+ * disabled on free_irq():
+ */
if (!chip->shutdown)
- chip->shutdown = chip->disable;
+ chip->shutdown = chip->disable != default_disable ?
+ chip->disable : default_shutdown;
if (!chip->name)
chip->name = chip->typename;
if (!chip->end)
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index a6b2bc831dd..088dabbf2d6 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -6,6 +6,7 @@
* This file contains spurious interrupt handling.
*/
+#include <linux/jiffies.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
@@ -179,7 +180,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
* otherwise the couter becomes a doomsday timer for otherwise
* working systems
*/
- if (jiffies - desc->last_unhandled > HZ/10)
+ if (time_after(jiffies, desc->last_unhandled + HZ/10))
desc->irqs_unhandled = 1;
else
desc->irqs_unhandled++;
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 7a86e643233..fcfb580c3af 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -498,27 +498,36 @@ static int __kprobes in_kprobes_functions(unsigned long addr)
return 0;
}
+/*
+ * If we have a symbol_name argument, look it up and add the offset field
+ * to it. This way, we can specify a relative address to a symbol.
+ */
+static kprobe_opcode_t __kprobes *kprobe_addr(struct kprobe *p)
+{
+ kprobe_opcode_t *addr = p->addr;
+ if (p->symbol_name) {
+ if (addr)
+ return NULL;
+ kprobe_lookup_name(p->symbol_name, addr);
+ }
+
+ if (!addr)
+ return NULL;
+ return (kprobe_opcode_t *)(((char *)addr) + p->offset);
+}
+
static int __kprobes __register_kprobe(struct kprobe *p,
unsigned long called_from)
{
int ret = 0;
struct kprobe *old_p;
struct module *probed_mod;
+ kprobe_opcode_t *addr;
- /*
- * If we have a symbol_name argument look it up,
- * and add it to the address. That way the addr
- * field can either be global or relative to a symbol.
- */
- if (p->symbol_name) {
- if (p->addr)
- return -EINVAL;
- kprobe_lookup_name(p->symbol_name, p->addr);
- }
-
- if (!p->addr)
+ addr = kprobe_addr(p);
+ if (!addr)
return -EINVAL;
- p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset);
+ p->addr = addr;
if (!kernel_text_address((unsigned long) p->addr) ||
in_kprobes_functions((unsigned long) p->addr))
@@ -678,8 +687,7 @@ void __kprobes unregister_jprobe(struct jprobe *jp)
unregister_kprobe(&jp->kp);
}
-#ifdef ARCH_SUPPORTS_KRETPROBES
-
+#ifdef CONFIG_KRETPROBES
/*
* This kprobe pre_handler is registered with every kretprobe. When probe
* hits it will set up the return probe.
@@ -722,12 +730,12 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
int ret = 0;
struct kretprobe_instance *inst;
int i;
- void *addr = rp->kp.addr;
+ void *addr;
if (kretprobe_blacklist_size) {
- if (addr == NULL)
- kprobe_lookup_name(rp->kp.symbol_name, addr);
- addr += rp->kp.offset;
+ addr = kprobe_addr(&rp->kp);
+ if (!addr)
+ return -EINVAL;
for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
if (kretprobe_blacklist[i].addr == addr)
@@ -769,8 +777,7 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
return ret;
}
-#else /* ARCH_SUPPORTS_KRETPROBES */
-
+#else /* CONFIG_KRETPROBES */
int __kprobes register_kretprobe(struct kretprobe *rp)
{
return -ENOSYS;
@@ -781,8 +788,7 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p,
{
return 0;
}
-
-#endif /* ARCH_SUPPORTS_KRETPROBES */
+#endif /* CONFIG_KRETPROBES */
void __kprobes unregister_kretprobe(struct kretprobe *rp)
{
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 3574379f4d6..81a4e4a3f08 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -779,6 +779,10 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
* parallel walking of the hash-list safe:
*/
list_add_tail_rcu(&class->hash_entry, hash_head);
+ /*
+ * Add it to the global list of classes:
+ */
+ list_add_tail_rcu(&class->lock_entry, &all_lock_classes);
if (verbose(class)) {
graph_unlock();
@@ -2282,10 +2286,6 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
return 0;
break;
case LOCK_USED:
- /*
- * Add it to the global list of classes:
- */
- list_add_tail_rcu(&this->class->lock_entry, &all_lock_classes);
debug_atomic_dec(&nr_unused_locks);
break;
default:
diff --git a/kernel/marker.c b/kernel/marker.c
index c4c2cd8b61f..48a4ea5afff 100644
--- a/kernel/marker.c
+++ b/kernel/marker.c
@@ -61,8 +61,8 @@ struct marker_entry {
int refcount; /* Number of times armed. 0 if disarmed. */
struct rcu_head rcu;
void *oldptr;
- char rcu_pending:1;
- char ptype:1;
+ unsigned char rcu_pending:1;
+ unsigned char ptype:1;
char name[0]; /* Contains name'\0'format'\0' */
};
@@ -698,14 +698,12 @@ int marker_probe_unregister(const char *name,
{
struct marker_entry *entry;
struct marker_probe_closure *old;
- int ret = 0;
+ int ret = -ENOENT;
mutex_lock(&markers_mutex);
entry = get_marker(name);
- if (!entry) {
- ret = -ENOENT;
+ if (!entry)
goto end;
- }
if (entry->rcu_pending)
rcu_barrier();
old = marker_entry_remove_probe(entry, probe, probe_private);
@@ -713,12 +711,15 @@ int marker_probe_unregister(const char *name,
marker_update_probes(); /* may update entry */
mutex_lock(&markers_mutex);
entry = get_marker(name);
+ if (!entry)
+ goto end;
entry->oldptr = old;
entry->rcu_pending = 1;
/* write rcu_pending before calling the RCU callback */
smp_wmb();
call_rcu(&entry->rcu, free_old_closure);
remove_marker(name); /* Ignore busy error message */
+ ret = 0;
end:
mutex_unlock(&markers_mutex);
return ret;
diff --git a/kernel/module.c b/kernel/module.c
index 92595bad381..be4807fb90e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -987,12 +987,11 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
return ret;
}
-
/*
* /sys/module/foo/sections stuff
* J. Corbet <corbet@lwn.net>
*/
-#ifdef CONFIG_KALLSYMS
+#if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS)
static ssize_t module_sect_show(struct module_attribute *mattr,
struct module *mod, char *buf)
{
@@ -1188,7 +1187,7 @@ static inline void add_notes_attrs(struct module *mod, unsigned int nsect,
static inline void remove_notes_attrs(struct module *mod)
{
}
-#endif /* CONFIG_KALLSYMS */
+#endif
#ifdef CONFIG_SYSFS
int module_add_modinfo_attrs(struct module *mod)
@@ -1231,9 +1230,7 @@ void module_remove_modinfo_attrs(struct module *mod)
}
kfree(mod->modinfo_attrs);
}
-#endif
-#ifdef CONFIG_SYSFS
int mod_sysfs_init(struct module *mod)
{
int err;
@@ -1936,8 +1933,15 @@ static struct module *load_module(void __user *umod,
/* Set up license info based on the info section */
set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
+ /*
+ * ndiswrapper is under GPL by itself, but loads proprietary modules.
+ * Don't use add_taint_module(), as it would prevent ndiswrapper from
+ * using GPL-only symbols it needs.
+ */
if (strcmp(mod->name, "ndiswrapper") == 0)
- add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+ add_taint(TAINT_PROPRIETARY_MODULE);
+
+ /* driverloader was caught wrongly pretending to be under GPL */
if (strcmp(mod->name, "driverloader") == 0)
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 859a8e59773..14a656cdc65 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -391,7 +391,7 @@ int hibernation_platform_enter(void)
goto Close;
suspend_console();
- error = device_suspend(PMSG_SUSPEND);
+ error = device_suspend(PMSG_HIBERNATE);
if (error)
goto Resume_console;
@@ -404,7 +404,7 @@ int hibernation_platform_enter(void)
goto Finish;
local_irq_disable();
- error = device_power_down(PMSG_SUSPEND);
+ error = device_power_down(PMSG_HIBERNATE);
if (!error) {
hibernation_ops->enter();
/* We should never get here */
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 7c2118f9597..f1d0b345c9b 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -75,22 +75,15 @@ void refrigerator(void)
__set_current_state(save);
}
-static void fake_signal_wake_up(struct task_struct *p, int resume)
+static void fake_signal_wake_up(struct task_struct *p)
{
unsigned long flags;
spin_lock_irqsave(&p->sighand->siglock, flags);
- signal_wake_up(p, resume);
+ signal_wake_up(p, 0);
spin_unlock_irqrestore(&p->sighand->siglock, flags);
}
-static void send_fake_signal(struct task_struct *p)
-{
- if (task_is_stopped(p))
- force_sig_specific(SIGSTOP, p);
- fake_signal_wake_up(p, task_is_stopped(p));
-}
-
static int has_mm(struct task_struct *p)
{
return (p->mm && !(p->flags & PF_BORROWED_MM));
@@ -121,7 +114,7 @@ static int freeze_task(struct task_struct *p, int with_mm_only)
if (freezing(p)) {
if (has_mm(p)) {
if (!signal_pending(p))
- fake_signal_wake_up(p, 0);
+ fake_signal_wake_up(p);
} else {
if (with_mm_only)
ret = 0;
@@ -135,7 +128,7 @@ static int freeze_task(struct task_struct *p, int with_mm_only)
} else {
if (has_mm(p)) {
set_freeze_flag(p);
- send_fake_signal(p);
+ fake_signal_wake_up(p);
} else {
if (with_mm_only) {
ret = 0;
@@ -182,15 +175,17 @@ static int try_to_freeze_tasks(int freeze_user_space)
if (frozen(p) || !freezeable(p))
continue;
- if (task_is_traced(p) && frozen(p->parent)) {
- cancel_freezing(p);
- continue;
- }
-
if (!freeze_task(p, freeze_user_space))
continue;
- if (!freezer_should_skip(p))
+ /*
+ * Now that we've done set_freeze_flag, don't
+ * perturb a task in TASK_STOPPED or TASK_TRACED.
+ * It is "frozen enough". If the task does wake
+ * up, it will immediately call try_to_freeze.
+ */
+ if (!task_is_stopped_or_traced(p) &&
+ !freezer_should_skip(p))
todo++;
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 95250d7c8d9..72a020cabb4 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -875,8 +875,8 @@ static inline void *saveable_highmem_page(unsigned long pfn) { return NULL; }
#endif /* CONFIG_HIGHMEM */
/**
- * saveable - Determine whether a non-highmem page should be included in
- * the suspend image.
+ * saveable_page - Determine whether a non-highmem page should be included
+ * in the suspend image.
*
* We should save the page if it isn't Nosave, and is not in the range
* of pages statically defined as 'unsaveable', and it isn't a part of
@@ -897,7 +897,8 @@ static struct page *saveable_page(unsigned long pfn)
if (swsusp_page_is_forbidden(page) || swsusp_page_is_free(page))
return NULL;
- if (PageReserved(page) && pfn_is_nosave(pfn))
+ if (PageReserved(page)
+ && (!kernel_page_present(page) || pfn_is_nosave(pfn)))
return NULL;
return page;
@@ -938,6 +939,25 @@ static inline void do_copy_page(long *dst, long *src)
*dst++ = *src++;
}
+
+/**
+ * safe_copy_page - check if the page we are going to copy is marked as
+ * present in the kernel page tables (this always is the case if
+ * CONFIG_DEBUG_PAGEALLOC is not set and in that case
+ * kernel_page_present() always returns 'true').
+ */
+static void safe_copy_page(void *dst, struct page *s_page)
+{
+ if (kernel_page_present(s_page)) {
+ do_copy_page(dst, page_address(s_page));
+ } else {
+ kernel_map_pages(s_page, 1, 1);
+ do_copy_page(dst, page_address(s_page));
+ kernel_map_pages(s_page, 1, 0);
+ }
+}
+
+
#ifdef CONFIG_HIGHMEM
static inline struct page *
page_is_saveable(struct zone *zone, unsigned long pfn)
@@ -946,8 +966,7 @@ page_is_saveable(struct zone *zone, unsigned long pfn)
saveable_highmem_page(pfn) : saveable_page(pfn);
}
-static inline void
-copy_data_page(unsigned long dst_pfn, unsigned long src_pfn)
+static void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn)
{
struct page *s_page, *d_page;
void *src, *dst;
@@ -961,29 +980,26 @@ copy_data_page(unsigned long dst_pfn, unsigned long src_pfn)
kunmap_atomic(src, KM_USER0);
kunmap_atomic(dst, KM_USER1);
} else {
- src = page_address(s_page);
if (PageHighMem(d_page)) {
/* Page pointed to by src may contain some kernel
* data modified by kmap_atomic()
*/
- do_copy_page(buffer, src);
+ safe_copy_page(buffer, s_page);
dst = kmap_atomic(pfn_to_page(dst_pfn), KM_USER0);
memcpy(dst, buffer, PAGE_SIZE);
kunmap_atomic(dst, KM_USER0);
} else {
- dst = page_address(d_page);
- do_copy_page(dst, src);
+ safe_copy_page(page_address(d_page), s_page);
}
}
}
#else
#define page_is_saveable(zone, pfn) saveable_page(pfn)
-static inline void
-copy_data_page(unsigned long dst_pfn, unsigned long src_pfn)
+static inline void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn)
{
- do_copy_page(page_address(pfn_to_page(dst_pfn)),
- page_address(pfn_to_page(src_pfn)));
+ safe_copy_page(page_address(pfn_to_page(dst_pfn)),
+ pfn_to_page(src_pfn));
}
#endif /* CONFIG_HIGHMEM */
diff --git a/kernel/printk.c b/kernel/printk.c
index bee36100f11..9adc2a473e6 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -666,7 +666,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
}
/* Emit the output into the temporary buffer */
printed_len += vscnprintf(printk_buf + printed_len,
- sizeof(printk_buf), fmt, args);
+ sizeof(printk_buf) - printed_len, fmt, args);
/*
* Copy the output into log_buf. If the caller didn't provide
diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c
index 987cfb7ade8..e9517014b57 100644
--- a/kernel/rcupreempt.c
+++ b/kernel/rcupreempt.c
@@ -23,6 +23,10 @@
* to Suparna Bhattacharya for pushing me completely away
* from atomic instructions on the read side.
*
+ * - Added handling of Dynamic Ticks
+ * Copyright 2007 - Paul E. Mckenney <paulmck@us.ibm.com>
+ * - Steven Rostedt <srostedt@redhat.com>
+ *
* Papers: http://www.rdrop.com/users/paulmck/RCU
*
* Design Document: http://lwn.net/Articles/253651/
@@ -409,6 +413,212 @@ static void __rcu_advance_callbacks(struct rcu_data *rdp)
}
}
+#ifdef CONFIG_NO_HZ
+
+DEFINE_PER_CPU(long, dynticks_progress_counter) = 1;
+static DEFINE_PER_CPU(long, rcu_dyntick_snapshot);
+static DEFINE_PER_CPU(int, rcu_update_flag);
+
+/**
+ * rcu_irq_enter - Called from Hard irq handlers and NMI/SMI.
+ *
+ * If the CPU was idle with dynamic ticks active, this updates the
+ * dynticks_progress_counter to let the RCU handling know that the
+ * CPU is active.
+ */
+void rcu_irq_enter(void)
+{
+ int cpu = smp_processor_id();
+
+ if (per_cpu(rcu_update_flag, cpu))
+ per_cpu(rcu_update_flag, cpu)++;
+
+ /*
+ * Only update if we are coming from a stopped ticks mode
+ * (dynticks_progress_counter is even).
+ */
+ if (!in_interrupt() &&
+ (per_cpu(dynticks_progress_counter, cpu) & 0x1) == 0) {
+ /*
+ * The following might seem like we could have a race
+ * with NMI/SMIs. But this really isn't a problem.
+ * Here we do a read/modify/write, and the race happens
+ * when an NMI/SMI comes in after the read and before
+ * the write. But NMI/SMIs will increment this counter
+ * twice before returning, so the zero bit will not
+ * be corrupted by the NMI/SMI which is the most important
+ * part.
+ *
+ * The only thing is that we would bring back the counter
+ * to a postion that it was in during the NMI/SMI.
+ * But the zero bit would be set, so the rest of the
+ * counter would again be ignored.
+ *
+ * On return from the IRQ, the counter may have the zero
+ * bit be 0 and the counter the same as the return from
+ * the NMI/SMI. If the state machine was so unlucky to
+ * see that, it still doesn't matter, since all
+ * RCU read-side critical sections on this CPU would
+ * have already completed.
+ */
+ per_cpu(dynticks_progress_counter, cpu)++;
+ /*
+ * The following memory barrier ensures that any
+ * rcu_read_lock() primitives in the irq handler
+ * are seen by other CPUs to follow the above
+ * increment to dynticks_progress_counter. This is
+ * required in order for other CPUs to correctly
+ * determine when it is safe to advance the RCU
+ * grace-period state machine.
+ */
+ smp_mb(); /* see above block comment. */
+ /*
+ * Since we can't determine the dynamic tick mode from
+ * the dynticks_progress_counter after this routine,
+ * we use a second flag to acknowledge that we came
+ * from an idle state with ticks stopped.
+ */
+ per_cpu(rcu_update_flag, cpu)++;
+ /*
+ * If we take an NMI/SMI now, they will also increment
+ * the rcu_update_flag, and will not update the
+ * dynticks_progress_counter on exit. That is for
+ * this IRQ to do.
+ */
+ }
+}
+
+/**
+ * rcu_irq_exit - Called from exiting Hard irq context.
+ *
+ * If the CPU was idle with dynamic ticks active, update the
+ * dynticks_progress_counter to put let the RCU handling be
+ * aware that the CPU is going back to idle with no ticks.
+ */
+void rcu_irq_exit(void)
+{
+ int cpu = smp_processor_id();
+
+ /*
+ * rcu_update_flag is set if we interrupted the CPU
+ * when it was idle with ticks stopped.
+ * Once this occurs, we keep track of interrupt nesting
+ * because a NMI/SMI could also come in, and we still
+ * only want the IRQ that started the increment of the
+ * dynticks_progress_counter to be the one that modifies
+ * it on exit.
+ */
+ if (per_cpu(rcu_update_flag, cpu)) {
+ if (--per_cpu(rcu_update_flag, cpu))
+ return;
+
+ /* This must match the interrupt nesting */
+ WARN_ON(in_interrupt());
+
+ /*
+ * If an NMI/SMI happens now we are still
+ * protected by the dynticks_progress_counter being odd.
+ */
+
+ /*
+ * The following memory barrier ensures that any
+ * rcu_read_unlock() primitives in the irq handler
+ * are seen by other CPUs to preceed the following
+ * increment to dynticks_progress_counter. This
+ * is required in order for other CPUs to determine
+ * when it is safe to advance the RCU grace-period
+ * state machine.
+ */
+ smp_mb(); /* see above block comment. */
+ per_cpu(dynticks_progress_counter, cpu)++;
+ WARN_ON(per_cpu(dynticks_progress_counter, cpu) & 0x1);
+ }
+}
+
+static void dyntick_save_progress_counter(int cpu)
+{
+ per_cpu(rcu_dyntick_snapshot, cpu) =
+ per_cpu(dynticks_progress_counter, cpu);
+}
+
+static inline int
+rcu_try_flip_waitack_needed(int cpu)
+{
+ long curr;
+ long snap;
+
+ curr = per_cpu(dynticks_progress_counter, cpu);
+ snap = per_cpu(rcu_dyntick_snapshot, cpu);
+ smp_mb(); /* force ordering with cpu entering/leaving dynticks. */
+
+ /*
+ * If the CPU remained in dynticks mode for the entire time
+ * and didn't take any interrupts, NMIs, SMIs, or whatever,
+ * then it cannot be in the middle of an rcu_read_lock(), so
+ * the next rcu_read_lock() it executes must use the new value
+ * of the counter. So we can safely pretend that this CPU
+ * already acknowledged the counter.
+ */
+
+ if ((curr == snap) && ((curr & 0x1) == 0))
+ return 0;
+
+ /*
+ * If the CPU passed through or entered a dynticks idle phase with
+ * no active irq handlers, then, as above, we can safely pretend
+ * that this CPU already acknowledged the counter.
+ */
+
+ if ((curr - snap) > 2 || (snap & 0x1) == 0)
+ return 0;
+
+ /* We need this CPU to explicitly acknowledge the counter flip. */
+
+ return 1;
+}
+
+static inline int
+rcu_try_flip_waitmb_needed(int cpu)
+{
+ long curr;
+ long snap;
+
+ curr = per_cpu(dynticks_progress_counter, cpu);
+ snap = per_cpu(rcu_dyntick_snapshot, cpu);
+ smp_mb(); /* force ordering with cpu entering/leaving dynticks. */
+
+ /*
+ * If the CPU remained in dynticks mode for the entire time
+ * and didn't take any interrupts, NMIs, SMIs, or whatever,
+ * then it cannot have executed an RCU read-side critical section
+ * during that time, so there is no need for it to execute a
+ * memory barrier.
+ */
+
+ if ((curr == snap) && ((curr & 0x1) == 0))
+ return 0;
+
+ /*
+ * If the CPU either entered or exited an outermost interrupt,
+ * SMI, NMI, or whatever handler, then we know that it executed
+ * a memory barrier when doing so. So we don't need another one.
+ */
+ if (curr != snap)
+ return 0;
+
+ /* We need the CPU to execute a memory barrier. */
+
+ return 1;
+}
+
+#else /* !CONFIG_NO_HZ */
+
+# define dyntick_save_progress_counter(cpu) do { } while (0)
+# define rcu_try_flip_waitack_needed(cpu) (1)
+# define rcu_try_flip_waitmb_needed(cpu) (1)
+
+#endif /* CONFIG_NO_HZ */
+
/*
* Get here when RCU is idle. Decide whether we need to
* move out of idle state, and return non-zero if so.
@@ -447,8 +657,10 @@ rcu_try_flip_idle(void)
/* Now ask each CPU for acknowledgement of the flip. */
- for_each_cpu_mask(cpu, rcu_cpu_online_map)
+ for_each_cpu_mask(cpu, rcu_cpu_online_map) {
per_cpu(rcu_flip_flag, cpu) = rcu_flipped;
+ dyntick_save_progress_counter(cpu);
+ }
return 1;
}
@@ -464,7 +676,8 @@ rcu_try_flip_waitack(void)
RCU_TRACE_ME(rcupreempt_trace_try_flip_a1);
for_each_cpu_mask(cpu, rcu_cpu_online_map)
- if (per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) {
+ if (rcu_try_flip_waitack_needed(cpu) &&
+ per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) {
RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1);
return 0;
}
@@ -509,8 +722,10 @@ rcu_try_flip_waitzero(void)
smp_mb(); /* ^^^^^^^^^^^^ */
/* Call for a memory barrier from each CPU. */
- for_each_cpu_mask(cpu, rcu_cpu_online_map)
+ for_each_cpu_mask(cpu, rcu_cpu_online_map) {
per_cpu(rcu_mb_flag, cpu) = rcu_mb_needed;
+ dyntick_save_progress_counter(cpu);
+ }
RCU_TRACE_ME(rcupreempt_trace_try_flip_z2);
return 1;
@@ -528,7 +743,8 @@ rcu_try_flip_waitmb(void)
RCU_TRACE_ME(rcupreempt_trace_try_flip_m1);
for_each_cpu_mask(cpu, rcu_cpu_online_map)
- if (per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) {
+ if (rcu_try_flip_waitmb_needed(cpu) &&
+ per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) {
RCU_TRACE_ME(rcupreempt_trace_try_flip_me1);
return 0;
}
@@ -702,8 +918,9 @@ void rcu_offline_cpu(int cpu)
* fix.
*/
+ local_irq_save(flags);
rdp = RCU_DATA_ME();
- spin_lock_irqsave(&rdp->lock, flags);
+ spin_lock(&rdp->lock);
*rdp->nexttail = list;
if (list)
rdp->nexttail = tail;
@@ -735,9 +952,11 @@ static void rcu_process_callbacks(struct softirq_action *unused)
{
unsigned long flags;
struct rcu_head *next, *list;
- struct rcu_data *rdp = RCU_DATA_ME();
+ struct rcu_data *rdp;
- spin_lock_irqsave(&rdp->lock, flags);
+ local_irq_save(flags);
+ rdp = RCU_DATA_ME();
+ spin_lock(&rdp->lock);
list = rdp->donelist;
if (list == NULL) {
spin_unlock_irqrestore(&rdp->lock, flags);
diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index 16cbec2d5d6..efbfc0fc232 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -113,6 +113,7 @@ ssize_t res_counter_write(struct res_counter *counter, int member,
ret = -EINVAL;
+ strstrip(buf);
if (write_strategy) {
if (write_strategy(buf, &tmp)) {
goto out_free;
diff --git a/kernel/sched.c b/kernel/sched.c
index f28f19e65b5..b02e4fc2564 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -174,41 +174,6 @@ struct task_group {
struct sched_entity **se;
/* runqueue "owned" by this group on each cpu */
struct cfs_rq **cfs_rq;
-
- /*
- * shares assigned to a task group governs how much of cpu bandwidth
- * is allocated to the group. The more shares a group has, the more is
- * the cpu bandwidth allocated to it.
- *
- * For ex, lets say that there are three task groups, A, B and C which
- * have been assigned shares 1000, 2000 and 3000 respectively. Then,
- * cpu bandwidth allocated by the scheduler to task groups A, B and C
- * should be:
- *
- * Bw(A) = 1000/(1000+2000+3000) * 100 = 16.66%
- * Bw(B) = 2000/(1000+2000+3000) * 100 = 33.33%
- * Bw(C) = 3000/(1000+2000+3000) * 100 = 50%
- *
- * The weight assigned to a task group's schedulable entities on every
- * cpu (task_group.se[a_cpu]->load.weight) is derived from the task
- * group's shares. For ex: lets say that task group A has been
- * assigned shares of 1000 and there are two CPUs in a system. Then,
- *
- * tg_A->se[0]->load.weight = tg_A->se[1]->load.weight = 1000;
- *
- * Note: It's not necessary that each of a task's group schedulable
- * entity have the same weight on all CPUs. If the group
- * has 2 of its tasks on CPU0 and 1 task on CPU1, then a
- * better distribution of weight could be:
- *
- * tg_A->se[0]->load.weight = 2/3 * 2000 = 1333
- * tg_A->se[1]->load.weight = 1/2 * 2000 = 667
- *
- * rebalance_shares() is responsible for distributing the shares of a
- * task groups like this among the group's schedulable entities across
- * cpus.
- *
- */
unsigned long shares;
#endif
@@ -250,22 +215,12 @@ static DEFINE_SPINLOCK(task_group_lock);
static DEFINE_MUTEX(doms_cur_mutex);
#ifdef CONFIG_FAIR_GROUP_SCHED
-#ifdef CONFIG_SMP
-/* kernel thread that runs rebalance_shares() periodically */
-static struct task_struct *lb_monitor_task;
-static int load_balance_monitor(void *unused);
-#endif
-
-static void set_se_shares(struct sched_entity *se, unsigned long shares);
-
#ifdef CONFIG_USER_SCHED
# define INIT_TASK_GROUP_LOAD (2*NICE_0_LOAD)
#else
# define INIT_TASK_GROUP_LOAD NICE_0_LOAD
#endif
-#define MIN_GROUP_SHARES 2
-
static int init_task_group_load = INIT_TASK_GROUP_LOAD;
#endif
@@ -668,6 +623,8 @@ const_debug unsigned int sysctl_sched_nr_migrate = 32;
*/
unsigned int sysctl_sched_rt_period = 1000000;
+static __read_mostly int scheduler_running;
+
/*
* part of the period that we allow rt tasks to run in us.
* default: 0.95s
@@ -689,14 +646,16 @@ unsigned long long cpu_clock(int cpu)
unsigned long flags;
struct rq *rq;
- local_irq_save(flags);
- rq = cpu_rq(cpu);
/*
* Only call sched_clock() if the scheduler has already been
* initialized (some code might call cpu_clock() very early):
*/
- if (rq->idle)
- update_rq_clock(rq);
+ if (unlikely(!scheduler_running))
+ return 0;
+
+ local_irq_save(flags);
+ rq = cpu_rq(cpu);
+ update_rq_clock(rq);
now = rq->clock;
local_irq_restore(flags);
@@ -1241,16 +1200,6 @@ static void cpuacct_charge(struct task_struct *tsk, u64 cputime);
static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {}
#endif
-static inline void inc_cpu_load(struct rq *rq, unsigned long load)
-{
- update_load_add(&rq->load, load);
-}
-
-static inline void dec_cpu_load(struct rq *rq, unsigned long load)
-{
- update_load_sub(&rq->load, load);
-}
-
#ifdef CONFIG_SMP
static unsigned long source_load(int cpu, int type);
static unsigned long target_load(int cpu, int type);
@@ -1268,14 +1217,26 @@ static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd);
#define sched_class_highest (&rt_sched_class)
-static void inc_nr_running(struct rq *rq)
+static inline void inc_load(struct rq *rq, const struct task_struct *p)
+{
+ update_load_add(&rq->load, p->se.load.weight);
+}
+
+static inline void dec_load(struct rq *rq, const struct task_struct *p)
+{
+ update_load_sub(&rq->load, p->se.load.weight);
+}
+
+static void inc_nr_running(struct task_struct *p, struct rq *rq)
{
rq->nr_running++;
+ inc_load(rq, p);
}
-static void dec_nr_running(struct rq *rq)
+static void dec_nr_running(struct task_struct *p, struct rq *rq)
{
rq->nr_running--;
+ dec_load(rq, p);
}
static void set_load_weight(struct task_struct *p)
@@ -1367,7 +1328,7 @@ static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
rq->nr_uninterruptible--;
enqueue_task(rq, p, wakeup);
- inc_nr_running(rq);
+ inc_nr_running(p, rq);
}
/*
@@ -1379,7 +1340,7 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep)
rq->nr_uninterruptible++;
dequeue_task(rq, p, sleep);
- dec_nr_running(rq);
+ dec_nr_running(p, rq);
}
/**
@@ -1831,6 +1792,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
long old_state;
struct rq *rq;
+ smp_wmb();
rq = task_rq_lock(p, &flags);
old_state = p->state;
if (!(old_state & state))
@@ -2018,7 +1980,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
* management (if any):
*/
p->sched_class->task_new(rq, p);
- inc_nr_running(rq);
+ inc_nr_running(p, rq);
}
check_preempt_curr(rq, p);
#ifdef CONFIG_SMP
@@ -3766,7 +3728,7 @@ void scheduler_tick(void)
#if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT)
-void add_preempt_count(int val)
+void __kprobes add_preempt_count(int val)
{
/*
* Underflow?
@@ -3782,7 +3744,7 @@ void add_preempt_count(int val)
}
EXPORT_SYMBOL(add_preempt_count);
-void sub_preempt_count(int val)
+void __kprobes sub_preempt_count(int val)
{
/*
* Underflow?
@@ -3884,7 +3846,7 @@ pick_next_task(struct rq *rq, struct task_struct *prev)
asmlinkage void __sched schedule(void)
{
struct task_struct *prev, *next;
- long *switch_count;
+ unsigned long *switch_count;
struct rq *rq;
int cpu;
@@ -4357,8 +4319,10 @@ void set_user_nice(struct task_struct *p, long nice)
goto out_unlock;
}
on_rq = p->se.on_rq;
- if (on_rq)
+ if (on_rq) {
dequeue_task(rq, p, 0);
+ dec_load(rq, p);
+ }
p->static_prio = NICE_TO_PRIO(nice);
set_load_weight(p);
@@ -4368,6 +4332,7 @@ void set_user_nice(struct task_struct *p, long nice)
if (on_rq) {
enqueue_task(rq, p, 0);
+ inc_load(rq, p);
/*
* If the task increased its priority or is running and
* lowered its priority, then reschedule its CPU:
@@ -4457,7 +4422,7 @@ int task_nice(const struct task_struct *p)
{
return TASK_NICE(p);
}
-EXPORT_SYMBOL_GPL(task_nice);
+EXPORT_SYMBOL(task_nice);
/**
* idle_cpu - is a given cpu idle currently?
@@ -5135,7 +5100,7 @@ long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval)
time_slice = 0;
if (p->policy == SCHED_RR) {
time_slice = DEF_TIMESLICE;
- } else {
+ } else if (p->policy != SCHED_FIFO) {
struct sched_entity *se = &p->se;
unsigned long flags;
struct rq *rq;
@@ -5848,6 +5813,13 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
/* Must be high prio: stop_machine expects to yield to it. */
rq = task_rq_lock(p, &flags);
__setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
+
+ /* Update our root-domain */
+ if (rq->rd) {
+ BUG_ON(!cpu_isset(cpu, rq->rd->span));
+ cpu_set(cpu, rq->rd->online);
+ }
+
task_rq_unlock(rq, &flags);
cpu_rq(cpu)->migration_thread = p;
break;
@@ -5856,15 +5828,6 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
case CPU_ONLINE_FROZEN:
/* Strictly unnecessary, as first user will wake it. */
wake_up_process(cpu_rq(cpu)->migration_thread);
-
- /* Update our root-domain */
- rq = cpu_rq(cpu);
- spin_lock_irqsave(&rq->lock, flags);
- if (rq->rd) {
- BUG_ON(!cpu_isset(cpu, rq->rd->span));
- cpu_set(cpu, rq->rd->online);
- }
- spin_unlock_irqrestore(&rq->lock, flags);
break;
#ifdef CONFIG_HOTPLUG_CPU
@@ -6140,8 +6103,6 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd)
rq->rd = rd;
cpu_set(rq->cpu, rd->span);
- if (cpu_isset(rq->cpu, cpu_online_map))
- cpu_set(rq->cpu, rd->online);
for (class = sched_class_highest; class; class = class->next) {
if (class->join_domain)
@@ -7082,21 +7043,6 @@ void __init sched_init_smp(void)
if (set_cpus_allowed(current, non_isolated_cpus) < 0)
BUG();
sched_init_granularity();
-
-#ifdef CONFIG_FAIR_GROUP_SCHED
- if (nr_cpu_ids == 1)
- return;
-
- lb_monitor_task = kthread_create(load_balance_monitor, NULL,
- "group_balance");
- if (!IS_ERR(lb_monitor_task)) {
- lb_monitor_task->flags |= PF_NOFREEZE;
- wake_up_process(lb_monitor_task);
- } else {
- printk(KERN_ERR "Could not create load balance monitor thread"
- "(error = %ld) \n", PTR_ERR(lb_monitor_task));
- }
-#endif
}
#else
void __init sched_init_smp(void)
@@ -7283,6 +7229,8 @@ void __init sched_init(void)
* During early bootup we pretend to be a normal task:
*/
current->sched_class = &fair_sched_class;
+
+ scheduler_running = 1;
}
#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
@@ -7417,157 +7365,6 @@ void set_curr_task(int cpu, struct task_struct *p)
#ifdef CONFIG_GROUP_SCHED
-#if defined CONFIG_FAIR_GROUP_SCHED && defined CONFIG_SMP
-/*
- * distribute shares of all task groups among their schedulable entities,
- * to reflect load distribution across cpus.
- */
-static int rebalance_shares(struct sched_domain *sd, int this_cpu)
-{
- struct cfs_rq *cfs_rq;
- struct rq *rq = cpu_rq(this_cpu);
- cpumask_t sdspan = sd->span;
- int balanced = 1;
-
- /* Walk thr' all the task groups that we have */
- for_each_leaf_cfs_rq(rq, cfs_rq) {
- int i;
- unsigned long total_load = 0, total_shares;
- struct task_group *tg = cfs_rq->tg;
-
- /* Gather total task load of this group across cpus */
- for_each_cpu_mask(i, sdspan)
- total_load += tg->cfs_rq[i]->load.weight;
-
- /* Nothing to do if this group has no load */
- if (!total_load)
- continue;
-
- /*
- * tg->shares represents the number of cpu shares the task group
- * is eligible to hold on a single cpu. On N cpus, it is
- * eligible to hold (N * tg->shares) number of cpu shares.
- */
- total_shares = tg->shares * cpus_weight(sdspan);
-
- /*
- * redistribute total_shares across cpus as per the task load
- * distribution.
- */
- for_each_cpu_mask(i, sdspan) {
- unsigned long local_load, local_shares;
-
- local_load = tg->cfs_rq[i]->load.weight;
- local_shares = (local_load * total_shares) / total_load;
- if (!local_shares)
- local_shares = MIN_GROUP_SHARES;
- if (local_shares == tg->se[i]->load.weight)
- continue;
-
- spin_lock_irq(&cpu_rq(i)->lock);
- set_se_shares(tg->se[i], local_shares);
- spin_unlock_irq(&cpu_rq(i)->lock);
- balanced = 0;
- }
- }
-
- return balanced;
-}
-
-/*
- * How frequently should we rebalance_shares() across cpus?
- *
- * The more frequently we rebalance shares, the more accurate is the fairness
- * of cpu bandwidth distribution between task groups. However higher frequency
- * also implies increased scheduling overhead.
- *
- * sysctl_sched_min_bal_int_shares represents the minimum interval between
- * consecutive calls to rebalance_shares() in the same sched domain.
- *
- * sysctl_sched_max_bal_int_shares represents the maximum interval between
- * consecutive calls to rebalance_shares() in the same sched domain.
- *
- * These settings allows for the appropriate trade-off between accuracy of
- * fairness and the associated overhead.
- *
- */
-
-/* default: 8ms, units: milliseconds */
-const_debug unsigned int sysctl_sched_min_bal_int_shares = 8;
-
-/* default: 128ms, units: milliseconds */
-const_debug unsigned int sysctl_sched_max_bal_int_shares = 128;
-
-/* kernel thread that runs rebalance_shares() periodically */
-static int load_balance_monitor(void *unused)
-{
- unsigned int timeout = sysctl_sched_min_bal_int_shares;
- struct sched_param schedparm;
- int ret;
-
- /*
- * We don't want this thread's execution to be limited by the shares
- * assigned to default group (init_task_group). Hence make it run
- * as a SCHED_RR RT task at the lowest priority.
- */
- schedparm.sched_priority = 1;
- ret = sched_setscheduler(current, SCHED_RR, &schedparm);
- if (ret)
- printk(KERN_ERR "Couldn't set SCHED_RR policy for load balance"
- " monitor thread (error = %d) \n", ret);
-
- while (!kthread_should_stop()) {
- int i, cpu, balanced = 1;
-
- /* Prevent cpus going down or coming up */
- get_online_cpus();
- /* lockout changes to doms_cur[] array */
- lock_doms_cur();
- /*
- * Enter a rcu read-side critical section to safely walk rq->sd
- * chain on various cpus and to walk task group list
- * (rq->leaf_cfs_rq_list) in rebalance_shares().
- */
- rcu_read_lock();
-
- for (i = 0; i < ndoms_cur; i++) {
- cpumask_t cpumap = doms_cur[i];
- struct sched_domain *sd = NULL, *sd_prev = NULL;
-
- cpu = first_cpu(cpumap);
-
- /* Find the highest domain at which to balance shares */
- for_each_domain(cpu, sd) {
- if (!(sd->flags & SD_LOAD_BALANCE))
- continue;
- sd_prev = sd;
- }
-
- sd = sd_prev;
- /* sd == NULL? No load balance reqd in this domain */
- if (!sd)
- continue;
-
- balanced &= rebalance_shares(sd, cpu);
- }
-
- rcu_read_unlock();
-
- unlock_doms_cur();
- put_online_cpus();
-
- if (!balanced)
- timeout = sysctl_sched_min_bal_int_shares;
- else if (timeout < sysctl_sched_max_bal_int_shares)
- timeout *= 2;
-
- msleep_interruptible(timeout);
- }
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
#ifdef CONFIG_FAIR_GROUP_SCHED
static void free_fair_sched_group(struct task_group *tg)
{
@@ -7824,6 +7621,11 @@ void sched_move_task(struct task_struct *tsk)
set_task_rq(tsk, task_cpu(tsk));
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ if (tsk->sched_class->moved_group)
+ tsk->sched_class->moved_group(tsk);
+#endif
+
if (on_rq) {
if (unlikely(running))
tsk->sched_class->set_curr_task(rq);
@@ -7834,29 +7636,25 @@ void sched_move_task(struct task_struct *tsk)
}
#ifdef CONFIG_FAIR_GROUP_SCHED
-/* rq->lock to be locked by caller */
static void set_se_shares(struct sched_entity *se, unsigned long shares)
{
struct cfs_rq *cfs_rq = se->cfs_rq;
struct rq *rq = cfs_rq->rq;
int on_rq;
- if (!shares)
- shares = MIN_GROUP_SHARES;
+ spin_lock_irq(&rq->lock);
on_rq = se->on_rq;
- if (on_rq) {
+ if (on_rq)
dequeue_entity(cfs_rq, se, 0);
- dec_cpu_load(rq, se->load.weight);
- }
se->load.weight = shares;
se->load.inv_weight = div64_64((1ULL<<32), shares);
- if (on_rq) {
+ if (on_rq)
enqueue_entity(cfs_rq, se, 0);
- inc_cpu_load(rq, se->load.weight);
- }
+
+ spin_unlock_irq(&rq->lock);
}
static DEFINE_MUTEX(shares_mutex);
@@ -7866,18 +7664,18 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares)
int i;
unsigned long flags;
+ /*
+ * A weight of 0 or 1 can cause arithmetics problems.
+ * (The default weight is 1024 - so there's no practical
+ * limitation from this.)
+ */
+ if (shares < 2)
+ shares = 2;
+
mutex_lock(&shares_mutex);
if (tg->shares == shares)
goto done;
- if (shares < MIN_GROUP_SHARES)
- shares = MIN_GROUP_SHARES;
-
- /*
- * Prevent any load balance activity (rebalance_shares,
- * load_balance_fair) from referring to this group first,
- * by taking it off the rq->leaf_cfs_rq_list on each cpu.
- */
spin_lock_irqsave(&task_group_lock, flags);
for_each_possible_cpu(i)
unregister_fair_sched_group(tg, i);
@@ -7891,11 +7689,8 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares)
* w/o tripping rebalance_share or load_balance_fair.
*/
tg->shares = shares;
- for_each_possible_cpu(i) {
- spin_lock_irq(&cpu_rq(i)->lock);
+ for_each_possible_cpu(i)
set_se_shares(tg->se[i], shares);
- spin_unlock_irq(&cpu_rq(i)->lock);
- }
/*
* Enable load balance activity on this group, by inserting it back on
@@ -7927,9 +7722,7 @@ static unsigned long to_ratio(u64 period, u64 runtime)
if (runtime == RUNTIME_INF)
return 1ULL << 16;
- runtime *= (1ULL << 16);
- div64_64(runtime, period);
- return runtime;
+ return div64_64(runtime << 16, period);
}
static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
@@ -7953,25 +7746,40 @@ static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
return total + to_ratio(period, runtime) < global_ratio;
}
+/* Must be called with tasklist_lock held */
+static inline int tg_has_rt_tasks(struct task_group *tg)
+{
+ struct task_struct *g, *p;
+ do_each_thread(g, p) {
+ if (rt_task(p) && rt_rq_of_se(&p->rt)->tg == tg)
+ return 1;
+ } while_each_thread(g, p);
+ return 0;
+}
+
int sched_group_set_rt_runtime(struct task_group *tg, long rt_runtime_us)
{
u64 rt_runtime, rt_period;
int err = 0;
- rt_period = sysctl_sched_rt_period * NSEC_PER_USEC;
+ rt_period = (u64)sysctl_sched_rt_period * NSEC_PER_USEC;
rt_runtime = (u64)rt_runtime_us * NSEC_PER_USEC;
if (rt_runtime_us == -1)
- rt_runtime = rt_period;
+ rt_runtime = RUNTIME_INF;
mutex_lock(&rt_constraints_mutex);
+ read_lock(&tasklist_lock);
+ if (rt_runtime_us == 0 && tg_has_rt_tasks(tg)) {
+ err = -EBUSY;
+ goto unlock;
+ }
if (!__rt_schedulable(tg, rt_period, rt_runtime)) {
err = -EINVAL;
goto unlock;
}
- if (rt_runtime_us == -1)
- rt_runtime = RUNTIME_INF;
tg->rt_runtime = rt_runtime;
unlock:
+ read_unlock(&tasklist_lock);
mutex_unlock(&rt_constraints_mutex);
return err;
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 6c091d6e159..e2a53051561 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -202,17 +202,12 @@ static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq)
static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
{
- struct rb_node **link = &cfs_rq->tasks_timeline.rb_node;
- struct sched_entity *se = NULL;
- struct rb_node *parent;
+ struct rb_node *last = rb_last(&cfs_rq->tasks_timeline);
- while (*link) {
- parent = *link;
- se = rb_entry(parent, struct sched_entity, run_node);
- link = &parent->rb_right;
- }
+ if (!last)
+ return NULL;
- return se;
+ return rb_entry(last, struct sched_entity, run_node);
}
/**************************************************************
@@ -732,8 +727,6 @@ static inline struct sched_entity *parent_entity(struct sched_entity *se)
return se->parent;
}
-#define GROUP_IMBALANCE_PCT 20
-
#else /* CONFIG_FAIR_GROUP_SCHED */
#define for_each_sched_entity(se) \
@@ -824,26 +817,15 @@ hrtick_start_fair(struct rq *rq, struct task_struct *p)
static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
{
struct cfs_rq *cfs_rq;
- struct sched_entity *se = &p->se,
- *topse = NULL; /* Highest schedulable entity */
- int incload = 1;
+ struct sched_entity *se = &p->se;
for_each_sched_entity(se) {
- topse = se;
- if (se->on_rq) {
- incload = 0;
+ if (se->on_rq)
break;
- }
cfs_rq = cfs_rq_of(se);
enqueue_entity(cfs_rq, se, wakeup);
wakeup = 1;
}
- /* Increment cpu load if we just enqueued the first task of a group on
- * 'rq->cpu'. 'topse' represents the group to which task 'p' belongs
- * at the highest grouping level.
- */
- if (incload)
- inc_cpu_load(rq, topse->load.weight);
hrtick_start_fair(rq, rq->curr);
}
@@ -856,28 +838,16 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep)
{
struct cfs_rq *cfs_rq;
- struct sched_entity *se = &p->se,
- *topse = NULL; /* Highest schedulable entity */
- int decload = 1;
+ struct sched_entity *se = &p->se;
for_each_sched_entity(se) {
- topse = se;
cfs_rq = cfs_rq_of(se);
dequeue_entity(cfs_rq, se, sleep);
/* Don't dequeue parent if it has other entities besides us */
- if (cfs_rq->load.weight) {
- if (parent_entity(se))
- decload = 0;
+ if (cfs_rq->load.weight)
break;
- }
sleep = 1;
}
- /* Decrement cpu load if we just dequeued the last task of a group on
- * 'rq->cpu'. 'topse' represents the group to which task 'p' belongs
- * at the highest grouping level.
- */
- if (decload)
- dec_cpu_load(rq, topse->load.weight);
hrtick_start_fair(rq, rq->curr);
}
@@ -1191,6 +1161,25 @@ static struct task_struct *load_balance_next_fair(void *arg)
return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr);
}
+#ifdef CONFIG_FAIR_GROUP_SCHED
+static int cfs_rq_best_prio(struct cfs_rq *cfs_rq)
+{
+ struct sched_entity *curr;
+ struct task_struct *p;
+
+ if (!cfs_rq->nr_running || !first_fair(cfs_rq))
+ return MAX_PRIO;
+
+ curr = cfs_rq->curr;
+ if (!curr)
+ curr = __pick_next_entity(cfs_rq);
+
+ p = task_of(curr);
+
+ return p->prio;
+}
+#endif
+
static unsigned long
load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
unsigned long max_load_move,
@@ -1200,45 +1189,28 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
struct cfs_rq *busy_cfs_rq;
long rem_load_move = max_load_move;
struct rq_iterator cfs_rq_iterator;
- unsigned long load_moved;
cfs_rq_iterator.start = load_balance_start_fair;
cfs_rq_iterator.next = load_balance_next_fair;
for_each_leaf_cfs_rq(busiest, busy_cfs_rq) {
#ifdef CONFIG_FAIR_GROUP_SCHED
- struct cfs_rq *this_cfs_rq = busy_cfs_rq->tg->cfs_rq[this_cpu];
- unsigned long maxload, task_load, group_weight;
- unsigned long thisload, per_task_load;
- struct sched_entity *se = busy_cfs_rq->tg->se[busiest->cpu];
-
- task_load = busy_cfs_rq->load.weight;
- group_weight = se->load.weight;
+ struct cfs_rq *this_cfs_rq;
+ long imbalance;
+ unsigned long maxload;
- /*
- * 'group_weight' is contributed by tasks of total weight
- * 'task_load'. To move 'rem_load_move' worth of weight only,
- * we need to move a maximum task load of:
- *
- * maxload = (remload / group_weight) * task_load;
- */
- maxload = (rem_load_move * task_load) / group_weight;
+ this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu);
- if (!maxload || !task_load)
+ imbalance = busy_cfs_rq->load.weight - this_cfs_rq->load.weight;
+ /* Don't pull if this_cfs_rq has more load than busy_cfs_rq */
+ if (imbalance <= 0)
continue;
- per_task_load = task_load / busy_cfs_rq->nr_running;
- /*
- * balance_tasks will try to forcibly move atleast one task if
- * possible (because of SCHED_LOAD_SCALE_FUZZ). Avoid that if
- * maxload is less than GROUP_IMBALANCE_FUZZ% the per_task_load.
- */
- if (100 * maxload < GROUP_IMBALANCE_PCT * per_task_load)
- continue;
+ /* Don't pull more than imbalance/2 */
+ imbalance /= 2;
+ maxload = min(rem_load_move, imbalance);
- /* Disable priority-based load balance */
- *this_best_prio = 0;
- thisload = this_cfs_rq->load.weight;
+ *this_best_prio = cfs_rq_best_prio(this_cfs_rq);
#else
# define maxload rem_load_move
#endif
@@ -1247,33 +1219,11 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
* load_balance_[start|next]_fair iterators
*/
cfs_rq_iterator.arg = busy_cfs_rq;
- load_moved = balance_tasks(this_rq, this_cpu, busiest,
+ rem_load_move -= balance_tasks(this_rq, this_cpu, busiest,
maxload, sd, idle, all_pinned,
this_best_prio,
&cfs_rq_iterator);
-#ifdef CONFIG_FAIR_GROUP_SCHED
- /*
- * load_moved holds the task load that was moved. The
- * effective (group) weight moved would be:
- * load_moved_eff = load_moved/task_load * group_weight;
- */
- load_moved = (group_weight * load_moved) / task_load;
-
- /* Adjust shares on both cpus to reflect load_moved */
- group_weight -= load_moved;
- set_se_shares(se, group_weight);
-
- se = busy_cfs_rq->tg->se[this_cpu];
- if (!thisload)
- group_weight = load_moved;
- else
- group_weight = se->load.weight + load_moved;
- set_se_shares(se, group_weight);
-#endif
-
- rem_load_move -= load_moved;
-
if (rem_load_move <= 0)
break;
}
@@ -1403,6 +1353,16 @@ static void set_curr_task_fair(struct rq *rq)
set_next_entity(cfs_rq_of(se), se);
}
+#ifdef CONFIG_FAIR_GROUP_SCHED
+static void moved_group_fair(struct task_struct *p)
+{
+ struct cfs_rq *cfs_rq = task_cfs_rq(p);
+
+ update_curr(cfs_rq);
+ place_entity(cfs_rq, &p->se, 1);
+}
+#endif
+
/*
* All the scheduling class methods:
*/
@@ -1431,6 +1391,10 @@ static const struct sched_class fair_sched_class = {
.prio_changed = prio_changed_fair,
.switched_to = switched_to_fair,
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ .moved_group = moved_group_fair,
+#endif
};
#ifdef CONFIG_SCHED_DEBUG
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index f54792b175b..0a6d2e51642 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -393,8 +393,6 @@ static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup)
*/
for_each_sched_rt_entity(rt_se)
enqueue_rt_entity(rt_se);
-
- inc_cpu_load(rq, p->se.load.weight);
}
static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
@@ -414,8 +412,6 @@ static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
if (rt_rq && rt_rq->rt_nr_running)
enqueue_rt_entity(rt_se);
}
-
- dec_cpu_load(rq, p->se.load.weight);
}
/*
@@ -1111,9 +1107,11 @@ static void prio_changed_rt(struct rq *rq, struct task_struct *p,
pull_rt_task(rq);
/*
* If there's a higher priority task waiting to run
- * then reschedule.
+ * then reschedule. Note, the above pull_rt_task
+ * can release the rq lock and p could migrate.
+ * Only reschedule if p is still on the same runqueue.
*/
- if (p->prio > rq->rt.highest_prio)
+ if (p->prio > rq->rt.highest_prio && rq->curr == p)
resched_task(p);
#else
/* For UP simply resched on drop of prio */
diff --git a/kernel/signal.c b/kernel/signal.c
index 84917fe507f..6af1210092c 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1623,7 +1623,6 @@ static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info)
/* Let the debugger run. */
__set_current_state(TASK_TRACED);
spin_unlock_irq(&current->sighand->siglock);
- try_to_freeze();
read_lock(&tasklist_lock);
if (!unlikely(killed) && may_ptrace_stop()) {
do_notify_parent_cldstop(current, CLD_TRAPPED);
@@ -1641,6 +1640,13 @@ static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info)
}
/*
+ * While in TASK_TRACED, we were considered "frozen enough".
+ * Now that we woke up, it's crucial if we're supposed to be
+ * frozen that we freeze now before running anything substantial.
+ */
+ try_to_freeze();
+
+ /*
* We are back. Now reacquire the siglock before touching
* last_siginfo, so that we are sure to have synchronized with
* any signal-sending on another CPU that wants to examine it.
@@ -1757,9 +1763,15 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
sigset_t *mask = &current->blocked;
int signr = 0;
+relock:
+ /*
+ * We'll jump back here after any time we were stopped in TASK_STOPPED.
+ * While in TASK_STOPPED, we were considered "frozen enough".
+ * Now that we woke up, it's crucial if we're supposed to be
+ * frozen that we freeze now before running anything substantial.
+ */
try_to_freeze();
-relock:
spin_lock_irq(&current->sighand->siglock);
for (;;) {
struct k_sigaction *ka;
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 5b3aea5f471..31e9f2a4792 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -313,6 +313,7 @@ void irq_exit(void)
/* Make sure that timer wheel updates are propagated */
if (!in_interrupt() && idle_cpu(smp_processor_id()) && !need_resched())
tick_nohz_stop_sched_tick();
+ rcu_irq_exit();
#endif
preempt_enable_no_resched();
}
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 7c2da88db4e..01b6522fd92 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -216,26 +216,27 @@ static int watchdog(void *__bind_cpu)
/* initialize timestamp */
touch_softlockup_watchdog();
+ set_current_state(TASK_INTERRUPTIBLE);
/*
* Run briefly once per second to reset the softlockup timestamp.
* If this gets delayed for more than 60 seconds then the
* debug-printout triggers in softlockup_tick().
*/
while (!kthread_should_stop()) {
- set_current_state(TASK_INTERRUPTIBLE);
touch_softlockup_watchdog();
schedule();
if (kthread_should_stop())
break;
- if (this_cpu != check_cpu)
- continue;
-
- if (sysctl_hung_task_timeout_secs)
- check_hung_uninterruptible_tasks(this_cpu);
+ if (this_cpu == check_cpu) {
+ if (sysctl_hung_task_timeout_secs)
+ check_hung_uninterruptible_tasks(this_cpu);
+ }
+ set_current_state(TASK_INTERRUPTIBLE);
}
+ __set_current_state(TASK_RUNNING);
return 0;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 8b7e9541179..b2a2d6889ba 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -311,24 +311,6 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec,
},
-#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP)
- {
- .ctl_name = CTL_UNNUMBERED,
- .procname = "sched_min_bal_int_shares",
- .data = &sysctl_sched_min_bal_int_shares,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
- {
- .ctl_name = CTL_UNNUMBERED,
- .procname = "sched_max_bal_int_shares",
- .data = &sysctl_sched_max_bal_int_shares,
- .maxlen = sizeof(unsigned int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
-#endif
#endif
{
.ctl_name = CTL_UNNUMBERED,
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index fa9bb73dbdb..2968298f8f3 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -282,6 +282,7 @@ void tick_nohz_stop_sched_tick(void)
ts->idle_tick = ts->sched_timer.expires;
ts->tick_stopped = 1;
ts->idle_jiffies = last_jiffies;
+ rcu_enter_nohz();
}
/*
@@ -375,6 +376,8 @@ void tick_nohz_restart_sched_tick(void)
return;
}
+ rcu_exit_nohz();
+
/* Update jiffies first */
select_nohz_load_balancer(0);
now = ktime_get();
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index d3d94c1a0fd..67fe8fc21fb 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -65,9 +65,9 @@ print_timer(struct seq_file *m, struct hrtimer *timer, int idx, u64 now)
SEQ_printf(m, ", %s/%d", tmp, timer->start_pid);
#endif
SEQ_printf(m, "\n");
- SEQ_printf(m, " # expires at %Lu nsecs [in %Lu nsecs]\n",
+ SEQ_printf(m, " # expires at %Lu nsecs [in %Ld nsecs]\n",
(unsigned long long)ktime_to_ns(timer->expires),
- (unsigned long long)(ktime_to_ns(timer->expires) - now));
+ (long long)(ktime_to_ns(timer->expires) - now));
}
static void
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index a370fe828a7..0796c1a090c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -82,6 +82,9 @@ config HEADERS_CHECK
config DEBUG_SECTION_MISMATCH
bool "Enable full Section mismatch analysis"
depends on UNDEFINED
+ # This option is on purpose disabled for now.
+ # It will be enabled when we are down to a resonable number
+ # of section mismatch warnings (< 10 for an allyesconfig build)
help
The section mismatch analysis checks if there are illegal
references from one section to another section.
@@ -524,6 +527,7 @@ config LKDTM
tristate "Linux Kernel Dump Test Tool Module"
depends on DEBUG_KERNEL
depends on KPROBES
+ depends on BLOCK
default n
help
This module enables testing of the different dumping mechanisms by
diff --git a/lib/iommu-helper.c b/lib/iommu-helper.c
index 495575a59ca..a3b8d4c3f77 100644
--- a/lib/iommu-helper.c
+++ b/lib/iommu-helper.c
@@ -40,10 +40,12 @@ static inline void set_bit_area(unsigned long *map, unsigned long i,
}
}
-static inline int is_span_boundary(unsigned int index, unsigned int nr,
- unsigned long shift,
- unsigned long boundary_size)
+int iommu_is_span_boundary(unsigned int index, unsigned int nr,
+ unsigned long shift,
+ unsigned long boundary_size)
{
+ BUG_ON(!is_power_of_2(boundary_size));
+
shift = (shift + index) & (boundary_size - 1);
return shift + nr > boundary_size;
}
@@ -57,7 +59,7 @@ unsigned long iommu_area_alloc(unsigned long *map, unsigned long size,
again:
index = find_next_zero_area(map, size, start, nr, align_mask);
if (index != -1) {
- if (is_span_boundary(index, nr, shift, boundary_size)) {
+ if (iommu_is_span_boundary(index, nr, shift, boundary_size)) {
/* we could do more effectively */
start = index + 1;
goto again;
diff --git a/lib/kobject.c b/lib/kobject.c
index d784daeb857..0d03252f87a 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -153,6 +153,10 @@ static void kobject_init_internal(struct kobject *kobj)
return;
kref_init(&kobj->kref);
INIT_LIST_HEAD(&kobj->entry);
+ kobj->state_in_sysfs = 0;
+ kobj->state_add_uevent_sent = 0;
+ kobj->state_remove_uevent_sent = 0;
+ kobj->state_initialized = 1;
}
@@ -289,13 +293,8 @@ void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
dump_stack();
}
- kref_init(&kobj->kref);
- INIT_LIST_HEAD(&kobj->entry);
+ kobject_init_internal(kobj);
kobj->ktype = ktype;
- kobj->state_in_sysfs = 0;
- kobj->state_add_uevent_sent = 0;
- kobj->state_remove_uevent_sent = 0;
- kobj->state_initialized = 1;
return;
error:
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index fd987b17bda..6021757a449 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -234,7 +234,7 @@ int strict_strto##type(const char *cp, unsigned int base, valtype *res) \
int ret; \
if (*cp == '-') { \
ret = strict_strtou##type(cp+1, base, res); \
- if (ret != 0) \
+ if (!ret) \
*res = -(*res); \
} else \
ret = strict_strtou##type(cp, base, res); \
diff --git a/mm/Makefile b/mm/Makefile
index 9f117bab532..a5b0dd93427 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -32,5 +32,5 @@ obj-$(CONFIG_FS_XIP) += filemap_xip.o
obj-$(CONFIG_MIGRATION) += migrate.o
obj-$(CONFIG_SMP) += allocpercpu.o
obj-$(CONFIG_QUICKLIST) += quicklist.o
-obj-$(CONFIG_CGROUP_MEM_CONT) += memcontrol.o
+obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o
diff --git a/mm/allocpercpu.c b/mm/allocpercpu.c
index 7e58322b713..b0012e27fea 100644
--- a/mm/allocpercpu.c
+++ b/mm/allocpercpu.c
@@ -6,6 +6,10 @@
#include <linux/mm.h>
#include <linux/module.h>
+#ifndef cache_line_size
+#define cache_line_size() L1_CACHE_BYTES
+#endif
+
/**
* percpu_depopulate - depopulate per-cpu data for given cpu
* @__pdata: per-cpu data to depopulate
@@ -52,6 +56,11 @@ void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu)
struct percpu_data *pdata = __percpu_disguise(__pdata);
int node = cpu_to_node(cpu);
+ /*
+ * We should make sure each CPU gets private memory.
+ */
+ size = roundup(size, cache_line_size());
+
BUG_ON(pdata->ptrs[cpu]);
if (node_online(node))
pdata->ptrs[cpu] = kmalloc_node(size, gfp|__GFP_ZERO, node);
@@ -98,7 +107,11 @@ EXPORT_SYMBOL_GPL(__percpu_populate_mask);
*/
void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask)
{
- void *pdata = kzalloc(nr_cpu_ids * sizeof(void *), gfp);
+ /*
+ * We allocate whole cache lines to avoid false sharing
+ */
+ size_t sz = roundup(nr_cpu_ids * sizeof(void *), cache_line_size());
+ void *pdata = kzalloc(sz, gfp);
void *__pdata = __percpu_disguise(pdata);
if (unlikely(!pdata))
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index cb1b3a7ecdf..dcacc811e70 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -71,7 +71,25 @@ static void enqueue_huge_page(struct page *page)
free_huge_pages_node[nid]++;
}
-static struct page *dequeue_huge_page(struct vm_area_struct *vma,
+static struct page *dequeue_huge_page(void)
+{
+ int nid;
+ struct page *page = NULL;
+
+ for (nid = 0; nid < MAX_NUMNODES; ++nid) {
+ if (!list_empty(&hugepage_freelists[nid])) {
+ page = list_entry(hugepage_freelists[nid].next,
+ struct page, lru);
+ list_del(&page->lru);
+ free_huge_pages--;
+ free_huge_pages_node[nid]--;
+ break;
+ }
+ }
+ return page;
+}
+
+static struct page *dequeue_huge_page_vma(struct vm_area_struct *vma,
unsigned long address)
{
int nid;
@@ -120,6 +138,7 @@ static void free_huge_page(struct page *page)
struct address_space *mapping;
mapping = (struct address_space *) page_private(page);
+ set_page_private(page, 0);
BUG_ON(page_count(page));
INIT_LIST_HEAD(&page->lru);
@@ -134,7 +153,6 @@ static void free_huge_page(struct page *page)
spin_unlock(&hugetlb_lock);
if (mapping)
hugetlb_put_quota(mapping, 1);
- set_page_private(page, 0);
}
/*
@@ -296,8 +314,10 @@ static int gather_surplus_pages(int delta)
int needed, allocated;
needed = (resv_huge_pages + delta) - free_huge_pages;
- if (needed <= 0)
+ if (needed <= 0) {
+ resv_huge_pages += delta;
return 0;
+ }
allocated = 0;
INIT_LIST_HEAD(&surplus_list);
@@ -335,9 +355,12 @@ retry:
* The surplus_list now contains _at_least_ the number of extra pages
* needed to accomodate the reservation. Add the appropriate number
* of pages to the hugetlb pool and free the extras back to the buddy
- * allocator.
+ * allocator. Commit the entire reservation here to prevent another
+ * process from stealing the pages as they are added to the pool but
+ * before they are reserved.
*/
needed += allocated;
+ resv_huge_pages += delta;
ret = 0;
free:
list_for_each_entry_safe(page, tmp, &surplus_list, lru) {
@@ -371,6 +394,9 @@ static void return_unused_surplus_pages(unsigned long unused_resv_pages)
struct page *page;
unsigned long nr_pages;
+ /* Uncommit the reservation */
+ resv_huge_pages -= unused_resv_pages;
+
nr_pages = min(unused_resv_pages, surplus_huge_pages);
while (nr_pages) {
@@ -402,7 +428,7 @@ static struct page *alloc_huge_page_shared(struct vm_area_struct *vma,
struct page *page;
spin_lock(&hugetlb_lock);
- page = dequeue_huge_page(vma, addr);
+ page = dequeue_huge_page_vma(vma, addr);
spin_unlock(&hugetlb_lock);
return page ? page : ERR_PTR(-VM_FAULT_OOM);
}
@@ -417,7 +443,7 @@ static struct page *alloc_huge_page_private(struct vm_area_struct *vma,
spin_lock(&hugetlb_lock);
if (free_huge_pages > resv_huge_pages)
- page = dequeue_huge_page(vma, addr);
+ page = dequeue_huge_page_vma(vma, addr);
spin_unlock(&hugetlb_lock);
if (!page) {
page = alloc_buddy_huge_page(vma, addr);
@@ -570,7 +596,7 @@ static unsigned long set_max_huge_pages(unsigned long count)
min_count = max(count, min_count);
try_to_free_low(min_count);
while (min_count < persistent_huge_pages) {
- struct page *page = dequeue_huge_page(NULL, 0);
+ struct page *page = dequeue_huge_page();
if (!page)
break;
update_and_free_page(page);
@@ -1205,12 +1231,13 @@ static int hugetlb_acct_memory(long delta)
if (gather_surplus_pages(delta) < 0)
goto out;
- if (delta > cpuset_mems_nr(free_huge_pages_node))
+ if (delta > cpuset_mems_nr(free_huge_pages_node)) {
+ return_unused_surplus_pages(delta);
goto out;
+ }
}
ret = 0;
- resv_huge_pages += delta;
if (delta < 0)
return_unused_surplus_pages((unsigned long) -delta);
diff --git a/mm/internal.h b/mm/internal.h
index 5a9a6200e03..789727309f4 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -47,4 +47,17 @@ static inline unsigned long page_order(struct page *page)
VM_BUG_ON(!PageBuddy(page));
return page_private(page);
}
+
+/*
+ * FLATMEM and DISCONTIGMEM configurations use alloc_bootmem_node,
+ * so all functions starting at paging_init should be marked __init
+ * in those cases. SPARSEMEM, however, allows for memory hotplug,
+ * and alloc_bootmem_node is not used.
+ */
+#ifdef CONFIG_SPARSEMEM
+#define __paginginit __meminit
+#else
+#define __paginginit __init
+#endif
+
#endif
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6bded84c20c..8b9f6cae938 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -137,14 +137,21 @@ struct mem_cgroup {
*/
struct mem_cgroup_stat stat;
};
+static struct mem_cgroup init_mem_cgroup;
/*
* We use the lower bit of the page->page_cgroup pointer as a bit spin
- * lock. We need to ensure that page->page_cgroup is atleast two
- * byte aligned (based on comments from Nick Piggin)
+ * lock. We need to ensure that page->page_cgroup is at least two
+ * byte aligned (based on comments from Nick Piggin). But since
+ * bit_spin_lock doesn't actually set that lock bit in a non-debug
+ * uniprocessor kernel, we should avoid setting it here too.
*/
#define PAGE_CGROUP_LOCK_BIT 0x0
-#define PAGE_CGROUP_LOCK (1 << PAGE_CGROUP_LOCK_BIT)
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+#define PAGE_CGROUP_LOCK (1 << PAGE_CGROUP_LOCK_BIT)
+#else
+#define PAGE_CGROUP_LOCK 0x0
+#endif
/*
* A page_cgroup page is associated with every page descriptor. The
@@ -154,37 +161,27 @@ struct page_cgroup {
struct list_head lru; /* per cgroup LRU list */
struct page *page;
struct mem_cgroup *mem_cgroup;
- atomic_t ref_cnt; /* Helpful when pages move b/w */
- /* mapped and cached states */
- int flags;
+ int ref_cnt; /* cached, mapped, migrating */
+ int flags;
};
#define PAGE_CGROUP_FLAG_CACHE (0x1) /* charged as cache */
#define PAGE_CGROUP_FLAG_ACTIVE (0x2) /* page is active in this cgroup */
-static inline int page_cgroup_nid(struct page_cgroup *pc)
+static int page_cgroup_nid(struct page_cgroup *pc)
{
return page_to_nid(pc->page);
}
-static inline enum zone_type page_cgroup_zid(struct page_cgroup *pc)
+static enum zone_type page_cgroup_zid(struct page_cgroup *pc)
{
return page_zonenum(pc->page);
}
-enum {
- MEM_CGROUP_TYPE_UNSPEC = 0,
- MEM_CGROUP_TYPE_MAPPED,
- MEM_CGROUP_TYPE_CACHED,
- MEM_CGROUP_TYPE_ALL,
- MEM_CGROUP_TYPE_MAX,
-};
-
enum charge_type {
MEM_CGROUP_CHARGE_TYPE_CACHE = 0,
MEM_CGROUP_CHARGE_TYPE_MAPPED,
};
-
/*
* Always modified under lru lock. Then, not necessary to preempt_disable()
*/
@@ -193,23 +190,21 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, int flags,
{
int val = (charge)? 1 : -1;
struct mem_cgroup_stat *stat = &mem->stat;
- VM_BUG_ON(!irqs_disabled());
+ VM_BUG_ON(!irqs_disabled());
if (flags & PAGE_CGROUP_FLAG_CACHE)
- __mem_cgroup_stat_add_safe(stat,
- MEM_CGROUP_STAT_CACHE, val);
+ __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_CACHE, val);
else
__mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_RSS, val);
}
-static inline struct mem_cgroup_per_zone *
+static struct mem_cgroup_per_zone *
mem_cgroup_zoneinfo(struct mem_cgroup *mem, int nid, int zid)
{
- BUG_ON(!mem->info.nodeinfo[nid]);
return &mem->info.nodeinfo[nid]->zoneinfo[zid];
}
-static inline struct mem_cgroup_per_zone *
+static struct mem_cgroup_per_zone *
page_cgroup_zoneinfo(struct page_cgroup *pc)
{
struct mem_cgroup *mem = pc->mem_cgroup;
@@ -234,18 +229,14 @@ static unsigned long mem_cgroup_get_all_zonestat(struct mem_cgroup *mem,
return total;
}
-static struct mem_cgroup init_mem_cgroup;
-
-static inline
-struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont)
+static struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont)
{
return container_of(cgroup_subsys_state(cont,
mem_cgroup_subsys_id), struct mem_cgroup,
css);
}
-static inline
-struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p)
+static struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p)
{
return container_of(task_subsys_state(p, mem_cgroup_subsys_id),
struct mem_cgroup, css);
@@ -267,81 +258,33 @@ void mm_free_cgroup(struct mm_struct *mm)
static inline int page_cgroup_locked(struct page *page)
{
- return bit_spin_is_locked(PAGE_CGROUP_LOCK_BIT,
- &page->page_cgroup);
+ return bit_spin_is_locked(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup);
}
-void page_assign_page_cgroup(struct page *page, struct page_cgroup *pc)
+static void page_assign_page_cgroup(struct page *page, struct page_cgroup *pc)
{
- int locked;
-
- /*
- * While resetting the page_cgroup we might not hold the
- * page_cgroup lock. free_hot_cold_page() is an example
- * of such a scenario
- */
- if (pc)
- VM_BUG_ON(!page_cgroup_locked(page));
- locked = (page->page_cgroup & PAGE_CGROUP_LOCK);
- page->page_cgroup = ((unsigned long)pc | locked);
+ VM_BUG_ON(!page_cgroup_locked(page));
+ page->page_cgroup = ((unsigned long)pc | PAGE_CGROUP_LOCK);
}
struct page_cgroup *page_get_page_cgroup(struct page *page)
{
- return (struct page_cgroup *)
- (page->page_cgroup & ~PAGE_CGROUP_LOCK);
+ return (struct page_cgroup *) (page->page_cgroup & ~PAGE_CGROUP_LOCK);
}
-static void __always_inline lock_page_cgroup(struct page *page)
+static void lock_page_cgroup(struct page *page)
{
bit_spin_lock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup);
- VM_BUG_ON(!page_cgroup_locked(page));
-}
-
-static void __always_inline unlock_page_cgroup(struct page *page)
-{
- bit_spin_unlock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup);
}
-/*
- * Tie new page_cgroup to struct page under lock_page_cgroup()
- * This can fail if the page has been tied to a page_cgroup.
- * If success, returns 0.
- */
-static int page_cgroup_assign_new_page_cgroup(struct page *page,
- struct page_cgroup *pc)
+static int try_lock_page_cgroup(struct page *page)
{
- int ret = 0;
-
- lock_page_cgroup(page);
- if (!page_get_page_cgroup(page))
- page_assign_page_cgroup(page, pc);
- else /* A page is tied to other pc. */
- ret = 1;
- unlock_page_cgroup(page);
- return ret;
+ return bit_spin_trylock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup);
}
-/*
- * Clear page->page_cgroup member under lock_page_cgroup().
- * If given "pc" value is different from one page->page_cgroup,
- * page->cgroup is not cleared.
- * Returns a value of page->page_cgroup at lock taken.
- * A can can detect failure of clearing by following
- * clear_page_cgroup(page, pc) == pc
- */
-
-static struct page_cgroup *clear_page_cgroup(struct page *page,
- struct page_cgroup *pc)
+static void unlock_page_cgroup(struct page *page)
{
- struct page_cgroup *ret;
- /* lock and clear */
- lock_page_cgroup(page);
- ret = page_get_page_cgroup(page);
- if (likely(ret == pc))
- page_assign_page_cgroup(page, NULL);
- unlock_page_cgroup(page);
- return ret;
+ bit_spin_unlock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup);
}
static void __mem_cgroup_remove_list(struct page_cgroup *pc)
@@ -399,7 +342,7 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem)
int ret;
task_lock(task);
- ret = task->mm && vm_match_cgroup(task->mm, mem);
+ ret = task->mm && mm_match_cgroup(task->mm, mem);
task_unlock(task);
return ret;
}
@@ -407,18 +350,30 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem)
/*
* This routine assumes that the appropriate zone's lru lock is already held
*/
-void mem_cgroup_move_lists(struct page_cgroup *pc, bool active)
+void mem_cgroup_move_lists(struct page *page, bool active)
{
+ struct page_cgroup *pc;
struct mem_cgroup_per_zone *mz;
unsigned long flags;
- if (!pc)
+ /*
+ * We cannot lock_page_cgroup while holding zone's lru_lock,
+ * because other holders of lock_page_cgroup can be interrupted
+ * with an attempt to rotate_reclaimable_page. But we cannot
+ * safely get to page_cgroup without it, so just try_lock it:
+ * mem_cgroup_isolate_pages allows for page left on wrong list.
+ */
+ if (!try_lock_page_cgroup(page))
return;
- mz = page_cgroup_zoneinfo(pc);
- spin_lock_irqsave(&mz->lru_lock, flags);
- __mem_cgroup_move_lists(pc, active);
- spin_unlock_irqrestore(&mz->lru_lock, flags);
+ pc = page_get_page_cgroup(page);
+ if (pc) {
+ mz = page_cgroup_zoneinfo(pc);
+ spin_lock_irqsave(&mz->lru_lock, flags);
+ __mem_cgroup_move_lists(pc, active);
+ spin_unlock_irqrestore(&mz->lru_lock, flags);
+ }
+ unlock_page_cgroup(page);
}
/*
@@ -437,6 +392,7 @@ int mem_cgroup_calc_mapped_ratio(struct mem_cgroup *mem)
rss = (long)mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_RSS);
return (int)((rss * 100L) / total);
}
+
/*
* This function is called from vmscan.c. In page reclaiming loop. balance
* between active and inactive list is calculated. For memory controller
@@ -500,7 +456,6 @@ long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem,
struct mem_cgroup_per_zone *mz = mem_cgroup_zoneinfo(mem, nid, zid);
nr_inactive = MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_INACTIVE);
-
return (nr_inactive >> priority);
}
@@ -534,7 +489,6 @@ unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
if (scan >= nr_to_scan)
break;
page = pc->page;
- VM_BUG_ON(!pc);
if (unlikely(!PageLRU(page)))
continue;
@@ -587,26 +541,21 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
* with it
*/
retry:
- if (page) {
- lock_page_cgroup(page);
- pc = page_get_page_cgroup(page);
- /*
- * The page_cgroup exists and
- * the page has already been accounted.
- */
- if (pc) {
- if (unlikely(!atomic_inc_not_zero(&pc->ref_cnt))) {
- /* this page is under being uncharged ? */
- unlock_page_cgroup(page);
- cpu_relax();
- goto retry;
- } else {
- unlock_page_cgroup(page);
- goto done;
- }
- }
+ lock_page_cgroup(page);
+ pc = page_get_page_cgroup(page);
+ /*
+ * The page_cgroup exists and
+ * the page has already been accounted.
+ */
+ if (pc) {
+ VM_BUG_ON(pc->page != page);
+ VM_BUG_ON(pc->ref_cnt <= 0);
+
+ pc->ref_cnt++;
unlock_page_cgroup(page);
+ goto done;
}
+ unlock_page_cgroup(page);
pc = kzalloc(sizeof(struct page_cgroup), gfp_mask);
if (pc == NULL)
@@ -624,16 +573,11 @@ retry:
rcu_read_lock();
mem = rcu_dereference(mm->mem_cgroup);
/*
- * For every charge from the cgroup, increment reference
- * count
+ * For every charge from the cgroup, increment reference count
*/
css_get(&mem->css);
rcu_read_unlock();
- /*
- * If we created the page_cgroup, we should free it on exceeding
- * the cgroup limit.
- */
while (res_counter_charge(&mem->res, PAGE_SIZE)) {
if (!(gfp_mask & __GFP_WAIT))
goto out;
@@ -642,12 +586,12 @@ retry:
continue;
/*
- * try_to_free_mem_cgroup_pages() might not give us a full
- * picture of reclaim. Some pages are reclaimed and might be
- * moved to swap cache or just unmapped from the cgroup.
- * Check the limit again to see if the reclaim reduced the
- * current usage of the cgroup before giving up
- */
+ * try_to_free_mem_cgroup_pages() might not give us a full
+ * picture of reclaim. Some pages are reclaimed and might be
+ * moved to swap cache or just unmapped from the cgroup.
+ * Check the limit again to see if the reclaim reduced the
+ * current usage of the cgroup before giving up
+ */
if (res_counter_check_under_limit(&mem->res))
continue;
@@ -658,14 +602,16 @@ retry:
congestion_wait(WRITE, HZ/10);
}
- atomic_set(&pc->ref_cnt, 1);
+ pc->ref_cnt = 1;
pc->mem_cgroup = mem;
pc->page = page;
pc->flags = PAGE_CGROUP_FLAG_ACTIVE;
if (ctype == MEM_CGROUP_CHARGE_TYPE_CACHE)
pc->flags |= PAGE_CGROUP_FLAG_CACHE;
- if (!page || page_cgroup_assign_new_page_cgroup(page, pc)) {
+ lock_page_cgroup(page);
+ if (page_get_page_cgroup(page)) {
+ unlock_page_cgroup(page);
/*
* Another charge has been added to this page already.
* We take lock_page_cgroup(page) again and read
@@ -674,17 +620,16 @@ retry:
res_counter_uncharge(&mem->res, PAGE_SIZE);
css_put(&mem->css);
kfree(pc);
- if (!page)
- goto done;
goto retry;
}
+ page_assign_page_cgroup(page, pc);
mz = page_cgroup_zoneinfo(pc);
spin_lock_irqsave(&mz->lru_lock, flags);
- /* Update statistics vector */
__mem_cgroup_add_list(pc);
spin_unlock_irqrestore(&mz->lru_lock, flags);
+ unlock_page_cgroup(page);
done:
return 0;
out:
@@ -694,70 +639,61 @@ err:
return -ENOMEM;
}
-int mem_cgroup_charge(struct page *page, struct mm_struct *mm,
- gfp_t gfp_mask)
+int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask)
{
return mem_cgroup_charge_common(page, mm, gfp_mask,
- MEM_CGROUP_CHARGE_TYPE_MAPPED);
+ MEM_CGROUP_CHARGE_TYPE_MAPPED);
}
-/*
- * See if the cached pages should be charged at all?
- */
int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
gfp_t gfp_mask)
{
- int ret = 0;
if (!mm)
mm = &init_mm;
-
- ret = mem_cgroup_charge_common(page, mm, gfp_mask,
+ return mem_cgroup_charge_common(page, mm, gfp_mask,
MEM_CGROUP_CHARGE_TYPE_CACHE);
- return ret;
}
/*
* Uncharging is always a welcome operation, we never complain, simply
- * uncharge. This routine should be called with lock_page_cgroup held
+ * uncharge.
*/
-void mem_cgroup_uncharge(struct page_cgroup *pc)
+void mem_cgroup_uncharge_page(struct page *page)
{
+ struct page_cgroup *pc;
struct mem_cgroup *mem;
struct mem_cgroup_per_zone *mz;
- struct page *page;
unsigned long flags;
/*
* Check if our page_cgroup is valid
*/
+ lock_page_cgroup(page);
+ pc = page_get_page_cgroup(page);
if (!pc)
- return;
+ goto unlock;
- if (atomic_dec_and_test(&pc->ref_cnt)) {
- page = pc->page;
+ VM_BUG_ON(pc->page != page);
+ VM_BUG_ON(pc->ref_cnt <= 0);
+
+ if (--(pc->ref_cnt) == 0) {
mz = page_cgroup_zoneinfo(pc);
- /*
- * get page->cgroup and clear it under lock.
- * force_empty can drop page->cgroup without checking refcnt.
- */
+ spin_lock_irqsave(&mz->lru_lock, flags);
+ __mem_cgroup_remove_list(pc);
+ spin_unlock_irqrestore(&mz->lru_lock, flags);
+
+ page_assign_page_cgroup(page, NULL);
unlock_page_cgroup(page);
- if (clear_page_cgroup(page, pc) == pc) {
- mem = pc->mem_cgroup;
- css_put(&mem->css);
- res_counter_uncharge(&mem->res, PAGE_SIZE);
- spin_lock_irqsave(&mz->lru_lock, flags);
- __mem_cgroup_remove_list(pc);
- spin_unlock_irqrestore(&mz->lru_lock, flags);
- kfree(pc);
- }
- lock_page_cgroup(page);
+
+ mem = pc->mem_cgroup;
+ res_counter_uncharge(&mem->res, PAGE_SIZE);
+ css_put(&mem->css);
+
+ kfree(pc);
+ return;
}
-}
-void mem_cgroup_uncharge_page(struct page *page)
-{
- lock_page_cgroup(page);
- mem_cgroup_uncharge(page_get_page_cgroup(page));
+unlock:
unlock_page_cgroup(page);
}
@@ -765,63 +701,59 @@ void mem_cgroup_uncharge_page(struct page *page)
* Returns non-zero if a page (under migration) has valid page_cgroup member.
* Refcnt of page_cgroup is incremented.
*/
-
int mem_cgroup_prepare_migration(struct page *page)
{
struct page_cgroup *pc;
- int ret = 0;
+
lock_page_cgroup(page);
pc = page_get_page_cgroup(page);
- if (pc && atomic_inc_not_zero(&pc->ref_cnt))
- ret = 1;
+ if (pc)
+ pc->ref_cnt++;
unlock_page_cgroup(page);
- return ret;
+ return pc != NULL;
}
void mem_cgroup_end_migration(struct page *page)
{
- struct page_cgroup *pc;
-
- lock_page_cgroup(page);
- pc = page_get_page_cgroup(page);
- mem_cgroup_uncharge(pc);
- unlock_page_cgroup(page);
+ mem_cgroup_uncharge_page(page);
}
+
/*
- * We know both *page* and *newpage* are now not-on-LRU and Pg_locked.
+ * We know both *page* and *newpage* are now not-on-LRU and PG_locked.
* And no race with uncharge() routines because page_cgroup for *page*
* has extra one reference by mem_cgroup_prepare_migration.
*/
-
void mem_cgroup_page_migration(struct page *page, struct page *newpage)
{
struct page_cgroup *pc;
- struct mem_cgroup *mem;
- unsigned long flags;
struct mem_cgroup_per_zone *mz;
-retry:
+ unsigned long flags;
+
+ lock_page_cgroup(page);
pc = page_get_page_cgroup(page);
- if (!pc)
+ if (!pc) {
+ unlock_page_cgroup(page);
return;
- mem = pc->mem_cgroup;
+ }
+
mz = page_cgroup_zoneinfo(pc);
- if (clear_page_cgroup(page, pc) != pc)
- goto retry;
spin_lock_irqsave(&mz->lru_lock, flags);
-
__mem_cgroup_remove_list(pc);
spin_unlock_irqrestore(&mz->lru_lock, flags);
+ page_assign_page_cgroup(page, NULL);
+ unlock_page_cgroup(page);
+
pc->page = newpage;
lock_page_cgroup(newpage);
page_assign_page_cgroup(newpage, pc);
- unlock_page_cgroup(newpage);
mz = page_cgroup_zoneinfo(pc);
spin_lock_irqsave(&mz->lru_lock, flags);
__mem_cgroup_add_list(pc);
spin_unlock_irqrestore(&mz->lru_lock, flags);
- return;
+
+ unlock_page_cgroup(newpage);
}
/*
@@ -830,14 +762,13 @@ retry:
* *And* this routine doesn't reclaim page itself, just removes page_cgroup.
*/
#define FORCE_UNCHARGE_BATCH (128)
-static void
-mem_cgroup_force_empty_list(struct mem_cgroup *mem,
+static void mem_cgroup_force_empty_list(struct mem_cgroup *mem,
struct mem_cgroup_per_zone *mz,
int active)
{
struct page_cgroup *pc;
struct page *page;
- int count;
+ int count = FORCE_UNCHARGE_BATCH;
unsigned long flags;
struct list_head *list;
@@ -846,46 +777,36 @@ mem_cgroup_force_empty_list(struct mem_cgroup *mem,
else
list = &mz->inactive_list;
- if (list_empty(list))
- return;
-retry:
- count = FORCE_UNCHARGE_BATCH;
spin_lock_irqsave(&mz->lru_lock, flags);
-
- while (--count && !list_empty(list)) {
+ while (!list_empty(list)) {
pc = list_entry(list->prev, struct page_cgroup, lru);
page = pc->page;
- /* Avoid race with charge */
- atomic_set(&pc->ref_cnt, 0);
- if (clear_page_cgroup(page, pc) == pc) {
- css_put(&mem->css);
- res_counter_uncharge(&mem->res, PAGE_SIZE);
- __mem_cgroup_remove_list(pc);
- kfree(pc);
- } else /* being uncharged ? ...do relax */
- break;
+ get_page(page);
+ spin_unlock_irqrestore(&mz->lru_lock, flags);
+ mem_cgroup_uncharge_page(page);
+ put_page(page);
+ if (--count <= 0) {
+ count = FORCE_UNCHARGE_BATCH;
+ cond_resched();
+ }
+ spin_lock_irqsave(&mz->lru_lock, flags);
}
spin_unlock_irqrestore(&mz->lru_lock, flags);
- if (!list_empty(list)) {
- cond_resched();
- goto retry;
- }
- return;
}
/*
* make mem_cgroup's charge to be 0 if there is no task.
* This enables deleting this mem_cgroup.
*/
-
-int mem_cgroup_force_empty(struct mem_cgroup *mem)
+static int mem_cgroup_force_empty(struct mem_cgroup *mem)
{
int ret = -EBUSY;
int node, zid;
+
css_get(&mem->css);
/*
* page reclaim code (kswapd etc..) will move pages between
-` * active_list <-> inactive_list while we don't take a lock.
+ * active_list <-> inactive_list while we don't take a lock.
* So, we have to do loop here until all lists are empty.
*/
while (mem->res.usage > 0) {
@@ -907,9 +828,7 @@ out:
return ret;
}
-
-
-int mem_cgroup_write_strategy(char *buf, unsigned long long *tmp)
+static int mem_cgroup_write_strategy(char *buf, unsigned long long *tmp)
{
*tmp = memparse(buf, &buf);
if (*buf != '\0')
@@ -946,8 +865,7 @@ static ssize_t mem_force_empty_write(struct cgroup *cont,
size_t nbytes, loff_t *ppos)
{
struct mem_cgroup *mem = mem_cgroup_from_cont(cont);
- int ret;
- ret = mem_cgroup_force_empty(mem);
+ int ret = mem_cgroup_force_empty(mem);
if (!ret)
ret = nbytes;
return ret;
@@ -956,7 +874,6 @@ static ssize_t mem_force_empty_write(struct cgroup *cont,
/*
* Note: This should be removed if cgroup supports write-only file.
*/
-
static ssize_t mem_force_empty_read(struct cgroup *cont,
struct cftype *cft,
struct file *file, char __user *userbuf,
@@ -965,7 +882,6 @@ static ssize_t mem_force_empty_read(struct cgroup *cont,
return -EINVAL;
}
-
static const struct mem_cgroup_stat_desc {
const char *msg;
u64 unit;
@@ -1018,8 +934,6 @@ static int mem_control_stat_open(struct inode *unused, struct file *file)
return single_open(file, mem_control_stat_show, cont);
}
-
-
static struct cftype mem_cgroup_files[] = {
{
.name = "usage_in_bytes",
@@ -1085,9 +999,6 @@ static void free_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node)
kfree(mem->info.nodeinfo[node]);
}
-
-static struct mem_cgroup init_mem_cgroup;
-
static struct cgroup_subsys_state *
mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
{
@@ -1101,7 +1012,7 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
mem = kzalloc(sizeof(struct mem_cgroup), GFP_KERNEL);
if (mem == NULL)
- return NULL;
+ return ERR_PTR(-ENOMEM);
res_counter_init(&mem->res);
@@ -1117,7 +1028,7 @@ free_out:
free_mem_cgroup_per_zone_info(mem, node);
if (cont->parent != NULL)
kfree(mem);
- return NULL;
+ return ERR_PTR(-ENOMEM);
}
static void mem_cgroup_pre_destroy(struct cgroup_subsys *ss,
@@ -1177,7 +1088,6 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss,
out:
mmput(mm);
- return;
}
struct cgroup_subsys mem_cgroup_subsys = {
diff --git a/mm/memory.c b/mm/memory.c
index ce3c9e4492d..0d14d1e58a5 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1711,7 +1711,7 @@ unlock:
}
return ret;
oom_free_new:
- __free_page(new_page);
+ page_cache_release(new_page);
oom:
if (old_page)
page_cache_release(old_page);
@@ -2093,12 +2093,9 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
unlock_page(page);
if (write_access) {
- /* XXX: We could OR the do_wp_page code with this one? */
- if (do_wp_page(mm, vma, address,
- page_table, pmd, ptl, pte) & VM_FAULT_OOM) {
- mem_cgroup_uncharge_page(page);
- ret = VM_FAULT_OOM;
- }
+ ret |= do_wp_page(mm, vma, address, page_table, pmd, ptl, pte);
+ if (ret & VM_FAULT_ERROR)
+ ret &= VM_FAULT_ERROR;
goto out;
}
@@ -2163,7 +2160,7 @@ release:
page_cache_release(page);
goto unlock;
oom_free_page:
- __free_page(page);
+ page_cache_release(page);
oom:
return VM_FAULT_OOM;
}
diff --git a/mm/migrate.c b/mm/migrate.c
index a73504ff5ab..4e0eccca5e2 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -153,11 +153,6 @@ static void remove_migration_pte(struct vm_area_struct *vma,
return;
}
- if (mem_cgroup_charge(new, mm, GFP_KERNEL)) {
- pte_unmap(ptep);
- return;
- }
-
ptl = pte_lockptr(mm, pmd);
spin_lock(ptl);
pte = *ptep;
@@ -169,6 +164,20 @@ static void remove_migration_pte(struct vm_area_struct *vma,
if (!is_migration_entry(entry) || migration_entry_to_page(entry) != old)
goto out;
+ /*
+ * Yes, ignore the return value from a GFP_ATOMIC mem_cgroup_charge.
+ * Failure is not an option here: we're now expected to remove every
+ * migration pte, and will cause crashes otherwise. Normally this
+ * is not an issue: mem_cgroup_prepare_migration bumped up the old
+ * page_cgroup count for safety, that's now attached to the new page,
+ * so this charge should just be another incrementation of the count,
+ * to keep in balance with rmap.c's mem_cgroup_uncharging. But if
+ * there's been a force_empty, those reference counts may no longer
+ * be reliable, and this charge can actually fail: oh well, we don't
+ * make the situation any worse by proceeding as if it had succeeded.
+ */
+ mem_cgroup_charge(new, mm, GFP_ATOMIC);
+
get_page(new);
pte = pte_mkold(mk_pte(new, vma->vm_page_prot));
if (is_write_migration_entry(entry))
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 4194b9db010..44b2da11bf4 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -412,7 +412,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
return oom_kill_task(p);
}
-#ifdef CONFIG_CGROUP_MEM_CONT
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask)
{
unsigned long points = 0;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 75b97931334..402a504f122 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -19,6 +19,7 @@
#include <linux/swap.h>
#include <linux/interrupt.h>
#include <linux/pagemap.h>
+#include <linux/jiffies.h>
#include <linux/bootmem.h>
#include <linux/compiler.h>
#include <linux/kernel.h>
@@ -221,13 +222,19 @@ static inline int bad_range(struct zone *zone, struct page *page)
static void bad_page(struct page *page)
{
- printk(KERN_EMERG "Bad page state in process '%s'\n"
- KERN_EMERG "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n"
- KERN_EMERG "Trying to fix it up, but a reboot is needed\n"
- KERN_EMERG "Backtrace:\n",
+ void *pc = page_get_page_cgroup(page);
+
+ printk(KERN_EMERG "Bad page state in process '%s'\n" KERN_EMERG
+ "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n",
current->comm, page, (int)(2*sizeof(unsigned long)),
(unsigned long)page->flags, page->mapping,
page_mapcount(page), page_count(page));
+ if (pc) {
+ printk(KERN_EMERG "cgroup:%p\n", pc);
+ page_reset_bad_cgroup(page);
+ }
+ printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n"
+ KERN_EMERG "Backtrace:\n");
dump_stack();
page->flags &= ~(1 << PG_lru |
1 << PG_private |
@@ -453,6 +460,7 @@ static inline int free_pages_check(struct page *page)
{
if (unlikely(page_mapcount(page) |
(page->mapping != NULL) |
+ (page_get_page_cgroup(page) != NULL) |
(page_count(page) != 0) |
(page->flags & (
1 << PG_lru |
@@ -602,6 +610,7 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
{
if (unlikely(page_mapcount(page) |
(page->mapping != NULL) |
+ (page_get_page_cgroup(page) != NULL) |
(page_count(page) != 0) |
(page->flags & (
1 << PG_lru |
@@ -988,7 +997,6 @@ static void free_hot_cold_page(struct page *page, int cold)
if (!PageHighMem(page))
debug_check_no_locks_freed(page_address(page), PAGE_SIZE);
- VM_BUG_ON(page_get_page_cgroup(page));
arch_free_page(page, 0);
kernel_map_pages(page, 1, 0);
@@ -1276,7 +1284,7 @@ static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags)
if (!zlc)
return NULL;
- if (jiffies - zlc->last_full_zap > 1 * HZ) {
+ if (time_after(jiffies, zlc->last_full_zap + HZ)) {
bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST);
zlc->last_full_zap = jiffies;
}
@@ -2527,7 +2535,6 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
set_page_links(page, zone, nid, pfn);
init_page_count(page);
reset_page_mapcount(page);
- page_assign_page_cgroup(page, NULL);
SetPageReserved(page);
/*
@@ -3314,7 +3321,7 @@ static inline int pageblock_default_order(unsigned int order)
* - mark all memory queues empty
* - clear the memory bitmaps
*/
-static void __meminit free_area_init_core(struct pglist_data *pgdat,
+static void __paginginit free_area_init_core(struct pglist_data *pgdat,
unsigned long *zones_size, unsigned long *zholes_size)
{
enum zone_type j;
@@ -3438,7 +3445,7 @@ static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat)
#endif /* CONFIG_FLAT_NODE_MEM_MAP */
}
-void __meminit free_area_init_node(int nid, struct pglist_data *pgdat,
+void __paginginit free_area_init_node(int nid, struct pglist_data *pgdat,
unsigned long *zones_size, unsigned long node_start_pfn,
unsigned long *zholes_size)
{
diff --git a/mm/rmap.c b/mm/rmap.c
index 8fd527c4e2b..0c9a2df06c3 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -321,7 +321,7 @@ static int page_referenced_anon(struct page *page,
* counting on behalf of references from different
* cgroups
*/
- if (mem_cont && !vm_match_cgroup(vma->vm_mm, mem_cont))
+ if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont))
continue;
referenced += page_referenced_one(page, vma, &mapcount);
if (!mapcount)
@@ -382,7 +382,7 @@ static int page_referenced_file(struct page *page,
* counting on behalf of references from different
* cgroups
*/
- if (mem_cont && !vm_match_cgroup(vma->vm_mm, mem_cont))
+ if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont))
continue;
if ((vma->vm_flags & (VM_LOCKED|VM_MAYSHARE))
== (VM_LOCKED|VM_MAYSHARE)) {
diff --git a/mm/shmem.c b/mm/shmem.c
index 90b576cbc06..3372bc579e8 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1370,14 +1370,17 @@ repeat:
shmem_swp_unmap(entry);
spin_unlock(&info->lock);
unlock_page(swappage);
- page_cache_release(swappage);
if (error == -ENOMEM) {
/* allow reclaim from this memory cgroup */
- error = mem_cgroup_cache_charge(NULL,
+ error = mem_cgroup_cache_charge(swappage,
current->mm, gfp & ~__GFP_HIGHMEM);
- if (error)
+ if (error) {
+ page_cache_release(swappage);
goto failed;
+ }
+ mem_cgroup_uncharge_page(swappage);
}
+ page_cache_release(swappage);
goto repeat;
}
} else if (sgp == SGP_READ && !filepage) {
diff --git a/mm/slab.c b/mm/slab.c
index 473e6c2eaef..e6c698f5567 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -333,7 +333,7 @@ static __always_inline int index_of(const size_t size)
return i; \
else \
i++;
-#include "linux/kmalloc_sizes.h"
+#include <linux/kmalloc_sizes.h>
#undef CACHE
__bad_size();
} else
@@ -2964,11 +2964,10 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags)
struct array_cache *ac;
int node;
- node = numa_node_id();
-
+retry:
check_irq_off();
+ node = numa_node_id();
ac = cpu_cache_get(cachep);
-retry:
batchcount = ac->batchcount;
if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
/*
@@ -3280,7 +3279,7 @@ retry:
if (local_flags & __GFP_WAIT)
local_irq_enable();
kmem_flagcheck(cache, flags);
- obj = kmem_getpages(cache, flags, -1);
+ obj = kmem_getpages(cache, local_flags, -1);
if (local_flags & __GFP_WAIT)
local_irq_disable();
if (obj) {
diff --git a/mm/slub.c b/mm/slub.c
index 4b3895cb90e..96d63eb3ab1 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -149,13 +149,6 @@ static inline void ClearSlabDebug(struct page *page)
/* Enable to test recovery from slab corruption on boot */
#undef SLUB_RESILIENCY_TEST
-/*
- * Currently fastpath is not supported if preemption is enabled.
- */
-#if defined(CONFIG_FAST_CMPXCHG_LOCAL) && !defined(CONFIG_PREEMPT)
-#define SLUB_FASTPATH
-#endif
-
#if PAGE_SHIFT <= 12
/*
@@ -298,32 +291,16 @@ static inline struct kmem_cache_cpu *get_cpu_slab(struct kmem_cache *s, int cpu)
#endif
}
-/*
- * The end pointer in a slab is special. It points to the first object in the
- * slab but has bit 0 set to mark it.
- *
- * Note that SLUB relies on page_mapping returning NULL for pages with bit 0
- * in the mapping set.
- */
-static inline int is_end(void *addr)
-{
- return (unsigned long)addr & PAGE_MAPPING_ANON;
-}
-
-static void *slab_address(struct page *page)
-{
- return page->end - PAGE_MAPPING_ANON;
-}
-
+/* Verify that a pointer has an address that is valid within a slab page */
static inline int check_valid_pointer(struct kmem_cache *s,
struct page *page, const void *object)
{
void *base;
- if (object == page->end)
+ if (!object)
return 1;
- base = slab_address(page);
+ base = page_address(page);
if (object < base || object >= base + s->objects * s->size ||
(object - base) % s->size) {
return 0;
@@ -356,8 +333,7 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
/* Scan freelist */
#define for_each_free_object(__p, __s, __free) \
- for (__p = (__free); (__p) != page->end; __p = get_freepointer((__s),\
- __p))
+ for (__p = (__free); __p; __p = get_freepointer((__s), __p))
/* Determine object index from a given position */
static inline int slab_index(void *p, struct kmem_cache *s, void *addr)
@@ -509,7 +485,7 @@ static void slab_fix(struct kmem_cache *s, char *fmt, ...)
static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
{
unsigned int off; /* Offset of last byte */
- u8 *addr = slab_address(page);
+ u8 *addr = page_address(page);
print_tracking(s, p);
@@ -644,7 +620,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
* A. Free pointer (if we cannot overwrite object on free)
* B. Tracking data for SLAB_STORE_USER
* C. Padding to reach required alignment boundary or at mininum
- * one word if debuggin is on to be able to detect writes
+ * one word if debugging is on to be able to detect writes
* before the word boundary.
*
* Padding is done using 0x5a (POISON_INUSE)
@@ -687,7 +663,7 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page)
if (!(s->flags & SLAB_POISON))
return 1;
- start = slab_address(page);
+ start = page_address(page);
end = start + (PAGE_SIZE << s->order);
length = s->objects * s->size;
remainder = end - (start + length);
@@ -755,7 +731,7 @@ static int check_object(struct kmem_cache *s, struct page *page,
* of the free objects in this slab. May cause
* another error because the object count is now wrong.
*/
- set_freepointer(s, p, page->end);
+ set_freepointer(s, p, NULL);
return 0;
}
return 1;
@@ -789,18 +765,18 @@ static int on_freelist(struct kmem_cache *s, struct page *page, void *search)
void *fp = page->freelist;
void *object = NULL;
- while (fp != page->end && nr <= s->objects) {
+ while (fp && nr <= s->objects) {
if (fp == search)
return 1;
if (!check_valid_pointer(s, page, fp)) {
if (object) {
object_err(s, page, object,
"Freechain corrupt");
- set_freepointer(s, object, page->end);
+ set_freepointer(s, object, NULL);
break;
} else {
slab_err(s, page, "Freepointer corrupt");
- page->freelist = page->end;
+ page->freelist = NULL;
page->inuse = s->objects;
slab_fix(s, "Freelist cleared");
return 0;
@@ -877,7 +853,7 @@ static int alloc_debug_processing(struct kmem_cache *s, struct page *page,
if (!check_slab(s, page))
goto bad;
- if (object && !on_freelist(s, page, object)) {
+ if (!on_freelist(s, page, object)) {
object_err(s, page, object, "Object already allocated");
goto bad;
}
@@ -887,7 +863,7 @@ static int alloc_debug_processing(struct kmem_cache *s, struct page *page,
goto bad;
}
- if (object && !check_object(s, page, object, 0))
+ if (!check_object(s, page, object, 0))
goto bad;
/* Success perform special debug activities for allocs */
@@ -906,7 +882,7 @@ bad:
*/
slab_fix(s, "Marking all objects used");
page->inuse = s->objects;
- page->freelist = page->end;
+ page->freelist = NULL;
}
return 0;
}
@@ -946,7 +922,7 @@ static int free_debug_processing(struct kmem_cache *s, struct page *page,
}
/* Special debug activities for freeing objects */
- if (!SlabFrozen(page) && page->freelist == page->end)
+ if (!SlabFrozen(page) && !page->freelist)
remove_full(s, page);
if (s->flags & SLAB_STORE_USER)
set_track(s, object, TRACK_FREE, addr);
@@ -1022,30 +998,11 @@ static unsigned long kmem_cache_flags(unsigned long objsize,
void (*ctor)(struct kmem_cache *, void *))
{
/*
- * The page->offset field is only 16 bit wide. This is an offset
- * in units of words from the beginning of an object. If the slab
- * size is bigger then we cannot move the free pointer behind the
- * object anymore.
- *
- * On 32 bit platforms the limit is 256k. On 64bit platforms
- * the limit is 512k.
- *
- * Debugging or ctor may create a need to move the free
- * pointer. Fail if this happens.
+ * Enable debugging if selected on the kernel commandline.
*/
- if (objsize >= 65535 * sizeof(void *)) {
- BUG_ON(flags & (SLAB_RED_ZONE | SLAB_POISON |
- SLAB_STORE_USER | SLAB_DESTROY_BY_RCU));
- BUG_ON(ctor);
- } else {
- /*
- * Enable debugging if selected on the kernel commandline.
- */
- if (slub_debug && (!slub_debug_slabs ||
- strncmp(slub_debug_slabs, name,
- strlen(slub_debug_slabs)) == 0))
- flags |= slub_debug;
- }
+ if (slub_debug && (!slub_debug_slabs ||
+ strncmp(slub_debug_slabs, name, strlen(slub_debug_slabs)) == 0))
+ flags |= slub_debug;
return flags;
}
@@ -1131,7 +1088,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
SetSlabDebug(page);
start = page_address(page);
- page->end = start + 1;
if (unlikely(s->flags & SLAB_POISON))
memset(start, POISON_INUSE, PAGE_SIZE << s->order);
@@ -1143,7 +1099,7 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
last = p;
}
setup_object(s, page, last);
- set_freepointer(s, last, page->end);
+ set_freepointer(s, last, NULL);
page->freelist = start;
page->inuse = 0;
@@ -1159,7 +1115,7 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
void *p;
slab_pad_check(s, page);
- for_each_object(p, s, slab_address(page))
+ for_each_object(p, s, page_address(page))
check_object(s, page, p, 0);
ClearSlabDebug(page);
}
@@ -1169,7 +1125,6 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
-pages);
- page->mapping = NULL;
__free_pages(page, s->order);
}
@@ -1314,7 +1269,7 @@ static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags)
* may return off node objects because partial slabs are obtained
* from other nodes and filled up.
*
- * If /sys/slab/xx/defrag_ratio is set to 100 (which makes
+ * If /sys/kernel/slab/xx/defrag_ratio is set to 100 (which makes
* defrag_ratio = 1000) then every (well almost) allocation will
* first attempt to defrag slab caches on other nodes. This means
* scanning over all nodes to look for partial slabs which may be
@@ -1373,7 +1328,7 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
ClearSlabFrozen(page);
if (page->inuse) {
- if (page->freelist != page->end) {
+ if (page->freelist) {
add_partial(n, page, tail);
stat(c, tail ? DEACTIVATE_TO_TAIL : DEACTIVATE_TO_HEAD);
} else {
@@ -1389,9 +1344,11 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
* Adding an empty slab to the partial slabs in order
* to avoid page allocator overhead. This slab needs
* to come after the other slabs with objects in
- * order to fill them up. That way the size of the
- * partial list stays small. kmem_cache_shrink can
- * reclaim empty slabs from the partial list.
+ * so that the others get filled first. That way the
+ * size of the partial list stays small.
+ *
+ * kmem_cache_shrink can reclaim any empty slabs from the
+ * partial list.
*/
add_partial(n, page, 1);
slab_unlock(page);
@@ -1411,18 +1368,14 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
struct page *page = c->page;
int tail = 1;
- if (c->freelist)
+ if (page->freelist)
stat(c, DEACTIVATE_REMOTE_FREES);
/*
- * Merge cpu freelist into freelist. Typically we get here
+ * Merge cpu freelist into slab freelist. Typically we get here
* because both freelists are empty. So this is unlikely
* to occur.
- *
- * We need to use _is_end here because deactivate slab may
- * be called for a debug slab. Then c->freelist may contain
- * a dummy pointer.
*/
- while (unlikely(!is_end(c->freelist))) {
+ while (unlikely(c->freelist)) {
void **object;
tail = 0; /* Hot objects. Put the slab first */
@@ -1449,6 +1402,7 @@ static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
/*
* Flush cpu slab.
+ *
* Called from IPI handler with interrupts disabled.
*/
static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu)
@@ -1507,43 +1461,38 @@ static inline int node_match(struct kmem_cache_cpu *c, int node)
* rest of the freelist to the lockless freelist.
*
* And if we were unable to get a new slab from the partial slab lists then
- * we need to allocate a new slab. This is slowest path since we may sleep.
+ * we need to allocate a new slab. This is the slowest path since it involves
+ * a call to the page allocator and the setup of a new slab.
*/
static void *__slab_alloc(struct kmem_cache *s,
gfp_t gfpflags, int node, void *addr, struct kmem_cache_cpu *c)
{
void **object;
struct page *new;
-#ifdef SLUB_FASTPATH
- unsigned long flags;
- local_irq_save(flags);
-#endif
if (!c->page)
goto new_slab;
slab_lock(c->page);
if (unlikely(!node_match(c, node)))
goto another_slab;
+
stat(c, ALLOC_REFILL);
+
load_freelist:
object = c->page->freelist;
- if (unlikely(object == c->page->end))
+ if (unlikely(!object))
goto another_slab;
if (unlikely(SlabDebug(c->page)))
goto debug;
- object = c->page->freelist;
c->freelist = object[c->offset];
c->page->inuse = s->objects;
- c->page->freelist = c->page->end;
+ c->page->freelist = NULL;
c->node = page_to_nid(c->page);
unlock_out:
slab_unlock(c->page);
stat(c, ALLOC_SLOWPATH);
-#ifdef SLUB_FASTPATH
- local_irq_restore(flags);
-#endif
return object;
another_slab:
@@ -1575,9 +1524,7 @@ new_slab:
c->page = new;
goto load_freelist;
}
-#ifdef SLUB_FASTPATH
- local_irq_restore(flags);
-#endif
+
/*
* No memory available.
*
@@ -1594,7 +1541,6 @@ new_slab:
return NULL;
debug:
- object = c->page->freelist;
if (!alloc_debug_processing(s, c->page, object, addr))
goto another_slab;
@@ -1619,39 +1565,11 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
{
void **object;
struct kmem_cache_cpu *c;
-
-/*
- * The SLUB_FASTPATH path is provisional and is currently disabled if the
- * kernel is compiled with preemption or if the arch does not support
- * fast cmpxchg operations. There are a couple of coming changes that will
- * simplify matters and allow preemption. Ultimately we may end up making
- * SLUB_FASTPATH the default.
- *
- * 1. The introduction of the per cpu allocator will avoid array lookups
- * through get_cpu_slab(). A special register can be used instead.
- *
- * 2. The introduction of per cpu atomic operations (cpu_ops) means that
- * we can realize the logic here entirely with per cpu atomics. The
- * per cpu atomic ops will take care of the preemption issues.
- */
-
-#ifdef SLUB_FASTPATH
- c = get_cpu_slab(s, raw_smp_processor_id());
- do {
- object = c->freelist;
- if (unlikely(is_end(object) || !node_match(c, node))) {
- object = __slab_alloc(s, gfpflags, node, addr, c);
- break;
- }
- stat(c, ALLOC_FASTPATH);
- } while (cmpxchg_local(&c->freelist, object, object[c->offset])
- != object);
-#else
unsigned long flags;
local_irq_save(flags);
c = get_cpu_slab(s, smp_processor_id());
- if (unlikely(is_end(c->freelist) || !node_match(c, node)))
+ if (unlikely(!c->freelist || !node_match(c, node)))
object = __slab_alloc(s, gfpflags, node, addr, c);
@@ -1661,7 +1579,6 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
stat(c, ALLOC_FASTPATH);
}
local_irq_restore(flags);
-#endif
if (unlikely((gfpflags & __GFP_ZERO) && object))
memset(object, 0, c->objsize);
@@ -1698,17 +1615,13 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
void **object = (void *)x;
struct kmem_cache_cpu *c;
-#ifdef SLUB_FASTPATH
- unsigned long flags;
-
- local_irq_save(flags);
-#endif
c = get_cpu_slab(s, raw_smp_processor_id());
stat(c, FREE_SLOWPATH);
slab_lock(page);
if (unlikely(SlabDebug(page)))
goto debug;
+
checks_ok:
prior = object[offset] = page->freelist;
page->freelist = object;
@@ -1723,24 +1636,20 @@ checks_ok:
goto slab_empty;
/*
- * Objects left in the slab. If it
- * was not on the partial list before
+ * Objects left in the slab. If it was not on the partial list before
* then add it.
*/
- if (unlikely(prior == page->end)) {
+ if (unlikely(!prior)) {
add_partial(get_node(s, page_to_nid(page)), page, 1);
stat(c, FREE_ADD_PARTIAL);
}
out_unlock:
slab_unlock(page);
-#ifdef SLUB_FASTPATH
- local_irq_restore(flags);
-#endif
return;
slab_empty:
- if (prior != page->end) {
+ if (prior) {
/*
* Slab still on the partial list.
*/
@@ -1749,9 +1658,6 @@ slab_empty:
}
slab_unlock(page);
stat(c, FREE_SLAB);
-#ifdef SLUB_FASTPATH
- local_irq_restore(flags);
-#endif
discard_slab(s, page);
return;
@@ -1777,39 +1683,11 @@ static __always_inline void slab_free(struct kmem_cache *s,
{
void **object = (void *)x;
struct kmem_cache_cpu *c;
-
-#ifdef SLUB_FASTPATH
- void **freelist;
-
- c = get_cpu_slab(s, raw_smp_processor_id());
- debug_check_no_locks_freed(object, s->objsize);
- do {
- freelist = c->freelist;
- barrier();
- /*
- * If the compiler would reorder the retrieval of c->page to
- * come before c->freelist then an interrupt could
- * change the cpu slab before we retrieve c->freelist. We
- * could be matching on a page no longer active and put the
- * object onto the freelist of the wrong slab.
- *
- * On the other hand: If we already have the freelist pointer
- * then any change of cpu_slab will cause the cmpxchg to fail
- * since the freelist pointers are unique per slab.
- */
- if (unlikely(page != c->page || c->node < 0)) {
- __slab_free(s, page, x, addr, c->offset);
- break;
- }
- object[c->offset] = freelist;
- stat(c, FREE_FASTPATH);
- } while (cmpxchg_local(&c->freelist, freelist, object) != freelist);
-#else
unsigned long flags;
local_irq_save(flags);
- debug_check_no_locks_freed(object, s->objsize);
c = get_cpu_slab(s, smp_processor_id());
+ debug_check_no_locks_freed(object, c->objsize);
if (likely(page == c->page && c->node >= 0)) {
object[c->offset] = c->freelist;
c->freelist = object;
@@ -1818,7 +1696,6 @@ static __always_inline void slab_free(struct kmem_cache *s,
__slab_free(s, page, x, addr, c->offset);
local_irq_restore(flags);
-#endif
}
void kmem_cache_free(struct kmem_cache *s, void *x)
@@ -1973,20 +1850,21 @@ static unsigned long calculate_alignment(unsigned long flags,
unsigned long align, unsigned long size)
{
/*
- * If the user wants hardware cache aligned objects then
- * follow that suggestion if the object is sufficiently
- * large.
+ * If the user wants hardware cache aligned objects then follow that
+ * suggestion if the object is sufficiently large.
*
- * The hardware cache alignment cannot override the
- * specified alignment though. If that is greater
- * then use it.
+ * The hardware cache alignment cannot override the specified
+ * alignment though. If that is greater then use it.
*/
- if ((flags & SLAB_HWCACHE_ALIGN) &&
- size > cache_line_size() / 2)
- return max_t(unsigned long, align, cache_line_size());
+ if (flags & SLAB_HWCACHE_ALIGN) {
+ unsigned long ralign = cache_line_size();
+ while (size <= ralign / 2)
+ ralign /= 2;
+ align = max(align, ralign);
+ }
if (align < ARCH_SLAB_MINALIGN)
- return ARCH_SLAB_MINALIGN;
+ align = ARCH_SLAB_MINALIGN;
return ALIGN(align, sizeof(void *));
}
@@ -1995,7 +1873,7 @@ static void init_kmem_cache_cpu(struct kmem_cache *s,
struct kmem_cache_cpu *c)
{
c->page = NULL;
- c->freelist = (void *)PAGE_MAPPING_ANON;
+ c->freelist = NULL;
c->node = 0;
c->offset = s->offset / sizeof(void *);
c->objsize = s->objsize;
@@ -2177,6 +2055,7 @@ static struct kmem_cache_node *early_kmem_cache_node_alloc(gfp_t gfpflags,
#endif
init_kmem_cache_node(n);
atomic_long_inc(&n->nr_slabs);
+
/*
* lockdep requires consistent irq usage for each lock
* so even though there cannot be a race this early in
@@ -2258,6 +2137,14 @@ static int calculate_sizes(struct kmem_cache *s)
unsigned long align = s->align;
/*
+ * Round up object size to the next word boundary. We can only
+ * place the free pointer at word boundaries and this determines
+ * the possible location of the free pointer.
+ */
+ size = ALIGN(size, sizeof(void *));
+
+#ifdef CONFIG_SLUB_DEBUG
+ /*
* Determine if we can poison the object itself. If the user of
* the slab may touch the object after free or before allocation
* then we should never poison the object itself.
@@ -2268,14 +2155,7 @@ static int calculate_sizes(struct kmem_cache *s)
else
s->flags &= ~__OBJECT_POISON;
- /*
- * Round up object size to the next word boundary. We can only
- * place the free pointer at word boundaries and this determines
- * the possible location of the free pointer.
- */
- size = ALIGN(size, sizeof(void *));
-#ifdef CONFIG_SLUB_DEBUG
/*
* If we are Redzoning then check if there is some space between the
* end of the object and the free pointer. If not then add an
@@ -2428,7 +2308,7 @@ int kmem_ptr_validate(struct kmem_cache *s, const void *object)
/*
* We could also check if the object is on the slabs freelist.
* But this would be too expensive and it seems that the main
- * purpose of kmem_ptr_valid is to check if the object belongs
+ * purpose of kmem_ptr_valid() is to check if the object belongs
* to a certain slab.
*/
return 1;
@@ -2715,13 +2595,24 @@ void *__kmalloc(size_t size, gfp_t flags)
}
EXPORT_SYMBOL(__kmalloc);
+static void *kmalloc_large_node(size_t size, gfp_t flags, int node)
+{
+ struct page *page = alloc_pages_node(node, flags | __GFP_COMP,
+ get_order(size));
+
+ if (page)
+ return page_address(page);
+ else
+ return NULL;
+}
+
#ifdef CONFIG_NUMA
void *__kmalloc_node(size_t size, gfp_t flags, int node)
{
struct kmem_cache *s;
if (unlikely(size > PAGE_SIZE))
- return kmalloc_large(size, flags);
+ return kmalloc_large_node(size, flags, node);
s = get_slab(size, flags);
@@ -2738,19 +2629,17 @@ size_t ksize(const void *object)
struct page *page;
struct kmem_cache *s;
- BUG_ON(!object);
if (unlikely(object == ZERO_SIZE_PTR))
return 0;
page = virt_to_head_page(object);
- BUG_ON(!page);
if (unlikely(!PageSlab(page)))
return PAGE_SIZE << compound_order(page);
s = page->slab;
- BUG_ON(!s);
+#ifdef CONFIG_SLUB_DEBUG
/*
* Debugging requires use of the padding between object
* and whatever may come after it.
@@ -2758,6 +2647,7 @@ size_t ksize(const void *object)
if (s->flags & (SLAB_RED_ZONE | SLAB_POISON))
return s->objsize;
+#endif
/*
* If we have the need to store the freelist pointer
* back there or track user information then we can
@@ -2765,7 +2655,6 @@ size_t ksize(const void *object)
*/
if (s->flags & (SLAB_DESTROY_BY_RCU | SLAB_STORE_USER))
return s->inuse;
-
/*
* Else we can use all the padding etc for the allocation
*/
@@ -3042,7 +2931,7 @@ void __init kmem_cache_init(void)
/*
* Patch up the size_index table if we have strange large alignment
* requirements for the kmalloc array. This is only the case for
- * mips it seems. The standard arches will not generate any code here.
+ * MIPS it seems. The standard arches will not generate any code here.
*
* Largest permitted alignment is 256 bytes due to the way we
* handle the index determination for the smaller caches.
@@ -3071,7 +2960,6 @@ void __init kmem_cache_init(void)
kmem_size = sizeof(struct kmem_cache);
#endif
-
printk(KERN_INFO
"SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d,"
" CPUs=%d, Nodes=%d\n",
@@ -3168,12 +3056,15 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
*/
for_each_online_cpu(cpu)
get_cpu_slab(s, cpu)->objsize = s->objsize;
+
s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
up_write(&slub_lock);
+
if (sysfs_slab_alias(s, name))
goto err;
return s;
}
+
s = kmalloc(kmem_size, GFP_KERNEL);
if (s) {
if (kmem_cache_open(s, GFP_KERNEL, name,
@@ -3269,7 +3160,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
struct kmem_cache *s;
if (unlikely(size > PAGE_SIZE))
- return kmalloc_large(size, gfpflags);
+ return kmalloc_large_node(size, gfpflags, node);
s = get_slab(size, gfpflags);
@@ -3284,7 +3175,7 @@ static int validate_slab(struct kmem_cache *s, struct page *page,
unsigned long *map)
{
void *p;
- void *addr = slab_address(page);
+ void *addr = page_address(page);
if (!check_slab(s, page) ||
!on_freelist(s, page, NULL))
@@ -3567,7 +3458,7 @@ static int add_location(struct loc_track *t, struct kmem_cache *s,
static void process_slab(struct loc_track *t, struct kmem_cache *s,
struct page *page, enum track_item alloc)
{
- void *addr = slab_address(page);
+ void *addr = page_address(page);
DECLARE_BITMAP(map, s->objects);
void *p;
@@ -3676,8 +3567,8 @@ enum slab_stat_type {
#define SO_CPU (1 << SL_CPU)
#define SO_OBJECTS (1 << SL_OBJECTS)
-static unsigned long slab_objects(struct kmem_cache *s,
- char *buf, unsigned long flags)
+static ssize_t show_slab_objects(struct kmem_cache *s,
+ char *buf, unsigned long flags)
{
unsigned long total = 0;
int cpu;
@@ -3687,6 +3578,8 @@ static unsigned long slab_objects(struct kmem_cache *s,
unsigned long *per_cpu;
nodes = kzalloc(2 * sizeof(unsigned long) * nr_node_ids, GFP_KERNEL);
+ if (!nodes)
+ return -ENOMEM;
per_cpu = nodes + nr_node_ids;
for_each_possible_cpu(cpu) {
@@ -3839,25 +3732,25 @@ SLAB_ATTR_RO(aliases);
static ssize_t slabs_show(struct kmem_cache *s, char *buf)
{
- return slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU);
+ return show_slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU);
}
SLAB_ATTR_RO(slabs);
static ssize_t partial_show(struct kmem_cache *s, char *buf)
{
- return slab_objects(s, buf, SO_PARTIAL);
+ return show_slab_objects(s, buf, SO_PARTIAL);
}
SLAB_ATTR_RO(partial);
static ssize_t cpu_slabs_show(struct kmem_cache *s, char *buf)
{
- return slab_objects(s, buf, SO_CPU);
+ return show_slab_objects(s, buf, SO_CPU);
}
SLAB_ATTR_RO(cpu_slabs);
static ssize_t objects_show(struct kmem_cache *s, char *buf)
{
- return slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU|SO_OBJECTS);
+ return show_slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU|SO_OBJECTS);
}
SLAB_ATTR_RO(objects);
@@ -4056,7 +3949,6 @@ SLAB_ATTR(remote_node_defrag_ratio);
#endif
#ifdef CONFIG_SLUB_STATS
-
static int show_stat(struct kmem_cache *s, char *buf, enum stat_item si)
{
unsigned long sum = 0;
@@ -4240,8 +4132,8 @@ static struct kset *slab_kset;
#define ID_STR_LENGTH 64
/* Create a unique string id for a slab cache:
- * format
- * :[flags-]size:[memory address of kmemcache]
+ *
+ * Format :[flags-]size
*/
static char *create_unique_id(struct kmem_cache *s)
{
diff --git a/mm/swap.c b/mm/swap.c
index 710a20bb974..d4ec59aa5c4 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -176,7 +176,7 @@ void activate_page(struct page *page)
SetPageActive(page);
add_page_to_active_list(zone, page);
__count_vm_event(PGACTIVATE);
- mem_cgroup_move_lists(page_get_page_cgroup(page), true);
+ mem_cgroup_move_lists(page, true);
}
spin_unlock_irq(&zone->lru_lock);
}
diff --git a/mm/truncate.c b/mm/truncate.c
index c35c49e54fb..7d20ce41ecf 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -134,8 +134,7 @@ invalidate_complete_page(struct address_space *mapping, struct page *page)
}
/**
- * truncate_inode_pages - truncate range of pages specified by start and
- * end byte offsets
+ * truncate_inode_pages - truncate range of pages specified by start & end byte offsets
* @mapping: mapping to truncate
* @lstart: offset from which to truncate
* @lend: offset to which to truncate
diff --git a/mm/vmscan.c b/mm/vmscan.c
index a26dabd62fe..45711585684 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -126,7 +126,7 @@ long vm_total_pages; /* The total number of pages which the VM controls */
static LIST_HEAD(shrinker_list);
static DECLARE_RWSEM(shrinker_rwsem);
-#ifdef CONFIG_CGROUP_MEM_CONT
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
#define scan_global_lru(sc) (!(sc)->mem_cgroup)
#else
#define scan_global_lru(sc) (1)
@@ -1128,7 +1128,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
ClearPageActive(page);
list_move(&page->lru, &zone->inactive_list);
- mem_cgroup_move_lists(page_get_page_cgroup(page), false);
+ mem_cgroup_move_lists(page, false);
pgmoved++;
if (!pagevec_add(&pvec, page)) {
__mod_zone_page_state(zone, NR_INACTIVE, pgmoved);
@@ -1156,8 +1156,9 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
VM_BUG_ON(PageLRU(page));
SetPageLRU(page);
VM_BUG_ON(!PageActive(page));
+
list_move(&page->lru, &zone->active_list);
- mem_cgroup_move_lists(page_get_page_cgroup(page), true);
+ mem_cgroup_move_lists(page, true);
pgmoved++;
if (!pagevec_add(&pvec, page)) {
__mod_zone_page_state(zone, NR_ACTIVE, pgmoved);
@@ -1427,7 +1428,7 @@ unsigned long try_to_free_pages(struct zone **zones, int order, gfp_t gfp_mask)
return do_try_to_free_pages(zones, gfp_mask, &sc);
}
-#ifdef CONFIG_CGROUP_MEM_CONT
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont,
gfp_t gfp_mask)
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index a0ec4792559..146cfb0e988 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -161,11 +161,10 @@ int __init vlan_proc_init(void)
if (!proc_vlan_dir)
goto err;
- proc_vlan_conf = create_proc_entry(name_conf, S_IFREG|S_IRUSR|S_IWUSR,
- proc_vlan_dir);
+ proc_vlan_conf = proc_create(name_conf, S_IFREG|S_IRUSR|S_IWUSR,
+ proc_vlan_dir, &vlan_fops);
if (!proc_vlan_conf)
goto err;
- proc_vlan_conf->proc_fops = &vlan_fops;
return 0;
err:
@@ -182,13 +181,11 @@ int vlan_proc_add_dev(struct net_device *vlandev)
{
struct vlan_dev_info *dev_info = vlan_dev_info(vlandev);
- dev_info->dent = create_proc_entry(vlandev->name,
- S_IFREG|S_IRUSR|S_IWUSR,
- proc_vlan_dir);
+ dev_info->dent = proc_create(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR,
+ proc_vlan_dir, &vlandev_fops);
if (!dev_info->dent)
return -ENOBUFS;
- dev_info->dent->proc_fops = &vlandev_fops;
dev_info->dent->data = vlandev;
return 0;
}
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 0117b9fb848..de7a9f532ed 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -110,7 +110,7 @@ static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag)
}
for (count = old_max; count < c->max_tag; count++) {
c->reqs[count].status = REQ_STATUS_IDLE;
- c->reqs[count].wq = kmalloc(sizeof(wait_queue_t),
+ c->reqs[count].wq = kmalloc(sizeof(wait_queue_head_t),
GFP_ATOMIC);
if (!c->reqs[count].wq) {
printk(KERN_ERR "Couldn't grow tag array\n");
@@ -183,8 +183,7 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
sg_set_buf(&sg[index++], data, s);
count -= s;
data += s;
- if (index > limit)
- BUG();
+ BUG_ON(index > limit);
}
return index-start;
diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c
index 8e8dcfd532d..162199a2d74 100644
--- a/net/appletalk/atalk_proc.c
+++ b/net/appletalk/atalk_proc.c
@@ -283,25 +283,24 @@ int __init atalk_proc_init(void)
goto out;
atalk_proc_dir->owner = THIS_MODULE;
- p = create_proc_entry("interface", S_IRUGO, atalk_proc_dir);
+ p = proc_create("interface", S_IRUGO, atalk_proc_dir,
+ &atalk_seq_interface_fops);
if (!p)
goto out_interface;
- p->proc_fops = &atalk_seq_interface_fops;
- p = create_proc_entry("route", S_IRUGO, atalk_proc_dir);
+ p = proc_create("route", S_IRUGO, atalk_proc_dir,
+ &atalk_seq_route_fops);
if (!p)
goto out_route;
- p->proc_fops = &atalk_seq_route_fops;
- p = create_proc_entry("socket", S_IRUGO, atalk_proc_dir);
+ p = proc_create("socket", S_IRUGO, atalk_proc_dir,
+ &atalk_seq_socket_fops);
if (!p)
goto out_socket;
- p->proc_fops = &atalk_seq_socket_fops;
- p = create_proc_entry("arp", S_IRUGO, atalk_proc_dir);
+ p = proc_create("arp", S_IRUGO, atalk_proc_dir, &atalk_seq_arp_fops);
if (!p)
goto out_arp;
- p->proc_fops = &atalk_seq_arp_fops;
rc = 0;
out:
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 574d9a96417..1b228065e74 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -742,9 +742,9 @@ static int __init br2684_init(void)
{
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *p;
- if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL)
+ p = proc_create("br2684", 0, atm_proc_root, &br2684_proc_ops);
+ if (p == NULL)
return -ENOMEM;
- p->proc_fops = &br2684_proc_ops;
#endif
register_atm_ioctl(&br2684_ioctl_ops);
return 0;
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 86b885ec1cb..d30167c0b48 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -962,9 +962,7 @@ static int __init atm_clip_init(void)
{
struct proc_dir_entry *p;
- p = create_proc_entry("arp", S_IRUGO, atm_proc_root);
- if (p)
- p->proc_fops = &arp_seq_fops;
+ p = proc_create("arp", S_IRUGO, atm_proc_root, &arp_seq_fops);
}
#endif
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 1a8c4c6c0cd..0e450d12f03 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -1249,9 +1249,7 @@ static int __init lane_module_init(void)
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *p;
- p = create_proc_entry("lec", S_IRUGO, atm_proc_root);
- if (p)
- p->proc_fops = &lec_seq_fops;
+ p = proc_create("lec", S_IRUGO, atm_proc_root, &lec_seq_fops);
#endif
register_atm_ioctl(&lane_ioctl_ops);
diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c
index 91f3ffc90db..4990541ef5d 100644
--- a/net/atm/mpoa_proc.c
+++ b/net/atm/mpoa_proc.c
@@ -276,12 +276,11 @@ int mpc_proc_init(void)
{
struct proc_dir_entry *p;
- p = create_proc_entry(STAT_FILE_NAME, 0, atm_proc_root);
+ p = proc_create(STAT_FILE_NAME, 0, atm_proc_root, &mpc_file_operations);
if (!p) {
printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
return -ENOMEM;
}
- p->proc_fops = &mpc_file_operations;
p->owner = THIS_MODULE;
return 0;
}
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 49125110bb8..e9693aed7ef 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -435,11 +435,11 @@ int atm_proc_dev_register(struct atm_dev *dev)
goto err_out;
sprintf(dev->proc_name,"%s:%d",dev->type, dev->number);
- dev->proc_entry = create_proc_entry(dev->proc_name, 0, atm_proc_root);
+ dev->proc_entry = proc_create(dev->proc_name, 0, atm_proc_root,
+ &proc_atm_dev_ops);
if (!dev->proc_entry)
goto err_free_name;
dev->proc_entry->data = dev;
- dev->proc_entry->proc_fops = &proc_atm_dev_ops;
dev->proc_entry->owner = THIS_MODULE;
return 0;
err_free_name:
@@ -492,10 +492,10 @@ int __init atm_proc_init(void)
for (e = atm_proc_ents; e->name; e++) {
struct proc_dir_entry *dirent;
- dirent = create_proc_entry(e->name, S_IRUGO, atm_proc_root);
+ dirent = proc_create(e->name, S_IRUGO,
+ atm_proc_root, e->proc_fops);
if (!dirent)
goto err_out_remove;
- dirent->proc_fops = e->proc_fops;
dirent->owner = THIS_MODULE;
e->dirent = dirent;
}
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 8fc64e3150a..48bfcc741f2 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -510,11 +510,7 @@ ax25_cb *ax25_create_cb(void)
skb_queue_head_init(&ax25->ack_queue);
skb_queue_head_init(&ax25->reseq_queue);
- init_timer(&ax25->timer);
- init_timer(&ax25->t1timer);
- init_timer(&ax25->t2timer);
- init_timer(&ax25->t3timer);
- init_timer(&ax25->idletimer);
+ ax25_setup_timers(ax25);
ax25_fillin_cb(ax25, NULL);
@@ -1928,12 +1924,10 @@ static int ax25_info_show(struct seq_file *seq, void *v)
ax25->paclen);
if (ax25->sk != NULL) {
- bh_lock_sock(ax25->sk);
- seq_printf(seq," %d %d %ld\n",
+ seq_printf(seq, " %d %d %lu\n",
atomic_read(&ax25->sk->sk_wmem_alloc),
atomic_read(&ax25->sk->sk_rmem_alloc),
- ax25->sk->sk_socket != NULL ? SOCK_INODE(ax25->sk->sk_socket)->i_ino : 0L);
- bh_unlock_sock(ax25->sk);
+ sock_i_ino(ax25->sk));
} else {
seq_puts(seq, " * * *\n");
}
diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c
index 528c874d982..a7a0e0c9698 100644
--- a/net/ax25/ax25_dev.c
+++ b/net/ax25/ax25_dev.c
@@ -82,7 +82,7 @@ void ax25_dev_device_up(struct net_device *dev)
ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT;
#if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
- init_timer(&ax25_dev->dama.slave_timer);
+ ax25_ds_setup_timer(ax25_dev);
#endif
spin_lock_bh(&ax25_dev_lock);
diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c
index c4e3b025d21..2ce79df0068 100644
--- a/net/ax25/ax25_ds_timer.c
+++ b/net/ax25/ax25_ds_timer.c
@@ -40,13 +40,10 @@ static void ax25_ds_timeout(unsigned long);
* 1/10th of a second.
*/
-static void ax25_ds_add_timer(ax25_dev *ax25_dev)
+void ax25_ds_setup_timer(ax25_dev *ax25_dev)
{
- struct timer_list *t = &ax25_dev->dama.slave_timer;
- t->data = (unsigned long) ax25_dev;
- t->function = &ax25_ds_timeout;
- t->expires = jiffies + HZ;
- add_timer(t);
+ setup_timer(&ax25_dev->dama.slave_timer, ax25_ds_timeout,
+ (unsigned long)ax25_dev);
}
void ax25_ds_del_timer(ax25_dev *ax25_dev)
@@ -60,10 +57,9 @@ void ax25_ds_set_timer(ax25_dev *ax25_dev)
if (ax25_dev == NULL) /* paranoia */
return;
- del_timer(&ax25_dev->dama.slave_timer);
ax25_dev->dama.slave_timeout =
msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10;
- ax25_ds_add_timer(ax25_dev);
+ mod_timer(&ax25_dev->dama.slave_timer, jiffies + HZ);
}
/*
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
index 92b517af726..bf706f83a5c 100644
--- a/net/ax25/ax25_out.c
+++ b/net/ax25/ax25_out.c
@@ -117,6 +117,12 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
unsigned char *p;
int frontlen, len, fragno, ka9qfrag, first = 1;
+ if (paclen < 16) {
+ WARN_ON_ONCE(1);
+ kfree_skb(skb);
+ return;
+ }
+
if ((skb->len - 1) > paclen) {
if (*skb->data == AX25_P_TEXT) {
skb_pull(skb, 1); /* skip PID */
@@ -251,8 +257,6 @@ void ax25_kick(ax25_cb *ax25)
if (start == end)
return;
- ax25->vs = start;
-
/*
* Transmit data until either we're out of data to send or
* the window is full. Send a poll on the final I frame if
@@ -261,8 +265,13 @@ void ax25_kick(ax25_cb *ax25)
/*
* Dequeue the frame and copy it.
+ * Check for race with ax25_clear_queues().
*/
skb = skb_dequeue(&ax25->write_queue);
+ if (!skb)
+ return;
+
+ ax25->vs = start;
do {
if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 38c7f3087ec..8672cd84fdf 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -45,7 +45,7 @@ void ax25_rt_device_down(struct net_device *dev)
{
ax25_route *s, *t, *ax25_rt;
- write_lock(&ax25_route_lock);
+ write_lock_bh(&ax25_route_lock);
ax25_rt = ax25_route_list;
while (ax25_rt != NULL) {
s = ax25_rt;
@@ -68,7 +68,7 @@ void ax25_rt_device_down(struct net_device *dev)
}
}
}
- write_unlock(&ax25_route_lock);
+ write_unlock_bh(&ax25_route_lock);
}
static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
@@ -82,7 +82,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
if (route->digi_count > AX25_MAX_DIGIS)
return -EINVAL;
- write_lock(&ax25_route_lock);
+ write_lock_bh(&ax25_route_lock);
ax25_rt = ax25_route_list;
while (ax25_rt != NULL) {
@@ -92,7 +92,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
ax25_rt->digipeat = NULL;
if (route->digi_count != 0) {
if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
- write_unlock(&ax25_route_lock);
+ write_unlock_bh(&ax25_route_lock);
return -ENOMEM;
}
ax25_rt->digipeat->lastrepeat = -1;
@@ -102,14 +102,14 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
ax25_rt->digipeat->calls[i] = route->digi_addr[i];
}
}
- write_unlock(&ax25_route_lock);
+ write_unlock_bh(&ax25_route_lock);
return 0;
}
ax25_rt = ax25_rt->next;
}
if ((ax25_rt = kmalloc(sizeof(ax25_route), GFP_ATOMIC)) == NULL) {
- write_unlock(&ax25_route_lock);
+ write_unlock_bh(&ax25_route_lock);
return -ENOMEM;
}
@@ -120,7 +120,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
ax25_rt->ip_mode = ' ';
if (route->digi_count != 0) {
if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
- write_unlock(&ax25_route_lock);
+ write_unlock_bh(&ax25_route_lock);
kfree(ax25_rt);
return -ENOMEM;
}
@@ -133,7 +133,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
}
ax25_rt->next = ax25_route_list;
ax25_route_list = ax25_rt;
- write_unlock(&ax25_route_lock);
+ write_unlock_bh(&ax25_route_lock);
return 0;
}
@@ -152,7 +152,7 @@ static int ax25_rt_del(struct ax25_routes_struct *route)
if ((ax25_dev = ax25_addr_ax25dev(&route->port_addr)) == NULL)
return -EINVAL;
- write_lock(&ax25_route_lock);
+ write_lock_bh(&ax25_route_lock);
ax25_rt = ax25_route_list;
while (ax25_rt != NULL) {
@@ -174,7 +174,7 @@ static int ax25_rt_del(struct ax25_routes_struct *route)
}
}
}
- write_unlock(&ax25_route_lock);
+ write_unlock_bh(&ax25_route_lock);
return 0;
}
@@ -188,7 +188,7 @@ static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option)
if ((ax25_dev = ax25_addr_ax25dev(&rt_option->port_addr)) == NULL)
return -EINVAL;
- write_lock(&ax25_route_lock);
+ write_lock_bh(&ax25_route_lock);
ax25_rt = ax25_route_list;
while (ax25_rt != NULL) {
@@ -216,7 +216,7 @@ static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option)
}
out:
- write_unlock(&ax25_route_lock);
+ write_unlock_bh(&ax25_route_lock);
return err;
}
@@ -492,7 +492,7 @@ void __exit ax25_rt_free(void)
{
ax25_route *s, *ax25_rt = ax25_route_list;
- write_lock(&ax25_route_lock);
+ write_lock_bh(&ax25_route_lock);
while (ax25_rt != NULL) {
s = ax25_rt;
ax25_rt = ax25_rt->next;
@@ -500,5 +500,5 @@ void __exit ax25_rt_free(void)
kfree(s->digipeat);
kfree(s);
}
- write_unlock(&ax25_route_lock);
+ write_unlock_bh(&ax25_route_lock);
}
diff --git a/net/ax25/ax25_timer.c b/net/ax25/ax25_timer.c
index 72594867fab..db29ea71e80 100644
--- a/net/ax25/ax25_timer.c
+++ b/net/ax25/ax25_timer.c
@@ -40,63 +40,45 @@ static void ax25_t2timer_expiry(unsigned long);
static void ax25_t3timer_expiry(unsigned long);
static void ax25_idletimer_expiry(unsigned long);
-void ax25_start_heartbeat(ax25_cb *ax25)
+void ax25_setup_timers(ax25_cb *ax25)
{
- del_timer(&ax25->timer);
-
- ax25->timer.data = (unsigned long)ax25;
- ax25->timer.function = &ax25_heartbeat_expiry;
- ax25->timer.expires = jiffies + 5 * HZ;
+ setup_timer(&ax25->timer, ax25_heartbeat_expiry, (unsigned long)ax25);
+ setup_timer(&ax25->t1timer, ax25_t1timer_expiry, (unsigned long)ax25);
+ setup_timer(&ax25->t2timer, ax25_t2timer_expiry, (unsigned long)ax25);
+ setup_timer(&ax25->t3timer, ax25_t3timer_expiry, (unsigned long)ax25);
+ setup_timer(&ax25->idletimer, ax25_idletimer_expiry,
+ (unsigned long)ax25);
+}
- add_timer(&ax25->timer);
+void ax25_start_heartbeat(ax25_cb *ax25)
+{
+ mod_timer(&ax25->timer, jiffies + 5 * HZ);
}
void ax25_start_t1timer(ax25_cb *ax25)
{
- del_timer(&ax25->t1timer);
-
- ax25->t1timer.data = (unsigned long)ax25;
- ax25->t1timer.function = &ax25_t1timer_expiry;
- ax25->t1timer.expires = jiffies + ax25->t1;
-
- add_timer(&ax25->t1timer);
+ mod_timer(&ax25->t1timer, jiffies + ax25->t1);
}
void ax25_start_t2timer(ax25_cb *ax25)
{
- del_timer(&ax25->t2timer);
-
- ax25->t2timer.data = (unsigned long)ax25;
- ax25->t2timer.function = &ax25_t2timer_expiry;
- ax25->t2timer.expires = jiffies + ax25->t2;
-
- add_timer(&ax25->t2timer);
+ mod_timer(&ax25->t2timer, jiffies + ax25->t2);
}
void ax25_start_t3timer(ax25_cb *ax25)
{
- del_timer(&ax25->t3timer);
-
- if (ax25->t3 > 0) {
- ax25->t3timer.data = (unsigned long)ax25;
- ax25->t3timer.function = &ax25_t3timer_expiry;
- ax25->t3timer.expires = jiffies + ax25->t3;
-
- add_timer(&ax25->t3timer);
- }
+ if (ax25->t3 > 0)
+ mod_timer(&ax25->t3timer, jiffies + ax25->t3);
+ else
+ del_timer(&ax25->t3timer);
}
void ax25_start_idletimer(ax25_cb *ax25)
{
- del_timer(&ax25->idletimer);
-
- if (ax25->idle > 0) {
- ax25->idletimer.data = (unsigned long)ax25;
- ax25->idletimer.function = &ax25_idletimer_expiry;
- ax25->idletimer.expires = jiffies + ax25->idle;
-
- add_timer(&ax25->idletimer);
- }
+ if (ax25->idle > 0)
+ mod_timer(&ax25->idletimer, jiffies + ax25->idle);
+ else
+ del_timer(&ax25->idletimer);
}
void ax25_stop_heartbeat(ax25_cb *ax25)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 5fc7be206f6..f8880261da0 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -260,7 +260,6 @@ int hci_conn_del(struct hci_conn *conn)
tasklet_enable(&hdev->tx_task);
skb_queue_purge(&conn->data_q);
hci_conn_del_sysfs(conn);
- hci_dev_put(hdev);
return 0;
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 372b0d3b75a..930b58e7149 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -24,6 +24,7 @@
/* Bluetooth HCI core. */
+#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/kmod.h>
@@ -1321,7 +1322,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
if (!test_bit(HCI_RAW, &hdev->flags)) {
/* ACL tx timeout must be longer than maximum
* link supervision timeout (40.9 seconds) */
- if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
+ if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45))
hci_acl_tx_to(hdev);
}
@@ -1543,7 +1544,7 @@ static void hci_cmd_task(unsigned long arg)
BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
- if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) {
+ if (!atomic_read(&hdev->cmd_cnt) && time_after(jiffies, hdev->cmd_last_tx + HZ)) {
BT_ERR("%s command tx timeout", hdev->name);
atomic_set(&hdev->cmd_cnt, 1);
}
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index e13cf5ef144..84360c117d4 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -320,28 +320,34 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
queue_work(btaddconn, &conn->work);
}
+/*
+ * The rfcomm tty device will possibly retain even when conn
+ * is down, and sysfs doesn't support move zombie device,
+ * so we should move the device before conn device is destroyed.
+ */
static int __match_tty(struct device *dev, void *data)
{
- /* The rfcomm tty device will possibly retain even when conn
- * is down, and sysfs doesn't support move zombie device,
- * so we should move the device before conn device is destroyed.
- * Due to the only child device of hci_conn dev is rfcomm
- * tty_dev, here just return 1
- */
- return 1;
+ return !strncmp(dev->bus_id, "rfcomm", 6);
}
static void del_conn(struct work_struct *work)
{
- struct device *dev;
struct hci_conn *conn = container_of(work, struct hci_conn, work);
+ struct hci_dev *hdev = conn->hdev;
+
+ while (1) {
+ struct device *dev;
- while (dev = device_find_child(&conn->dev, NULL, __match_tty)) {
+ dev = device_find_child(&conn->dev, NULL, __match_tty);
+ if (!dev)
+ break;
device_move(dev, NULL);
put_device(dev);
}
+
device_del(&conn->dev);
put_device(&conn->dev);
+ hci_dev_put(hdev);
}
void hci_conn_del_sysfs(struct hci_conn *conn)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index a8811c0a0ce..34f8bf98bc0 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -417,6 +417,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
l2cap_sock_kill(sk);
}
+ if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
+ del_timer_sync(&conn->info_timer);
+
hcon->l2cap_data = NULL;
kfree(conn);
}
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
index e700cbf634c..ca64c1cc1b4 100644
--- a/net/bridge/netfilter/ebt_dnat.c
+++ b/net/bridge/netfilter/ebt_dnat.c
@@ -20,8 +20,8 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
{
const struct ebt_nat_info *info = data;
- if (skb_make_writable(skb, 0))
- return NF_DROP;
+ if (!skb_make_writable(skb, 0))
+ return EBT_DROP;
memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN);
return info->target;
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
index bfdf2fb60b1..b8afe850cf1 100644
--- a/net/bridge/netfilter/ebt_redirect.c
+++ b/net/bridge/netfilter/ebt_redirect.c
@@ -21,8 +21,8 @@ static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr,
{
const struct ebt_redirect_info *info = data;
- if (skb_make_writable(skb, 0))
- return NF_DROP;
+ if (!skb_make_writable(skb, 0))
+ return EBT_DROP;
if (hooknr != NF_BR_BROUTING)
memcpy(eth_hdr(skb)->h_dest,
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c
index e252dabbb14..5425333dda0 100644
--- a/net/bridge/netfilter/ebt_snat.c
+++ b/net/bridge/netfilter/ebt_snat.c
@@ -22,8 +22,8 @@ static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
{
const struct ebt_nat_info *info = data;
- if (skb_make_writable(skb, 0))
- return NF_DROP;
+ if (!skb_make_writable(skb, 0))
+ return EBT_DROP;
memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
if (!(info->target & NAT_ARP_BIT) &&
diff --git a/net/core/dev.c b/net/core/dev.c
index b3e19ae57f9..fcdf03cf3b3 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1071,8 +1071,6 @@ int dev_close(struct net_device *dev)
*/
call_netdevice_notifiers(NETDEV_GOING_DOWN, dev);
- dev_deactivate(dev);
-
clear_bit(__LINK_STATE_START, &dev->state);
/* Synchronize to scheduled poll. We cannot touch poll list,
@@ -1083,6 +1081,8 @@ int dev_close(struct net_device *dev)
*/
smp_mb__after_clear_bit(); /* Commit netif_running(). */
+ dev_deactivate(dev);
+
/*
* Call the device specific close. This cannot fail.
* Only if device is UP
@@ -2900,7 +2900,7 @@ int __dev_addr_add(struct dev_addr_list **list, int *count,
}
}
- da = kmalloc(sizeof(*da), GFP_ATOMIC);
+ da = kzalloc(sizeof(*da), GFP_ATOMIC);
if (da == NULL)
return -ENOMEM;
memcpy(da->da_addr, addr, alen);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index a16cf1ec5e5..d9a02b2cc28 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -358,11 +358,12 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
{
struct neighbour *n;
int key_len = tbl->key_len;
- u32 hash_val = tbl->hash(pkey, dev);
+ u32 hash_val;
NEIGH_CACHE_STAT_INC(tbl, lookups);
read_lock_bh(&tbl->lock);
+ hash_val = tbl->hash(pkey, dev);
for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) {
neigh_hold(n);
@@ -379,11 +380,12 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
{
struct neighbour *n;
int key_len = tbl->key_len;
- u32 hash_val = tbl->hash(pkey, NULL);
+ u32 hash_val;
NEIGH_CACHE_STAT_INC(tbl, lookups);
read_lock_bh(&tbl->lock);
+ hash_val = tbl->hash(pkey, NULL);
for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
if (!memcmp(n->primary_key, pkey, key_len) &&
(net == n->dev->nd_net)) {
@@ -507,6 +509,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
if (tbl->pconstructor && tbl->pconstructor(n)) {
if (dev)
dev_put(dev);
+ release_net(net);
kfree(n);
n = NULL;
goto out;
@@ -836,7 +839,7 @@ static void neigh_timer_handler(unsigned long arg)
struct sk_buff *skb = skb_peek(&neigh->arp_queue);
/* keep skb alive even if arp_queue overflows */
if (skb)
- skb_get(skb);
+ skb = skb_copy(skb, GFP_ATOMIC);
write_unlock(&neigh->lock);
neigh->ops->solicit(neigh, skb);
atomic_inc(&neigh->probes);
@@ -1386,10 +1389,10 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
panic("cannot create neighbour cache statistics");
#ifdef CONFIG_PROC_FS
- tbl->pde = create_proc_entry(tbl->id, 0, init_net.proc_net_stat);
+ tbl->pde = proc_create(tbl->id, 0, init_net.proc_net_stat,
+ &neigh_stat_seq_fops);
if (!tbl->pde)
panic("cannot create neighbour proc dir entry");
- tbl->pde->proc_fops = &neigh_stat_seq_fops;
tbl->pde->data = tbl;
#endif
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 6faa128a4c8..4b7e756181c 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -39,6 +39,8 @@ static struct sk_buff_head skb_pool;
static atomic_t trapped;
#define USEC_PER_POLL 50
+#define NETPOLL_RX_ENABLED 1
+#define NETPOLL_RX_DROP 2
#define MAX_SKB_SIZE \
(MAX_UDP_CHUNK + sizeof(struct udphdr) + \
@@ -126,11 +128,13 @@ static int poll_one_napi(struct netpoll_info *npinfo,
if (!test_bit(NAPI_STATE_SCHED, &napi->state))
return budget;
+ npinfo->rx_flags |= NETPOLL_RX_DROP;
atomic_inc(&trapped);
work = napi->poll(napi, budget);
atomic_dec(&trapped);
+ npinfo->rx_flags &= ~NETPOLL_RX_DROP;
return budget - work;
}
@@ -472,7 +476,7 @@ int __netpoll_rx(struct sk_buff *skb)
if (skb->dev->type != ARPHRD_ETHER)
goto out;
- /* if receive ARP during middle of NAPI poll, then queue */
+ /* check if netpoll clients need ARP */
if (skb->protocol == htons(ETH_P_ARP) &&
atomic_read(&trapped)) {
skb_queue_tail(&npi->arp_tx, skb);
@@ -534,9 +538,6 @@ int __netpoll_rx(struct sk_buff *skb)
return 1;
out:
- /* If packet received while already in poll then just
- * silently drop.
- */
if (atomic_read(&trapped)) {
kfree_skb(skb);
return 1;
@@ -675,6 +676,7 @@ int netpoll_setup(struct netpoll *np)
goto release;
}
+ npinfo->rx_flags = 0;
npinfo->rx_np = NULL;
spin_lock_init(&npinfo->rx_lock);
@@ -756,6 +758,7 @@ int netpoll_setup(struct netpoll *np)
if (np->rx_hook) {
spin_lock_irqsave(&npinfo->rx_lock, flags);
+ npinfo->rx_flags |= NETPOLL_RX_ENABLED;
npinfo->rx_np = np;
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
}
@@ -797,6 +800,7 @@ void netpoll_cleanup(struct netpoll *np)
if (npinfo->rx_np == np) {
spin_lock_irqsave(&npinfo->rx_lock, flags);
npinfo->rx_np = NULL;
+ npinfo->rx_flags &= ~NETPOLL_RX_ENABLED;
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
}
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index bfcdfaebca5..20e63b302ba 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -3570,14 +3570,14 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
if (err)
goto out1;
- pkt_dev->entry = create_proc_entry(ifname, 0600, pg_proc_dir);
+ pkt_dev->entry = proc_create(ifname, 0600,
+ pg_proc_dir, &pktgen_if_fops);
if (!pkt_dev->entry) {
printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n",
PG_PROC_DIR, ifname);
err = -EINVAL;
goto out2;
}
- pkt_dev->entry->proc_fops = &pktgen_if_fops;
pkt_dev->entry->data = pkt_dev;
#ifdef CONFIG_XFRM
pkt_dev->ipsmode = XFRM_MODE_TRANSPORT;
@@ -3628,7 +3628,7 @@ static int __init pktgen_create_thread(int cpu)
kthread_bind(p, cpu);
t->tsk = p;
- pe = create_proc_entry(t->tsk->comm, 0600, pg_proc_dir);
+ pe = proc_create(t->tsk->comm, 0600, pg_proc_dir, &pktgen_thread_fops);
if (!pe) {
printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n",
PG_PROC_DIR, t->tsk->comm);
@@ -3638,7 +3638,6 @@ static int __init pktgen_create_thread(int cpu)
return -EINVAL;
}
- pe->proc_fops = &pktgen_thread_fops;
pe->data = t;
wake_up_process(p);
@@ -3709,7 +3708,7 @@ static int __init pg_init(void)
return -ENODEV;
pg_proc_dir->owner = THIS_MODULE;
- pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir);
+ pe = proc_create(PGCTRL, 0600, pg_proc_dir, &pktgen_fops);
if (pe == NULL) {
printk(KERN_ERR "pktgen: ERROR: cannot create %s "
"procfs entry.\n", PGCTRL);
@@ -3717,7 +3716,6 @@ static int __init pg_init(void)
return -EINVAL;
}
- pe->proc_fops = &pktgen_fops;
pe->data = NULL;
/* Register us to receive netdevice events */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 61ac8d06292..2bd9c5f7627 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -689,10 +689,12 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
[IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
[IFLA_MTU] = { .type = NLA_U32 },
+ [IFLA_LINK] = { .type = NLA_U32 },
[IFLA_TXQLEN] = { .type = NLA_U32 },
[IFLA_WEIGHT] = { .type = NLA_U32 },
[IFLA_OPERSTATE] = { .type = NLA_U8 },
[IFLA_LINKMODE] = { .type = NLA_U8 },
+ [IFLA_LINKINFO] = { .type = NLA_NESTED },
[IFLA_NET_NS_PID] = { .type = NLA_U32 },
};
@@ -720,6 +722,21 @@ static struct net *get_net_ns_by_pid(pid_t pid)
return net;
}
+static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
+{
+ if (dev) {
+ if (tb[IFLA_ADDRESS] &&
+ nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
+ return -EINVAL;
+
+ if (tb[IFLA_BROADCAST] &&
+ nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
struct nlattr **tb, char *ifname, int modified)
{
@@ -892,12 +909,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
goto errout;
}
- if (tb[IFLA_ADDRESS] &&
- nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
- goto errout_dev;
-
- if (tb[IFLA_BROADCAST] &&
- nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
+ if ((err = validate_linkmsg(dev, tb)) < 0)
goto errout_dev;
err = do_setlink(dev, ifm, tb, ifname, 0);
@@ -1018,6 +1030,9 @@ replay:
else
dev = NULL;
+ if ((err = validate_linkmsg(dev, tb)) < 0)
+ return err;
+
if (tb[IFLA_LINKINFO]) {
err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
tb[IFLA_LINKINFO], ifla_info_policy);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index cfc07dac636..0d0fd28a904 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2106,11 +2106,10 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
/**
* skb_pull_rcsum - pull skb and update receive checksum
* @skb: buffer to update
- * @start: start of data before pull
* @len: length of data pulled
*
* This function performs an skb_pull on the packet and updates
- * update the CHECKSUM_COMPLETE checksum. It should be used on
+ * the CHECKSUM_COMPLETE checksum. It should be used on
* receive path processing instead of skb_pull unless you know
* that the checksum difference is zero (e.g., a valid IP header)
* or you are setting ip_summed to CHECKSUM_NONE.
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 19880b086e7..9c7e5ffb223 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -343,7 +343,7 @@ config INET_ESP
tristate "IP: ESP transformation"
select XFRM
select CRYPTO
- select CRYPTO_AEAD
+ select CRYPTO_AUTHENC
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_CBC
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 9d4555ec0b5..8219b7e0968 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -96,7 +96,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
ah->reserved = 0;
ah->spi = x->id.spi;
- ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
+ ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output);
spin_lock_bh(&x->lock);
err = ah_mac_digest(ahp, skb, ah->auth_data);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index f282b26f63e..87490f7bb0f 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -752,6 +752,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
inet_del_ifa(in_dev, ifap, 0);
ifa->ifa_broadcast = 0;
ifa->ifa_anycast = 0;
+ ifa->ifa_scope = 0;
}
ifa->ifa_address = ifa->ifa_local = sin->sin_addr.s_addr;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 258d17631b4..091e6709f83 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -199,7 +199,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
}
esph->spi = x->id.spi;
- esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
+ esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output);
sg_init_table(sg, nfrags);
skb_to_sgvec(skb, sg,
@@ -210,7 +210,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
aead_givcrypt_set_assoc(req, asg, sizeof(*esph));
- aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq);
+ aead_givcrypt_set_giv(req, esph->enc_data,
+ XFRM_SKB_CB(skb)->seq.output);
ESP_SKB_CB(skb)->tmp = tmp;
err = crypto_aead_givencrypt(req);
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 76b9c684ccc..8d58d85dfac 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -372,7 +372,8 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key)
static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
{
struct fn_hash *table = (struct fn_hash *) tb->tb_data;
- struct fib_node *new_f, *f;
+ struct fib_node *new_f = NULL;
+ struct fib_node *f;
struct fib_alias *fa, *new_fa;
struct fn_zone *fz;
struct fib_info *fi;
@@ -496,7 +497,6 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
err = -ENOBUFS;
- new_f = NULL;
if (!f) {
new_f = kmem_cache_zalloc(fn_hash_kmem, GFP_KERNEL);
if (new_f == NULL)
@@ -512,7 +512,7 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
if (new_fa->fa_info != NULL) {
new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
if (new_fa == NULL)
- goto out_free_new_f;
+ goto out;
}
new_fa->fa_info = fi;
new_fa->fa_tos = tos;
@@ -540,9 +540,9 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
&cfg->fc_nlinfo, 0);
return 0;
-out_free_new_f:
- kmem_cache_free(fn_hash_kmem, new_f);
out:
+ if (new_f)
+ kmem_cache_free(fn_hash_kmem, new_f);
fib_release_info(fi);
return err;
}
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index f5fba3f71c0..1ff446d0fa8 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1762,11 +1762,9 @@ static struct leaf *trie_leafindex(struct trie *t, int index)
{
struct leaf *l = trie_firstleaf(t);
- while (index-- > 0) {
+ while (l && index-- > 0)
l = trie_nextleaf(l);
- if (!l)
- break;
- }
+
return l;
}
@@ -2461,6 +2459,84 @@ static const struct file_operations fib_trie_fops = {
.release = seq_release_net,
};
+struct fib_route_iter {
+ struct seq_net_private p;
+ struct trie *main_trie;
+ loff_t pos;
+ t_key key;
+};
+
+static struct leaf *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos)
+{
+ struct leaf *l = NULL;
+ struct trie *t = iter->main_trie;
+
+ /* use cache location of last found key */
+ if (iter->pos > 0 && pos >= iter->pos && (l = fib_find_node(t, iter->key)))
+ pos -= iter->pos;
+ else {
+ iter->pos = 0;
+ l = trie_firstleaf(t);
+ }
+
+ while (l && pos-- > 0) {
+ iter->pos++;
+ l = trie_nextleaf(l);
+ }
+
+ if (l)
+ iter->key = pos; /* remember it */
+ else
+ iter->pos = 0; /* forget it */
+
+ return l;
+}
+
+static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
+{
+ struct fib_route_iter *iter = seq->private;
+ struct fib_table *tb;
+
+ rcu_read_lock();
+ tb = fib_get_table(iter->p.net, RT_TABLE_MAIN);
+ if (!tb)
+ return NULL;
+
+ iter->main_trie = (struct trie *) tb->tb_data;
+ if (*pos == 0)
+ return SEQ_START_TOKEN;
+ else
+ return fib_route_get_idx(iter, *pos - 1);
+}
+
+static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct fib_route_iter *iter = seq->private;
+ struct leaf *l = v;
+
+ ++*pos;
+ if (v == SEQ_START_TOKEN) {
+ iter->pos = 0;
+ l = trie_firstleaf(iter->main_trie);
+ } else {
+ iter->pos++;
+ l = trie_nextleaf(l);
+ }
+
+ if (l)
+ iter->key = l->key;
+ else
+ iter->pos = 0;
+ return l;
+}
+
+static void fib_route_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
+{
+ rcu_read_unlock();
+}
+
static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
{
static unsigned type2flags[RTN_MAX + 1] = {
@@ -2484,7 +2560,6 @@ static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
*/
static int fib_route_seq_show(struct seq_file *seq, void *v)
{
- const struct fib_trie_iter *iter = seq->private;
struct leaf *l = v;
struct leaf_info *li;
struct hlist_node *node;
@@ -2496,12 +2571,6 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
return 0;
}
- if (iter->trie == iter->trie_local)
- return 0;
-
- if (IS_TNODE(l))
- return 0;
-
hlist_for_each_entry_rcu(li, node, &l->list, hlist) {
struct fib_alias *fa;
__be32 mask, prefix;
@@ -2544,16 +2613,16 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
}
static const struct seq_operations fib_route_seq_ops = {
- .start = fib_trie_seq_start,
- .next = fib_trie_seq_next,
- .stop = fib_trie_seq_stop,
+ .start = fib_route_seq_start,
+ .next = fib_route_seq_next,
+ .stop = fib_route_seq_stop,
.show = fib_route_seq_show,
};
static int fib_route_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &fib_route_seq_ops,
- sizeof(struct fib_trie_iter));
+ sizeof(struct fib_route_iter));
}
static const struct file_operations fib_route_fops = {
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 9cac6c034ab..1aba606f6bb 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -120,8 +120,6 @@ void inet_listen_wlock(struct inet_hashinfo *hashinfo)
}
}
-EXPORT_SYMBOL(inet_listen_wlock);
-
/*
* Don't inline this cruft. Here are some nice properties to exploit here. The
* BSD API does not allow a listening sock to specify the remote port nor the
@@ -494,7 +492,6 @@ out:
return ret;
}
}
-EXPORT_SYMBOL_GPL(__inet_hash_connect);
/*
* Bind a port for a connect operation and hash it.
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 63f69171935..e7821ba7a9a 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -259,35 +259,31 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
if (parms->name[0])
strlcpy(name, parms->name, IFNAMSIZ);
- else {
- int i;
- for (i=1; i<100; i++) {
- sprintf(name, "gre%d", i);
- if (__dev_get_by_name(&init_net, name) == NULL)
- break;
- }
- if (i==100)
- goto failed;
- }
+ else
+ sprintf(name, "gre%%d");
dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup);
if (!dev)
return NULL;
+ if (strchr(name, '%')) {
+ if (dev_alloc_name(dev, name) < 0)
+ goto failed_free;
+ }
+
dev->init = ipgre_tunnel_init;
nt = netdev_priv(dev);
nt->parms = *parms;
- if (register_netdevice(dev) < 0) {
- free_netdev(dev);
- goto failed;
- }
+ if (register_netdevice(dev) < 0)
+ goto failed_free;
dev_hold(dev);
ipgre_tunnel_link(nt);
return nt;
-failed:
+failed_free:
+ free_netdev(dev);
return NULL;
}
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 754b0a5bbfe..de0572c8885 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -514,11 +514,6 @@ static int do_ip_setsockopt(struct sock *sk, int level,
val &= ~3;
val |= inet->tos & 3;
}
- if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP &&
- !capable(CAP_NET_ADMIN)) {
- err = -EPERM;
- break;
- }
if (inet->tos != val) {
inet->tos = val;
sk->sk_priority = rt_tos2priority(val);
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index ae1f45fc23b..58b60b2fb01 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -108,8 +108,11 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb)
const int cpu = get_cpu();
u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu);
struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu);
- int err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
+ int err;
+ local_bh_disable();
+ err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
+ local_bh_enable();
if (err)
goto out;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index a52b5853aaa..5dd938579ee 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -753,9 +753,9 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
b->htype = dev->type; /* can cause undefined behavior */
}
+
+ /* server_ip and your_ip address are both already zero per RFC2131 */
b->hlen = dev->addr_len;
- b->your_ip = NONE;
- b->server_ip = NONE;
memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
b->secs = htons(jiffies_diff / HZ);
b->xid = d->xid;
@@ -1390,7 +1390,7 @@ static int __init ip_auto_config(void)
* Clue in the operator.
*/
printk("IP-Config: Complete:");
- printk("\n device=%s", ic_dev->name);
+ printk("\n device=%s", ic_dev->name);
printk(", addr=%u.%u.%u.%u", NIPQUAD(ic_myaddr));
printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask));
printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway));
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index da281581692..dbaed69de06 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -221,35 +221,31 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c
if (parms->name[0])
strlcpy(name, parms->name, IFNAMSIZ);
- else {
- int i;
- for (i=1; i<100; i++) {
- sprintf(name, "tunl%d", i);
- if (__dev_get_by_name(&init_net, name) == NULL)
- break;
- }
- if (i==100)
- goto failed;
- }
+ else
+ sprintf(name, "tunl%%d");
dev = alloc_netdev(sizeof(*t), name, ipip_tunnel_setup);
if (dev == NULL)
return NULL;
+ if (strchr(name, '%')) {
+ if (dev_alloc_name(dev, name) < 0)
+ goto failed_free;
+ }
+
nt = netdev_priv(dev);
dev->init = ipip_tunnel_init;
nt->parms = *parms;
- if (register_netdevice(dev) < 0) {
- free_netdev(dev);
- goto failed;
- }
+ if (register_netdevice(dev) < 0)
+ goto failed_free;
dev_hold(dev);
ipip_tunnel_link(nt);
return nt;
-failed:
+failed_free:
+ free_netdev(dev);
return NULL;
}
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index 45fa4e20094..3f4222b0a80 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -19,7 +19,7 @@ target(struct sk_buff *skb,
unsigned char *arpptr;
int pln, hln;
- if (skb_make_writable(skb, skb->len))
+ if (!skb_make_writable(skb, skb->len))
return NF_DROP;
arp = arp_hdr(skb);
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 6bda1102851..fe05da41d6b 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -283,8 +283,8 @@ static int
ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
{
int diff;
- int err;
struct iphdr *user_iph = (struct iphdr *)v->payload;
+ struct sk_buff *nskb;
if (v->data_len < sizeof(*user_iph))
return 0;
@@ -296,14 +296,16 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
if (v->data_len > 0xFFFF)
return -EINVAL;
if (diff > skb_tailroom(e->skb)) {
- err = pskb_expand_head(e->skb, 0,
+ nskb = skb_copy_expand(e->skb, 0,
diff - skb_tailroom(e->skb),
GFP_ATOMIC);
- if (err) {
+ if (!nskb) {
printk(KERN_WARNING "ip_queue: error "
- "in mangle, dropping packet: %d\n", -err);
- return err;
+ "in mangle, dropping packet\n");
+ return -ENOMEM;
}
+ kfree_skb(e->skb);
+ e->skb = nskb;
}
skb_put(e->skb, diff);
}
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 525787b52b7..7b5e8e1d94b 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -542,12 +542,11 @@ static __init int ip_rt_proc_init(struct net *net)
if (!pde)
goto err1;
- pde = create_proc_entry("rt_cache", S_IRUGO, net->proc_net_stat);
+ pde = proc_create("rt_cache", S_IRUGO,
+ net->proc_net_stat, &rt_cpu_seq_fops);
if (!pde)
goto err2;
- pde->proc_fops = &rt_cpu_seq_fops;
-
#ifdef CONFIG_NET_CLS_ROUTE
pde = create_proc_read_entry("rt_acct", 0, net->proc_net,
ip_rt_acct_read, NULL);
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
index 5212ed9b0c9..7eb7636db0d 100644
--- a/net/ipv4/tcp_bic.c
+++ b/net/ipv4/tcp_bic.c
@@ -1,12 +1,13 @@
/*
* Binary Increase Congestion control for TCP
- *
+ * Home page:
+ * http://netsrv.csc.ncsu.edu/twiki/bin/view/Main/BIC
* This is from the implementation of BICTCP in
* Lison-Xu, Kahaled Harfoush, and Injong Rhee.
* "Binary Increase Congestion Control for Fast, Long Distance
* Networks" in InfoComm 2004
* Available from:
- * http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf
+ * http://netsrv.csc.ncsu.edu/export/bitcp.pdf
*
* Unless BIC is enabled and congestion window is large
* this behaves the same as the original Reno.
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 19c449f6267..7facdb0f696 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1367,7 +1367,7 @@ static struct sk_buff *tcp_sacktag_walk(struct sk_buff *skb, struct sock *sk,
* a normal way
*/
static struct sk_buff *tcp_sacktag_skip(struct sk_buff *skb, struct sock *sk,
- u32 skip_to_seq)
+ u32 skip_to_seq, int *fack_count)
{
tcp_for_write_queue_from(skb, sk) {
if (skb == tcp_send_head(sk))
@@ -1375,6 +1375,8 @@ static struct sk_buff *tcp_sacktag_skip(struct sk_buff *skb, struct sock *sk,
if (!before(TCP_SKB_CB(skb)->end_seq, skip_to_seq))
break;
+
+ *fack_count += tcp_skb_pcount(skb);
}
return skb;
}
@@ -1390,7 +1392,7 @@ static struct sk_buff *tcp_maybe_skipping_dsack(struct sk_buff *skb,
return skb;
if (before(next_dup->start_seq, skip_to_seq)) {
- skb = tcp_sacktag_skip(skb, sk, next_dup->start_seq);
+ skb = tcp_sacktag_skip(skb, sk, next_dup->start_seq, fack_count);
tcp_sacktag_walk(skb, sk, NULL,
next_dup->start_seq, next_dup->end_seq,
1, fack_count, reord, flag);
@@ -1537,7 +1539,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb,
/* Head todo? */
if (before(start_seq, cache->start_seq)) {
- skb = tcp_sacktag_skip(skb, sk, start_seq);
+ skb = tcp_sacktag_skip(skb, sk, start_seq,
+ &fack_count);
skb = tcp_sacktag_walk(skb, sk, next_dup,
start_seq,
cache->start_seq,
@@ -1565,7 +1568,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb,
goto walk;
}
- skb = tcp_sacktag_skip(skb, sk, cache->end_seq);
+ skb = tcp_sacktag_skip(skb, sk, cache->end_seq,
+ &fack_count);
/* Check overlap against next cached too (past this one already) */
cache++;
continue;
@@ -1577,7 +1581,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb,
break;
fack_count = tp->fackets_out;
}
- skb = tcp_sacktag_skip(skb, sk, start_seq);
+ skb = tcp_sacktag_skip(skb, sk, start_seq, &fack_count);
walk:
skb = tcp_sacktag_walk(skb, sk, next_dup, start_seq, end_seq,
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 63414ea427c..00156bf421c 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -719,7 +719,7 @@ static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
}
/*
- * Send a SYN-ACK after having received an ACK.
+ * Send a SYN-ACK after having received a SYN.
* This still operates on a request_sock only, not on a big
* socket.
*/
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 3ffb0323668..58219dfffef 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -85,7 +85,7 @@ config INET6_ESP
depends on IPV6
select XFRM
select CRYPTO
- select CRYPTO_AEAD
+ select CRYPTO_AUTHENC
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_CBC
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e40213db9e4..101e0e70ba2 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1557,6 +1557,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
.fc_expires = expires,
.fc_dst_len = plen,
.fc_flags = RTF_UP | flags,
+ .fc_nlinfo.nl_net = &init_net,
};
ipv6_addr_copy(&cfg.fc_dst, pfx);
@@ -1583,6 +1584,7 @@ static void addrconf_add_mroute(struct net_device *dev)
.fc_ifindex = dev->ifindex,
.fc_dst_len = 8,
.fc_flags = RTF_UP,
+ .fc_nlinfo.nl_net = &init_net,
};
ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
@@ -1599,6 +1601,7 @@ static void sit_route_add(struct net_device *dev)
.fc_ifindex = dev->ifindex,
.fc_dst_len = 96,
.fc_flags = RTF_UP | RTF_NONEXTHOP,
+ .fc_nlinfo.nl_net = &init_net,
};
/* prefix length - 96 bits "::d.d.d.d" */
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index bddac0e8780..f0aa9773874 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -752,14 +752,6 @@ static int __init inet6_init(void)
BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb));
-#ifdef MODULE
-#if 0 /* FIXME --RR */
- if (!mod_member_present(&__this_module, can_unload))
- return -EINVAL;
-
- __this_module.can_unload = &ipv6_unload;
-#endif
-#endif
err = proto_register(&tcpv6_prot, 1);
if (err)
goto out;
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 379c8e04c36..2ff0c8233e4 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -283,7 +283,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
ah->reserved = 0;
ah->spi = x->id.spi;
- ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
+ ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output);
spin_lock_bh(&x->lock);
err = ah_mac_digest(ahp, skb, ah->auth_data);
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 8e0f1428c71..0ec1402320e 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -188,7 +188,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
*skb_mac_header(skb) = IPPROTO_ESP;
esph->spi = x->id.spi;
- esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
+ esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output);
sg_init_table(sg, nfrags);
skb_to_sgvec(skb, sg,
@@ -199,7 +199,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
aead_givcrypt_set_assoc(req, asg, sizeof(*esph));
- aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq);
+ aead_givcrypt_set_giv(req, esph->enc_data,
+ XFRM_SKB_CB(skb)->seq.output);
ESP_SKB_CB(skb)->tmp = tmp;
err = crypto_aead_givencrypt(req);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index f93407cf651..bab72b6f144 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1151,7 +1151,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
fn = fn->parent;
}
/* No more references are possible at this point. */
- if (atomic_read(&rt->rt6i_ref) != 1) BUG();
+ BUG_ON(atomic_read(&rt->rt6i_ref) != 1);
}
inet6_rt_notify(RTM_DELROUTE, rt, info);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 9ac6ca2521c..8b67ca07467 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -621,7 +621,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
* or if the skb it not generated by a local socket. (This last
* check should be redundant, but it's free.)
*/
- if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) {
+ if (!skb->local_df) {
skb->dev = skb->dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
@@ -1420,6 +1420,10 @@ int ip6_push_pending_frames(struct sock *sk)
tmp_skb->sk = NULL;
}
+ /* Allow local fragmentation. */
+ if (np->pmtudisc < IPV6_PMTUDISC_DO)
+ skb->local_df = 1;
+
ipv6_addr_copy(final_dst, &fl->fl6_dst);
__skb_pull(skb, skb_network_header_len(skb));
if (opt && opt->opt_flen)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 9031e521c1d..78f43888092 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -229,33 +229,33 @@ static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p)
char name[IFNAMSIZ];
int err;
- if (p->name[0]) {
+ if (p->name[0])
strlcpy(name, p->name, IFNAMSIZ);
- } else {
- int i;
- for (i = 1; i < IP6_TNL_MAX; i++) {
- sprintf(name, "ip6tnl%d", i);
- if (__dev_get_by_name(&init_net, name) == NULL)
- break;
- }
- if (i == IP6_TNL_MAX)
- goto failed;
- }
+ else
+ sprintf(name, "ip6tnl%%d");
+
dev = alloc_netdev(sizeof (*t), name, ip6_tnl_dev_setup);
if (dev == NULL)
goto failed;
+ if (strchr(name, '%')) {
+ if (dev_alloc_name(dev, name) < 0)
+ goto failed_free;
+ }
+
t = netdev_priv(dev);
dev->init = ip6_tnl_dev_init;
t->parms = *p;
- if ((err = register_netdevice(dev)) < 0) {
- free_netdev(dev);
- goto failed;
- }
+ if ((err = register_netdevice(dev)) < 0)
+ goto failed_free;
+
dev_hold(dev);
ip6_tnl_link(t);
return t;
+
+failed_free:
+ free_netdev(dev);
failed:
return NULL;
}
@@ -550,6 +550,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
ip_rt_put(rt);
goto out;
}
+ skb2->dst = (struct dst_entry *)rt;
} else {
ip_rt_put(rt);
if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos,
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index b90039593a7..e3dcfa2f436 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -146,7 +146,9 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
scratch = *per_cpu_ptr(ipcomp6_scratches, cpu);
tfm = *per_cpu_ptr(ipcd->tfms, cpu);
+ local_bh_disable();
err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
+ local_bh_enable();
if (err || (dlen + sizeof(*ipch)) >= plen) {
put_cpu();
goto out_ok;
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index e869916b05f..cc2f9afcf80 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -285,8 +285,8 @@ static int
ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
{
int diff;
- int err;
struct ipv6hdr *user_iph = (struct ipv6hdr *)v->payload;
+ struct sk_buff *nskb;
if (v->data_len < sizeof(*user_iph))
return 0;
@@ -298,14 +298,16 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
if (v->data_len > 0xFFFF)
return -EINVAL;
if (diff > skb_tailroom(e->skb)) {
- err = pskb_expand_head(e->skb, 0,
+ nskb = skb_copy_expand(e->skb, 0,
diff - skb_tailroom(e->skb),
GFP_ATOMIC);
- if (err) {
+ if (!nskb) {
printk(KERN_WARNING "ip6_queue: OOM "
"in mangle, dropping packet\n");
- return err;
+ return -ENOMEM;
}
+ kfree_skb(e->skb);
+ e->skb = nskb;
}
skb_put(e->skb, diff);
}
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 35e502a7249..199ef379e50 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -217,12 +217,12 @@ int snmp6_register_dev(struct inet6_dev *idev)
if (!proc_net_devsnmp6)
return -ENOENT;
- p = create_proc_entry(idev->dev->name, S_IRUGO, proc_net_devsnmp6);
+ p = proc_create(idev->dev->name, S_IRUGO,
+ proc_net_devsnmp6, &snmp6_seq_fops);
if (!p)
return -ENOMEM;
p->data = idev;
- p->proc_fops = &snmp6_seq_fops;
idev->stats.proc_dir_entry = p;
return 0;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 6e7b56ef444..e8b241cb60b 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1719,6 +1719,8 @@ static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg,
cfg->fc_src_len = rtmsg->rtmsg_src_len;
cfg->fc_flags = rtmsg->rtmsg_flags;
+ cfg->fc_nlinfo.nl_net = &init_net;
+
ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst);
ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src);
ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index e77239d02bf..1656c003b98 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -164,21 +164,18 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
if (parms->name[0])
strlcpy(name, parms->name, IFNAMSIZ);
- else {
- int i;
- for (i=1; i<100; i++) {
- sprintf(name, "sit%d", i);
- if (__dev_get_by_name(&init_net, name) == NULL)
- break;
- }
- if (i==100)
- goto failed;
- }
+ else
+ sprintf(name, "sit%%d");
dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup);
if (dev == NULL)
return NULL;
+ if (strchr(name, '%')) {
+ if (dev_alloc_name(dev, name) < 0)
+ goto failed_free;
+ }
+
nt = netdev_priv(dev);
dev->init = ipip6_tunnel_init;
nt->parms = *parms;
@@ -186,16 +183,16 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
if (parms->i_flags & SIT_ISATAP)
dev->priv_flags |= IFF_ISATAP;
- if (register_netdevice(dev) < 0) {
- free_netdev(dev);
- goto failed;
- }
+ if (register_netdevice(dev) < 0)
+ goto failed_free;
dev_hold(dev);
ipip6_tunnel_link(nt);
return nt;
+failed_free:
+ free_netdev(dev);
failed:
return NULL;
}
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 408691b777c..d6d3e68086f 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -102,9 +102,6 @@ static int ipv6_sysctl_net_init(struct net *net)
net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path,
ipv6_table);
if (!net->ipv6.sysctl.table)
- return -ENOMEM;
-
- if (!net->ipv6.sysctl.table)
goto out_ipv6_icmp_table;
err = 0;
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index b34c58c6565..79ccfb08073 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -36,7 +36,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
- if (skb->len > mtu) {
+ if (!skb->local_df && skb->len > mtu) {
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
ret = -EMSGSIZE;
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c
index d483a00dc42..5ed97ad0e2e 100644
--- a/net/ipx/ipx_proc.c
+++ b/net/ipx/ipx_proc.c
@@ -358,22 +358,19 @@ int __init ipx_proc_init(void)
if (!ipx_proc_dir)
goto out;
- p = create_proc_entry("interface", S_IRUGO, ipx_proc_dir);
+ p = proc_create("interface", S_IRUGO,
+ ipx_proc_dir, &ipx_seq_interface_fops);
if (!p)
goto out_interface;
- p->proc_fops = &ipx_seq_interface_fops;
- p = create_proc_entry("route", S_IRUGO, ipx_proc_dir);
+ p = proc_create("route", S_IRUGO, ipx_proc_dir, &ipx_seq_route_fops);
if (!p)
goto out_route;
- p->proc_fops = &ipx_seq_route_fops;
- p = create_proc_entry("socket", S_IRUGO, ipx_proc_dir);
+ p = proc_create("socket", S_IRUGO, ipx_proc_dir, &ipx_seq_socket_fops);
if (!p)
goto out_socket;
- p->proc_fops = &ipx_seq_socket_fops;
-
rc = 0;
out:
return rc;
diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c
index b825399fc16..6eef1f2a755 100644
--- a/net/irda/ircomm/ircomm_core.c
+++ b/net/irda/ircomm/ircomm_core.c
@@ -76,9 +76,11 @@ static int __init ircomm_init(void)
#ifdef CONFIG_PROC_FS
{ struct proc_dir_entry *ent;
- ent = create_proc_entry("ircomm", 0, proc_irda);
- if (ent)
- ent->proc_fops = &ircomm_proc_fops;
+ ent = proc_create("ircomm", 0, proc_irda, &ircomm_proc_fops);
+ if (!ent) {
+ printk(KERN_ERR "ircomm_init: can't create /proc entry!\n");
+ return -ENODEV;
+ }
}
#endif /* CONFIG_PROC_FS */
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index a4b56e25a91..1eb4bbcb1c9 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -128,13 +128,11 @@ static int __init irlan_init(void)
#ifdef CONFIG_PROC_FS
{ struct proc_dir_entry *proc;
- proc = create_proc_entry("irlan", 0, proc_irda);
+ proc = proc_create("irlan", 0, proc_irda, &irlan_fops);
if (!proc) {
printk(KERN_ERR "irlan_init: can't create /proc entry!\n");
return -ENODEV;
}
-
- proc->proc_fops = &irlan_fops;
}
#endif /* CONFIG_PROC_FS */
diff --git a/net/irda/irproc.c b/net/irda/irproc.c
index cae24fbda96..88e80a31273 100644
--- a/net/irda/irproc.c
+++ b/net/irda/irproc.c
@@ -72,11 +72,9 @@ void __init irda_proc_register(void)
return;
proc_irda->owner = THIS_MODULE;
- for (i=0; i<ARRAY_SIZE(irda_dirs); i++) {
- d = create_proc_entry(irda_dirs[i].name, 0, proc_irda);
- if (d)
- d->proc_fops = irda_dirs[i].fops;
- }
+ for (i = 0; i < ARRAY_SIZE(irda_dirs); i++)
+ d = proc_create(irda_dirs[i].name, 0, proc_irda,
+ irda_dirs[i].fops);
}
/*
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index 2753b0c448f..d764f4c1b7e 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -621,7 +621,6 @@ static int iucv_sever_pathid(u16 pathid, u8 userdata[16])
return iucv_call_b2f0(IUCV_SEVER, parm);
}
-#ifdef CONFIG_SMP
/**
* __iucv_cleanup_queue
* @dummy: unused dummy argument
@@ -632,7 +631,6 @@ static int iucv_sever_pathid(u16 pathid, u8 userdata[16])
static void __iucv_cleanup_queue(void *dummy)
{
}
-#endif
/**
* iucv_cleanup_queue
diff --git a/net/key/af_key.c b/net/key/af_key.c
index b3ac85e808a..8b5f486ac80 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2291,6 +2291,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
return 0;
out:
+ xp->dead = 1;
xfrm_policy_destroy(xp);
return err;
}
@@ -3806,17 +3807,16 @@ static int pfkey_init_proc(void)
{
struct proc_dir_entry *e;
- e = create_proc_entry("pfkey", 0, init_net.proc_net);
+ e = proc_net_fops_create(&init_net, "pfkey", 0, &pfkey_proc_ops);
if (e == NULL)
return -ENOMEM;
- e->proc_fops = &pfkey_proc_ops;
return 0;
}
static void pfkey_exit_proc(void)
{
- remove_proc_entry("net/pfkey", NULL);
+ proc_net_remove(&init_net, "pfkey");
}
#else
static inline int pfkey_init_proc(void)
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c
index cb34bc0518e..48212c0a961 100644
--- a/net/llc/llc_proc.c
+++ b/net/llc/llc_proc.c
@@ -239,18 +239,14 @@ int __init llc_proc_init(void)
goto out;
llc_proc_dir->owner = THIS_MODULE;
- p = create_proc_entry("socket", S_IRUGO, llc_proc_dir);
+ p = proc_create("socket", S_IRUGO, llc_proc_dir, &llc_seq_socket_fops);
if (!p)
goto out_socket;
- p->proc_fops = &llc_seq_socket_fops;
-
- p = create_proc_entry("core", S_IRUGO, llc_proc_dir);
+ p = proc_create("core", S_IRUGO, llc_proc_dir, &llc_seq_core_fops);
if (!p)
goto out_core;
- p->proc_fops = &llc_seq_core_fops;
-
rc = 0;
out:
return rc;
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 67b7c75c430..28bcdf9fc3d 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -165,6 +165,7 @@ static int ieee80211_open(struct net_device *dev)
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_if_init_conf conf;
int res;
+ bool need_hw_reconfig = 0;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -218,7 +219,7 @@ static int ieee80211_open(struct net_device *dev)
res = local->ops->start(local_to_hw(local));
if (res)
return res;
- ieee80211_hw_config(local);
+ need_hw_reconfig = 1;
ieee80211_led_radio(local, local->hw.conf.radio_enabled);
}
@@ -282,6 +283,8 @@ static int ieee80211_open(struct net_device *dev)
atomic_inc(&local->iff_promiscs);
local->open_count++;
+ if (need_hw_reconfig)
+ ieee80211_hw_config(local);
netif_start_queue(dev);
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 2019b4f0528..9aeed532022 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -1116,9 +1116,10 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
/* prepare reordering buffer */
tid_agg_rx->reorder_buf =
kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC);
- if ((!tid_agg_rx->reorder_buf) && net_ratelimit()) {
- printk(KERN_ERR "can not allocate reordering buffer "
- "to tid %d\n", tid);
+ if (!tid_agg_rx->reorder_buf) {
+ if (net_ratelimit())
+ printk(KERN_ERR "can not allocate reordering buffer "
+ "to tid %d\n", tid);
goto end;
}
memset(tid_agg_rx->reorder_buf, 0,
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index c339571632b..3b77410588e 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -2,7 +2,7 @@
* Copyright 2002-2005, Instant802 Networks, Inc.
* Copyright 2005, Devicescape Software, Inc.
* Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
- * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
+ * Copyright 2007-2008, Stefano Brivio <stefano.brivio@polimi.it>
*
* 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
@@ -63,72 +63,66 @@
* RC_PID_ARITH_SHIFT.
*/
-
-/* Shift the adjustment so that we won't switch to a lower rate if it exhibited
- * a worse failed frames behaviour and we'll choose the highest rate whose
- * failed frames behaviour is not worse than the one of the original rate
- * target. While at it, check that the adjustment is within the ranges. Then,
- * provide the new rate index. */
-static int rate_control_pid_shift_adjust(struct rc_pid_rateinfo *r,
- int adj, int cur, int l)
-{
- int i, j, k, tmp;
-
- j = r[cur].rev_index;
- i = j + adj;
-
- if (i < 0)
- return r[0].index;
- if (i >= l - 1)
- return r[l - 1].index;
-
- tmp = i;
-
- if (adj < 0) {
- for (k = j; k >= i; k--)
- if (r[k].diff <= r[j].diff)
- tmp = k;
- } else {
- for (k = i + 1; k + i < l; k++)
- if (r[k].diff <= r[i].diff)
- tmp = k;
- }
-
- return r[tmp].index;
-}
-
+/* Adjust the rate while ensuring that we won't switch to a lower rate if it
+ * exhibited a worse failed frames behaviour and we'll choose the highest rate
+ * whose failed frames behaviour is not worse than the one of the original rate
+ * target. While at it, check that the new rate is valid. */
static void rate_control_pid_adjust_rate(struct ieee80211_local *local,
struct sta_info *sta, int adj,
struct rc_pid_rateinfo *rinfo)
{
struct ieee80211_sub_if_data *sdata;
struct ieee80211_hw_mode *mode;
- int newidx;
- int maxrate;
- int back = (adj > 0) ? 1 : -1;
+ int cur_sorted, new_sorted, probe, tmp, n_bitrates;
+ int cur = sta->txrate;
sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
mode = local->oper_hw_mode;
- maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1;
+ n_bitrates = mode->num_rates;
- newidx = rate_control_pid_shift_adjust(rinfo, adj, sta->txrate,
- mode->num_rates);
+ /* Map passed arguments to sorted values. */
+ cur_sorted = rinfo[cur].rev_index;
+ new_sorted = cur_sorted + adj;
- while (newidx != sta->txrate) {
- if (rate_supported(sta, mode, newidx) &&
- (maxrate < 0 || newidx <= maxrate)) {
- sta->txrate = newidx;
- break;
- }
+ /* Check limits. */
+ if (new_sorted < 0)
+ new_sorted = rinfo[0].rev_index;
+ else if (new_sorted >= n_bitrates)
+ new_sorted = rinfo[n_bitrates - 1].rev_index;
- newidx += back;
+ tmp = new_sorted;
+
+ if (adj < 0) {
+ /* Ensure that the rate decrease isn't disadvantageous. */
+ for (probe = cur_sorted; probe >= new_sorted; probe--)
+ if (rinfo[probe].diff <= rinfo[cur_sorted].diff &&
+ rate_supported(sta, mode, rinfo[probe].index))
+ tmp = probe;
+ } else {
+ /* Look for rate increase with zero (or below) cost. */
+ for (probe = new_sorted + 1; probe < n_bitrates; probe++)
+ if (rinfo[probe].diff <= rinfo[new_sorted].diff &&
+ rate_supported(sta, mode, rinfo[probe].index))
+ tmp = probe;
}
+ /* Fit the rate found to the nearest supported rate. */
+ do {
+ if (rate_supported(sta, mode, rinfo[tmp].index)) {
+ sta->txrate = rinfo[tmp].index;
+ break;
+ }
+ if (adj < 0)
+ tmp--;
+ else
+ tmp++;
+ } while (tmp < n_bitrates && tmp >= 0);
+
#ifdef CONFIG_MAC80211_DEBUGFS
rate_control_pid_event_rate_change(
&((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events,
- newidx, mode->rates[newidx].rate);
+ cur, mode->rates[cur].rate);
#endif
}
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 327e847d270..b77eb56a87e 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -256,13 +256,19 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple)
struct hlist_node *n;
unsigned int hash = hash_conntrack(tuple);
+ /* Disable BHs the entire time since we normally need to disable them
+ * at least once for the stats anyway.
+ */
+ local_bh_disable();
hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
if (nf_ct_tuple_equal(tuple, &h->tuple)) {
NF_CT_STAT_INC(found);
+ local_bh_enable();
return h;
}
NF_CT_STAT_INC(searched);
}
+ local_bh_enable();
return NULL;
}
@@ -400,17 +406,20 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
struct hlist_node *n;
unsigned int hash = hash_conntrack(tuple);
- rcu_read_lock();
+ /* Disable BHs the entire time since we need to disable them at
+ * least once for the stats anyway.
+ */
+ rcu_read_lock_bh();
hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
nf_ct_tuple_equal(tuple, &h->tuple)) {
NF_CT_STAT_INC(found);
- rcu_read_unlock();
+ rcu_read_unlock_bh();
return 1;
}
NF_CT_STAT_INC(searched);
}
- rcu_read_unlock();
+ rcu_read_unlock_bh();
return 0;
}
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 202d7fa0948..62567959b66 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -945,7 +945,7 @@ static int tcp_packet(struct nf_conn *ct,
ct->proto.tcp.state = new_state;
if (old_state != new_state
- && new_state == TCP_CONNTRACK_CLOSE)
+ && new_state == TCP_CONNTRACK_FIN_WAIT)
ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
timeout = ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans
&& tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index a48b20fe9cd..0043d3a9f87 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -443,8 +443,8 @@ err_out:
static int
nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e)
{
+ struct sk_buff *nskb;
int diff;
- int err;
diff = data_len - e->skb->len;
if (diff < 0) {
@@ -454,14 +454,16 @@ nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e)
if (data_len > 0xFFFF)
return -EINVAL;
if (diff > skb_tailroom(e->skb)) {
- err = pskb_expand_head(e->skb, 0,
+ nskb = skb_copy_expand(e->skb, 0,
diff - skb_tailroom(e->skb),
GFP_ATOMIC);
- if (err) {
+ if (!nskb) {
printk(KERN_WARNING "nf_queue: OOM "
"in mangle, dropping packet\n");
- return err;
+ return -ENOMEM;
}
+ kfree_skb(e->skb);
+ e->skb = nskb;
}
skb_put(e->skb, diff);
}
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 7708e2084ce..c0284856ccd 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -111,7 +111,7 @@ secmark_tg_check(const char *tablename, const void *entry,
return true;
}
-void secmark_tg_destroy(const struct xt_target *target, void *targinfo)
+static void secmark_tg_destroy(const struct xt_target *target, void *targinfo)
{
switch (mode) {
case SECMARK_MODE_SEL:
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 85330856a29..0c50b289405 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -122,7 +122,7 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr,
const union nf_inet_addr *umask, unsigned int l3proto)
{
if (l3proto == AF_INET)
- return (kaddr->ip & umask->ip) == uaddr->ip;
+ return ((kaddr->ip ^ uaddr->ip) & umask->ip) == 0;
else if (l3proto == AF_INET6)
return ipv6_masked_addr_cmp(&kaddr->in6, &umask->in6,
&uaddr->in6) == 0;
@@ -231,7 +231,7 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
if (test_bit(IPS_DST_NAT_BIT, &ct->status))
statebit |= XT_CONNTRACK_STATE_DNAT;
}
- if ((info->state_mask & statebit) ^
+ if (!!(info->state_mask & statebit) ^
!(info->invert_flags & XT_CONNTRACK_STATE))
return false;
}
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 744c7f2ab0b..5418ce59ac3 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -774,9 +774,6 @@ hashlimit_mt_check(const char *tablename, const void *inf,
return false;
}
mutex_unlock(&hlimit_mutex);
-
- /* Ugly hack: For SMP, we only want to use one set */
- info->master = info;
return true;
}
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index 4f984dc6031..500528d60cd 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -102,7 +102,7 @@ iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b)
int r;
for (i = 0; i < 4; ++i) {
- r = (__force u32)a->s6_addr32[i] - (__force u32)b->s6_addr32[i];
+ r = ntohl(a->s6_addr32[i]) - ntohl(b->s6_addr32[i]);
if (r != 0)
return r;
}
diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c
index 9b8ed390a8e..627e0f336d5 100644
--- a/net/netfilter/xt_u32.c
+++ b/net/netfilter/xt_u32.c
@@ -26,7 +26,6 @@ static bool u32_match_it(const struct xt_u32 *data,
u_int32_t pos;
u_int32_t val;
u_int32_t at;
- int ret;
/*
* Small example: "0 >> 28 == 4 && 8 & 0xFF0000 >> 16 = 6, 17"
@@ -40,8 +39,8 @@ static bool u32_match_it(const struct xt_u32 *data,
if (skb->len < 4 || pos > skb->len - 4)
return false;
- ret = skb_copy_bits(skb, pos, &n, sizeof(n));
- BUG_ON(ret < 0);
+ if (skb_copy_bits(skb, pos, &n, sizeof(n)) < 0)
+ BUG();
val = ntohl(n);
nnums = ct->nnums;
@@ -67,9 +66,9 @@ static bool u32_match_it(const struct xt_u32 *data,
pos > skb->len - at - 4)
return false;
- ret = skb_copy_bits(skb, at + pos, &n,
- sizeof(n));
- BUG_ON(ret < 0);
+ if (skb_copy_bits(skb, at + pos, &n,
+ sizeof(n)) < 0)
+ BUG();
val = ntohl(n);
break;
}
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index c7ad64d664a..fdc14a0d21a 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -718,36 +718,35 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
* NetLabel Generic NETLINK Command Definitions
*/
-static struct genl_ops netlbl_cipsov4_genl_c_add = {
+static struct genl_ops netlbl_cipsov4_ops[] = {
+ {
.cmd = NLBL_CIPSOV4_C_ADD,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_cipsov4_genl_policy,
.doit = netlbl_cipsov4_add,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_cipsov4_genl_c_remove = {
+ },
+ {
.cmd = NLBL_CIPSOV4_C_REMOVE,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_cipsov4_genl_policy,
.doit = netlbl_cipsov4_remove,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_cipsov4_genl_c_list = {
+ },
+ {
.cmd = NLBL_CIPSOV4_C_LIST,
.flags = 0,
.policy = netlbl_cipsov4_genl_policy,
.doit = netlbl_cipsov4_list,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_cipsov4_genl_c_listall = {
+ },
+ {
.cmd = NLBL_CIPSOV4_C_LISTALL,
.flags = 0,
.policy = netlbl_cipsov4_genl_policy,
.doit = NULL,
.dumpit = netlbl_cipsov4_listall,
+ },
};
/*
@@ -762,30 +761,20 @@ static struct genl_ops netlbl_cipsov4_genl_c_listall = {
* mechanism. Returns zero on success, negative values on failure.
*
*/
-int netlbl_cipsov4_genl_init(void)
+int __init netlbl_cipsov4_genl_init(void)
{
- int ret_val;
+ int ret_val, i;
ret_val = genl_register_family(&netlbl_cipsov4_gnl_family);
if (ret_val != 0)
return ret_val;
- ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
- &netlbl_cipsov4_genl_c_add);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
- &netlbl_cipsov4_genl_c_remove);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
- &netlbl_cipsov4_genl_c_list);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
- &netlbl_cipsov4_genl_c_listall);
- if (ret_val != 0)
- return ret_val;
+ for (i = 0; i < ARRAY_SIZE(netlbl_cipsov4_ops); i++) {
+ ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
+ &netlbl_cipsov4_ops[i]);
+ if (ret_val != 0)
+ return ret_val;
+ }
return 0;
}
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index 9a8ea0195c4..02c2f7c0b25 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -150,11 +150,11 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
entry = netlbl_domhsh_search(domain);
if (entry == NULL) {
entry = rcu_dereference(netlbl_domhsh_def);
- if (entry != NULL && entry->valid)
- return entry;
+ if (entry != NULL && !entry->valid)
+ entry = NULL;
}
- return NULL;
+ return entry;
}
/*
@@ -171,7 +171,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
* values on error.
*
*/
-int netlbl_domhsh_init(u32 size)
+int __init netlbl_domhsh_init(u32 size)
{
u32 iter;
struct netlbl_domhsh_tbl *hsh_tbl;
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index e2258dc3c84..22c19126780 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -517,68 +517,63 @@ version_failure:
* NetLabel Generic NETLINK Command Definitions
*/
-static struct genl_ops netlbl_mgmt_genl_c_add = {
+static struct genl_ops netlbl_mgmt_genl_ops[] = {
+ {
.cmd = NLBL_MGMT_C_ADD,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_add,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_remove = {
+ },
+ {
.cmd = NLBL_MGMT_C_REMOVE,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_remove,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_listall = {
+ },
+ {
.cmd = NLBL_MGMT_C_LISTALL,
.flags = 0,
.policy = netlbl_mgmt_genl_policy,
.doit = NULL,
.dumpit = netlbl_mgmt_listall,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_adddef = {
+ },
+ {
.cmd = NLBL_MGMT_C_ADDDEF,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_adddef,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_removedef = {
+ },
+ {
.cmd = NLBL_MGMT_C_REMOVEDEF,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_removedef,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_listdef = {
+ },
+ {
.cmd = NLBL_MGMT_C_LISTDEF,
.flags = 0,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_listdef,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_protocols = {
+ },
+ {
.cmd = NLBL_MGMT_C_PROTOCOLS,
.flags = 0,
.policy = netlbl_mgmt_genl_policy,
.doit = NULL,
.dumpit = netlbl_mgmt_protocols,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_version = {
+ },
+ {
.cmd = NLBL_MGMT_C_VERSION,
.flags = 0,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_version,
.dumpit = NULL,
+ },
};
/*
@@ -593,46 +588,20 @@ static struct genl_ops netlbl_mgmt_genl_c_version = {
* mechanism. Returns zero on success, negative values on failure.
*
*/
-int netlbl_mgmt_genl_init(void)
+int __init netlbl_mgmt_genl_init(void)
{
- int ret_val;
+ int ret_val, i;
ret_val = genl_register_family(&netlbl_mgmt_gnl_family);
if (ret_val != 0)
return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_add);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_remove);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_listall);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_adddef);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_removedef);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_listdef);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_protocols);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_version);
- if (ret_val != 0)
- return ret_val;
+ for (i = 0; i < ARRAY_SIZE(netlbl_mgmt_genl_ops); i++) {
+ ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+ &netlbl_mgmt_genl_ops[i]);
+ if (ret_val != 0)
+ return ret_val;
+ }
return 0;
}
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 42e81fd8cc4..4478f2f6079 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -180,6 +180,7 @@ static void netlbl_unlabel_audit_addr4(struct audit_buffer *audit_buf,
}
}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
/**
* netlbl_unlabel_audit_addr6 - Audit an IPv6 address
* @audit_buf: audit buffer
@@ -213,6 +214,7 @@ static void netlbl_unlabel_audit_addr6(struct audit_buffer *audit_buf,
audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
}
}
+#endif /* IPv6 */
/*
* Unlabeled Connection Hash Table Functions
@@ -617,8 +619,6 @@ static int netlbl_unlhsh_add(struct net *net,
int ifindex;
struct net_device *dev;
struct netlbl_unlhsh_iface *iface;
- struct in_addr *addr4, *mask4;
- struct in6_addr *addr6, *mask6;
struct audit_buffer *audit_buf = NULL;
char *secctx = NULL;
u32 secctx_len;
@@ -651,7 +651,9 @@ static int netlbl_unlhsh_add(struct net *net,
audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD,
audit_info);
switch (addr_len) {
- case sizeof(struct in_addr):
+ case sizeof(struct in_addr): {
+ struct in_addr *addr4, *mask4;
+
addr4 = (struct in_addr *)addr;
mask4 = (struct in_addr *)mask;
ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid);
@@ -661,8 +663,11 @@ static int netlbl_unlhsh_add(struct net *net,
addr4->s_addr,
mask4->s_addr);
break;
+ }
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- case sizeof(struct in6_addr):
+ case sizeof(struct in6_addr): {
+ struct in6_addr *addr6, *mask6;
+
addr6 = (struct in6_addr *)addr;
mask6 = (struct in6_addr *)mask;
ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid);
@@ -671,6 +676,7 @@ static int netlbl_unlhsh_add(struct net *net,
dev_name,
addr6, mask6);
break;
+ }
#endif /* IPv6 */
default:
ret_val = -EINVAL;
@@ -1547,68 +1553,63 @@ unlabel_staticlistdef_return:
* NetLabel Generic NETLINK Command Definitions
*/
-static struct genl_ops netlbl_unlabel_genl_c_staticadd = {
+static struct genl_ops netlbl_unlabel_genl_ops[] = {
+ {
.cmd = NLBL_UNLABEL_C_STATICADD,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_staticadd,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_staticremove = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_STATICREMOVE,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_staticremove,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_staticlist = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_STATICLIST,
.flags = 0,
.policy = netlbl_unlabel_genl_policy,
.doit = NULL,
.dumpit = netlbl_unlabel_staticlist,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_staticadddef = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_STATICADDDEF,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_staticadddef,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_staticremovedef = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_STATICREMOVEDEF,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_staticremovedef,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_staticlistdef = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_STATICLISTDEF,
.flags = 0,
.policy = netlbl_unlabel_genl_policy,
.doit = NULL,
.dumpit = netlbl_unlabel_staticlistdef,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_accept = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_ACCEPT,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_accept,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_list = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_LIST,
.flags = 0,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_list,
.dumpit = NULL,
+ },
};
/*
@@ -1623,53 +1624,20 @@ static struct genl_ops netlbl_unlabel_genl_c_list = {
* mechanism. Returns zero on success, negative values on failure.
*
*/
-int netlbl_unlabel_genl_init(void)
+int __init netlbl_unlabel_genl_init(void)
{
- int ret_val;
+ int ret_val, i;
ret_val = genl_register_family(&netlbl_unlabel_gnl_family);
if (ret_val != 0)
return ret_val;
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticadd);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticremove);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticlist);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticadddef);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticremovedef);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticlistdef);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_accept);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_list);
- if (ret_val != 0)
- return ret_val;
+ for (i = 0; i < ARRAY_SIZE(netlbl_unlabel_genl_ops); i++) {
+ ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
+ &netlbl_unlabel_genl_ops[i]);
+ if (ret_val != 0)
+ return ret_val;
+ }
return 0;
}
@@ -1693,7 +1661,7 @@ static struct notifier_block netlbl_unlhsh_netdev_notifier = {
* non-zero values on error.
*
*/
-int netlbl_unlabel_init(u32 size)
+int __init netlbl_unlabel_init(u32 size)
{
u32 iter;
struct netlbl_unlhsh_tbl *hsh_tbl;
@@ -1741,10 +1709,6 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
u16 family,
struct netlbl_lsm_secattr *secattr)
{
- struct iphdr *hdr4;
- struct ipv6hdr *hdr6;
- struct netlbl_unlhsh_addr4 *addr4;
- struct netlbl_unlhsh_addr6 *addr6;
struct netlbl_unlhsh_iface *iface;
rcu_read_lock();
@@ -1752,21 +1716,29 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
if (iface == NULL)
goto unlabel_getattr_nolabel;
switch (family) {
- case PF_INET:
+ case PF_INET: {
+ struct iphdr *hdr4;
+ struct netlbl_unlhsh_addr4 *addr4;
+
hdr4 = ip_hdr(skb);
addr4 = netlbl_unlhsh_search_addr4(hdr4->saddr, iface);
if (addr4 == NULL)
goto unlabel_getattr_nolabel;
secattr->attr.secid = addr4->secid;
break;
+ }
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- case PF_INET6:
+ case PF_INET6: {
+ struct ipv6hdr *hdr6;
+ struct netlbl_unlhsh_addr6 *addr6;
+
hdr6 = ipv6_hdr(skb);
addr6 = netlbl_unlhsh_search_addr6(&hdr6->saddr, iface);
if (addr6 == NULL)
goto unlabel_getattr_nolabel;
secattr->attr.secid = addr6->secid;
break;
+ }
#endif /* IPv6 */
default:
goto unlabel_getattr_nolabel;
@@ -1793,7 +1765,7 @@ unlabel_getattr_nolabel:
* and to send unlabeled network traffic by default.
*
*/
-int netlbl_unlabel_defconf(void)
+int __init netlbl_unlabel_defconf(void)
{
int ret_val;
struct netlbl_dom_map *entry;
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 85a96a3fdda..b17d4203806 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -59,7 +59,7 @@
* non-zero on failure.
*
*/
-int netlbl_netlink_init(void)
+int __init netlbl_netlink_init(void)
{
int ret_val;
@@ -96,7 +96,6 @@ int netlbl_netlink_init(void)
struct audit_buffer *netlbl_audit_start_common(int type,
struct netlbl_audit *audit_info)
{
- struct audit_context *audit_ctx = current->audit_context;
struct audit_buffer *audit_buf;
char *secctx;
u32 secctx_len;
@@ -104,7 +103,7 @@ struct audit_buffer *netlbl_audit_start_common(int type,
if (audit_enabled == 0)
return NULL;
- audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type);
+ audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type);
if (audit_buf == NULL)
return NULL;
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 150579a2146..d16929c9b4b 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -230,10 +230,8 @@ static void genl_unregister_mc_groups(struct genl_family *family)
{
struct genl_multicast_group *grp, *tmp;
- genl_lock();
list_for_each_entry_safe(grp, tmp, &family->mcast_groups, list)
__genl_unregister_mc_group(family, grp);
- genl_unlock();
}
/**
@@ -396,10 +394,10 @@ int genl_unregister_family(struct genl_family *family)
{
struct genl_family *rc;
- genl_unregister_mc_groups(family);
-
genl_lock();
+ genl_unregister_mc_groups(family);
+
list_for_each_entry(rc, genl_family_chain(family->id), family_list) {
if (family->id != rc->id || strcmp(rc->name, family->name))
continue;
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 1a47f5d1be1..140a0a8c6b0 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -232,7 +232,7 @@ static int rfkill_suspend(struct device *dev, pm_message_t state)
struct rfkill *rfkill = to_rfkill(dev);
if (dev->power.power_state.event != state.event) {
- if (state.event == PM_EVENT_SUSPEND) {
+ if (state.event & PM_EVENT_SLEEP) {
mutex_lock(&rfkill->mutex);
if (rfkill->state == RFKILL_STATE_ON)
diff --git a/net/rxrpc/ar-accept.c b/net/rxrpc/ar-accept.c
index 92a87fde8bf..bdfb7741779 100644
--- a/net/rxrpc/ar-accept.c
+++ b/net/rxrpc/ar-accept.c
@@ -156,8 +156,7 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
false);
spin_unlock(&call->lock);
notification = NULL;
- if (ret < 0)
- BUG();
+ BUG_ON(ret < 0);
}
spin_unlock(&call->conn->state_lock);
diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c
index 657ee69f213..3ac1672e107 100644
--- a/net/rxrpc/ar-ack.c
+++ b/net/rxrpc/ar-ack.c
@@ -814,8 +814,7 @@ static int rxrpc_post_message(struct rxrpc_call *call, u32 mark, u32 error,
spin_lock_bh(&call->lock);
ret = rxrpc_queue_rcv_skb(call, skb, true, fatal);
spin_unlock_bh(&call->lock);
- if (ret < 0)
- BUG();
+ BUG_ON(ret < 0);
}
return 0;
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 8bb79f28177..675a5c3e68a 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -838,11 +838,11 @@ int sctp_auth_set_key(struct sctp_endpoint *ep,
}
/* Create a new key data based on the info passed in */
- key = sctp_auth_create_key(auth_key->sca_keylen, GFP_KERNEL);
+ key = sctp_auth_create_key(auth_key->sca_keylength, GFP_KERNEL);
if (!key)
goto nomem;
- memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylen);
+ memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylength);
/* If we are replacing, remove the old keys data from the
* key id. If we are adding new key id, add it to the
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 4d7ec961ae1..87f940587d5 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -966,7 +966,7 @@ static struct inet6_protocol sctpv6_protocol = {
.flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
};
-static struct sctp_af sctp_ipv6_specific = {
+static struct sctp_af sctp_af_inet6 = {
.sa_family = AF_INET6,
.sctp_xmit = sctp_v6_xmit,
.setsockopt = ipv6_setsockopt,
@@ -998,7 +998,7 @@ static struct sctp_af sctp_ipv6_specific = {
#endif
};
-static struct sctp_pf sctp_pf_inet6_specific = {
+static struct sctp_pf sctp_pf_inet6 = {
.event_msgname = sctp_inet6_event_msgname,
.skb_msgname = sctp_inet6_skb_msgname,
.af_supported = sctp_inet6_af_supported,
@@ -1008,7 +1008,7 @@ static struct sctp_pf sctp_pf_inet6_specific = {
.supported_addrs = sctp_inet6_supported_addrs,
.create_accept_sk = sctp_v6_create_accept_sk,
.addr_v4map = sctp_v6_addr_v4map,
- .af = &sctp_ipv6_specific,
+ .af = &sctp_af_inet6,
};
/* Initialize IPv6 support and register with socket layer. */
@@ -1017,10 +1017,10 @@ int sctp_v6_init(void)
int rc;
/* Register the SCTP specific PF_INET6 functions. */
- sctp_register_pf(&sctp_pf_inet6_specific, PF_INET6);
+ sctp_register_pf(&sctp_pf_inet6, PF_INET6);
/* Register the SCTP specific AF_INET6 functions. */
- sctp_register_af(&sctp_ipv6_specific);
+ sctp_register_af(&sctp_af_inet6);
rc = proto_register(&sctpv6_prot, 1);
if (rc)
@@ -1051,7 +1051,7 @@ void sctp_v6_exit(void)
inet6_unregister_protosw(&sctpv6_seqpacket_protosw);
inet6_unregister_protosw(&sctpv6_stream_protosw);
proto_unregister(&sctpv6_prot);
- list_del(&sctp_ipv6_specific.list);
+ list_del(&sctp_af_inet6.list);
}
/* Unregister with inet6 layer. */
diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c
index 14e294e3762..cfeb07ea1b0 100644
--- a/net/sctp/objcnt.c
+++ b/net/sctp/objcnt.c
@@ -132,12 +132,11 @@ void sctp_dbg_objcnt_init(void)
{
struct proc_dir_entry *ent;
- ent = create_proc_entry("sctp_dbg_objcnt", 0, proc_net_sctp);
+ ent = proc_create("sctp_dbg_objcnt", 0,
+ proc_net_sctp, &sctp_objcnt_ops);
if (!ent)
printk(KERN_WARNING
"sctp_dbg_objcnt: Unable to create /proc entry.\n");
- else
- ent->proc_fops = &sctp_objcnt_ops;
}
/* Cleanup the objcount entry in the proc filesystem. */
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 69bb5a63fd8..973f1dbc2ec 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -108,12 +108,10 @@ int __init sctp_snmp_proc_init(void)
{
struct proc_dir_entry *p;
- p = create_proc_entry("snmp", S_IRUGO, proc_net_sctp);
+ p = proc_create("snmp", S_IRUGO, proc_net_sctp, &sctp_snmp_seq_fops);
if (!p)
return -ENOMEM;
- p->proc_fops = &sctp_snmp_seq_fops;
-
return 0;
}
@@ -258,12 +256,10 @@ int __init sctp_eps_proc_init(void)
{
struct proc_dir_entry *p;
- p = create_proc_entry("eps", S_IRUGO, proc_net_sctp);
+ p = proc_create("eps", S_IRUGO, proc_net_sctp, &sctp_eps_seq_fops);
if (!p)
return -ENOMEM;
- p->proc_fops = &sctp_eps_seq_fops;
-
return 0;
}
@@ -369,12 +365,11 @@ int __init sctp_assocs_proc_init(void)
{
struct proc_dir_entry *p;
- p = create_proc_entry("assocs", S_IRUGO, proc_net_sctp);
+ p = proc_create("assocs", S_IRUGO, proc_net_sctp,
+ &sctp_assocs_seq_fops);
if (!p)
return -ENOMEM;
- p->proc_fops = &sctp_assocs_seq_fops;
-
return 0;
}
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 22a16571499..688546dccd8 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -832,7 +832,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb,
return ip_queue_xmit(skb, ipfragok);
}
-static struct sctp_af sctp_ipv4_specific;
+static struct sctp_af sctp_af_inet;
static struct sctp_pf sctp_pf_inet = {
.event_msgname = sctp_inet_event_msgname,
@@ -844,7 +844,7 @@ static struct sctp_pf sctp_pf_inet = {
.supported_addrs = sctp_inet_supported_addrs,
.create_accept_sk = sctp_v4_create_accept_sk,
.addr_v4map = sctp_v4_addr_v4map,
- .af = &sctp_ipv4_specific,
+ .af = &sctp_af_inet
};
/* Notifier for inetaddr addition/deletion events. */
@@ -906,7 +906,7 @@ static struct net_protocol sctp_protocol = {
};
/* IPv4 address related functions. */
-static struct sctp_af sctp_ipv4_specific = {
+static struct sctp_af sctp_af_inet = {
.sa_family = AF_INET,
.sctp_xmit = sctp_v4_xmit,
.setsockopt = ip_setsockopt,
@@ -1192,7 +1192,7 @@ SCTP_STATIC __init int sctp_init(void)
sctp_sysctl_register();
INIT_LIST_HEAD(&sctp_address_families);
- sctp_register_af(&sctp_ipv4_specific);
+ sctp_register_af(&sctp_af_inet);
status = proto_register(&sctp_prot, 1);
if (status)
@@ -1249,7 +1249,7 @@ err_v6_init:
proto_unregister(&sctp_prot);
err_proto_register:
sctp_sysctl_unregister();
- list_del(&sctp_ipv4_specific.list);
+ list_del(&sctp_af_inet.list);
free_pages((unsigned long)sctp_port_hashtable,
get_order(sctp_port_hashsize *
sizeof(struct sctp_bind_hashbucket)));
@@ -1299,7 +1299,7 @@ SCTP_STATIC __exit void sctp_exit(void)
inet_unregister_protosw(&sctp_seqpacket_protosw);
sctp_sysctl_unregister();
- list_del(&sctp_ipv4_specific.list);
+ list_del(&sctp_af_inet.list);
free_pages((unsigned long)sctp_assoc_hashtable,
get_order(sctp_assoc_hashsize *
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d47d5787e2e..939892691a2 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1964,7 +1964,7 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk,
static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
int optlen)
{
- if (optlen != sizeof(struct sctp_event_subscribe))
+ if (optlen > sizeof(struct sctp_event_subscribe))
return -EINVAL;
if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen))
return -EFAULT;
@@ -5070,6 +5070,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
struct sctp_authchunks val;
struct sctp_association *asoc;
struct sctp_chunks_param *ch;
+ u32 num_chunks;
char __user *to;
if (len <= sizeof(struct sctp_authchunks))
@@ -5086,12 +5087,15 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
ch = asoc->peer.peer_chunks;
/* See if the user provided enough room for all the data */
- if (len < ntohs(ch->param_hdr.length))
+ num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
+ if (len < num_chunks)
return -EINVAL;
- len = ntohs(ch->param_hdr.length);
+ len = num_chunks;
if (put_user(len, optlen))
return -EFAULT;
+ if (put_user(num_chunks, &p->gauth_number_of_chunks))
+ return -EFAULT;
if (copy_to_user(to, ch->chunks, len))
return -EFAULT;
@@ -5105,6 +5109,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
struct sctp_authchunks val;
struct sctp_association *asoc;
struct sctp_chunks_param *ch;
+ u32 num_chunks;
char __user *to;
if (len <= sizeof(struct sctp_authchunks))
@@ -5123,12 +5128,15 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
else
ch = sctp_sk(sk)->ep->auth_chunk_list;
- if (len < ntohs(ch->param_hdr.length))
+ num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
+ if (len < num_chunks)
return -EINVAL;
- len = ntohs(ch->param_hdr.length);
+ len = num_chunks;
if (put_user(len, optlen))
return -EFAULT;
+ if (put_user(num_chunks, &p->gauth_number_of_chunks))
+ return -EFAULT;
if (copy_to_user(to, ch->chunks, len))
return -EFAULT;
@@ -6488,6 +6496,7 @@ struct proto sctp_prot = {
.memory_pressure = &sctp_memory_pressure,
.enter_memory_pressure = sctp_enter_memory_pressure,
.memory_allocated = &sctp_memory_allocated,
+ .sockets_allocated = &sctp_sockets_allocated,
REF_PROTO_INUSE(sctp)
};
@@ -6521,6 +6530,7 @@ struct proto sctpv6_prot = {
.memory_pressure = &sctp_memory_pressure,
.enter_memory_pressure = sctp_enter_memory_pressure,
.memory_allocated = &sctp_memory_allocated,
+ .sockets_allocated = &sctp_sockets_allocated,
REF_PROTO_INUSE(sctpv6)
};
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index e27b11f18b7..b43f1f110f8 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -206,7 +206,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
* This field is the total length of the notification data, including
* the notification header.
*/
- sac->sac_length = sizeof(struct sctp_assoc_change);
+ sac->sac_length = skb->len;
/* Socket Extensions for SCTP
* 5.3.1.1 SCTP_ASSOC_CHANGE
diff --git a/net/socket.c b/net/socket.c
index 7651de00850..b6d35cd72a5 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -701,6 +701,9 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
{
struct socket *sock = file->private_data;
+ if (unlikely(!sock->ops->splice_read))
+ return -EINVAL;
+
return sock->ops->splice_read(sock, ppos, pipe, len, flags);
}
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 636c8e04e0b..b5f2786251b 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -316,31 +316,29 @@ static int create_cache_proc_entries(struct cache_detail *cd)
cd->proc_ent->owner = cd->owner;
cd->channel_ent = cd->content_ent = NULL;
- p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent);
+ p = proc_create("flush", S_IFREG|S_IRUSR|S_IWUSR,
+ cd->proc_ent, &cache_flush_operations);
cd->flush_ent = p;
if (p == NULL)
goto out_nomem;
- p->proc_fops = &cache_flush_operations;
p->owner = cd->owner;
p->data = cd;
if (cd->cache_request || cd->cache_parse) {
- p = create_proc_entry("channel", S_IFREG|S_IRUSR|S_IWUSR,
- cd->proc_ent);
+ p = proc_create("channel", S_IFREG|S_IRUSR|S_IWUSR,
+ cd->proc_ent, &cache_file_operations);
cd->channel_ent = p;
if (p == NULL)
goto out_nomem;
- p->proc_fops = &cache_file_operations;
p->owner = cd->owner;
p->data = cd;
}
if (cd->cache_show) {
- p = create_proc_entry("content", S_IFREG|S_IRUSR|S_IWUSR,
- cd->proc_ent);
+ p = proc_create("content", S_IFREG|S_IRUSR|S_IWUSR,
+ cd->proc_ent, &content_file_operations);
cd->content_ent = p;
if (p == NULL)
goto out_nomem;
- p->proc_fops = &content_file_operations;
p->owner = cd->owner;
p->data = cd;
}
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 5a16875f5ac..c6061a4346c 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -229,9 +229,8 @@ do_register(const char *name, void *data, const struct file_operations *fops)
rpc_proc_init();
dprintk("RPC: registering /proc/net/rpc/%s\n", name);
- ent = create_proc_entry(name, 0, proc_net_rpc);
+ ent = proc_create(name, 0, proc_net_rpc, fops);
if (ent) {
- ent->proc_fops = fops;
ent->data = data;
}
return ent;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 1d3e5fcc2cc..c475977de05 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -175,7 +175,7 @@ static int svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
size_t base = xdr->page_base;
unsigned int pglen = xdr->page_len;
unsigned int flags = MSG_MORE;
- char buf[RPC_MAX_ADDRBUFLEN];
+ RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
slen = xdr->len;
@@ -716,7 +716,7 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
struct socket *newsock;
struct svc_sock *newsvsk;
int err, slen;
- char buf[RPC_MAX_ADDRBUFLEN];
+ RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
dprintk("svc: tcp_accept %p sock %p\n", svsk, sock);
if (!sock)
@@ -1206,10 +1206,10 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
struct socket *sock;
int error;
int type;
- char buf[RPC_MAX_ADDRBUFLEN];
struct sockaddr_storage addr;
struct sockaddr *newsin = (struct sockaddr *)&addr;
int newlen;
+ RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
dprintk("svc: svc_create_socket(%s, %d, %s)\n",
serv->sv_program->pg_name, protocol,
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 02c522c17de..a564c1a39ec 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -614,7 +614,11 @@ xprt_rdma_free(void *buffer)
return;
req = container_of(buffer, struct rpcrdma_req, rl_xdr_buf[0]);
- r_xprt = container_of(req->rl_buffer, struct rpcrdma_xprt, rx_buf);
+ if (req->rl_iov.length == 0) { /* see allocate above */
+ r_xprt = container_of(((struct rpcrdma_req *) req->rl_buffer)->rl_buffer,
+ struct rpcrdma_xprt, rx_buf);
+ } else
+ r_xprt = container_of(req->rl_buffer, struct rpcrdma_xprt, rx_buf);
rep = req->rl_reply;
dprintk("RPC: %s: called on 0x%p%s\n",
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
index 95b373913aa..4bb3404f610 100644
--- a/net/tipc/cluster.c
+++ b/net/tipc/cluster.c
@@ -142,7 +142,7 @@ void tipc_cltr_attach_node(struct cluster *c_ptr, struct node *n_ptr)
max_n_num = tipc_highest_allowed_slave;
assert(n_num > 0);
assert(n_num <= max_n_num);
- assert(c_ptr->nodes[n_num] == 0);
+ assert(c_ptr->nodes[n_num] == NULL);
c_ptr->nodes[n_num] = n_ptr;
if (n_num > c_ptr->highest_node)
c_ptr->highest_node = n_num;
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 1b17fecee74..cefa99824c5 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -3251,7 +3251,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
if ((mod(msg_seqno(buf_msg(l_ptr->last_out)) -
msg_seqno(buf_msg(l_ptr->first_out)))
!= (l_ptr->out_queue_size - 1))
- || (l_ptr->last_out->next != 0)) {
+ || (l_ptr->last_out->next != NULL)) {
tipc_printf(buf, "\nSend queue inconsistency\n");
tipc_printf(buf, "first_out= %x ", l_ptr->first_out);
tipc_printf(buf, "next_out= %x ", l_ptr->next_out);
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 6704a58c785..c38744c96ed 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -148,7 +148,7 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
reference = (next_plus_upper & ~index_mask) + index;
entry->data.reference = reference;
entry->object = object;
- if (lock != 0)
+ if (lock != NULL)
*lock = &entry->lock;
spin_unlock_bh(&entry->lock);
}
diff --git a/net/tipc/zone.c b/net/tipc/zone.c
index 114e173f11a..3506f856344 100644
--- a/net/tipc/zone.c
+++ b/net/tipc/zone.c
@@ -82,7 +82,7 @@ void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr)
assert(c_ptr->addr);
assert(c_num <= tipc_max_clusters);
- assert(z_ptr->clusters[c_num] == 0);
+ assert(z_ptr->clusters[c_num] == NULL);
z_ptr->clusters[c_num] = c_ptr;
}
diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c
index f2e54c3f064..5bebe40bf4e 100644
--- a/net/wanrouter/wanproc.c
+++ b/net/wanrouter/wanproc.c
@@ -292,14 +292,12 @@ int __init wanrouter_proc_init(void)
if (!proc_router)
goto fail;
- p = create_proc_entry("config", S_IRUGO, proc_router);
+ p = proc_create("config", S_IRUGO, proc_router, &config_fops);
if (!p)
goto fail_config;
- p->proc_fops = &config_fops;
- p = create_proc_entry("status", S_IRUGO, proc_router);
+ p = proc_create("status", S_IRUGO, proc_router, &status_fops);
if (!p)
goto fail_stat;
- p->proc_fops = &status_fops;
return 0;
fail_stat:
remove_proc_entry("config", proc_router);
@@ -329,10 +327,10 @@ int wanrouter_proc_add(struct wan_device* wandev)
if (wandev->magic != ROUTER_MAGIC)
return -EINVAL;
- wandev->dent = create_proc_entry(wandev->name, S_IRUGO, proc_router);
+ wandev->dent = proc_create(wandev->name, S_IRUGO,
+ proc_router, &wandev_fops);
if (!wandev->dent)
return -ENOMEM;
- wandev->dent->proc_fops = &wandev_fops;
wandev->dent->data = wandev;
return 0;
}
diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c
index 3f52b09bed0..1afa44d25be 100644
--- a/net/x25/x25_proc.c
+++ b/net/x25/x25_proc.c
@@ -312,20 +312,18 @@ int __init x25_proc_init(void)
if (!x25_proc_dir)
goto out;
- p = create_proc_entry("route", S_IRUGO, x25_proc_dir);
+ p = proc_create("route", S_IRUGO, x25_proc_dir, &x25_seq_route_fops);
if (!p)
goto out_route;
- p->proc_fops = &x25_seq_route_fops;
- p = create_proc_entry("socket", S_IRUGO, x25_proc_dir);
+ p = proc_create("socket", S_IRUGO, x25_proc_dir, &x25_seq_socket_fops);
if (!p)
goto out_socket;
- p->proc_fops = &x25_seq_socket_fops;
- p = create_proc_entry("forward", S_IRUGO, x25_proc_dir);
+ p = proc_create("forward", S_IRUGO, x25_proc_dir,
+ &x25_seq_forward_fops);
if (!p)
goto out_forward;
- p->proc_fops = &x25_seq_forward_fops;
rc = 0;
out:
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
index 8f9dbec319b..9201ef8ad90 100644
--- a/net/xfrm/Kconfig
+++ b/net/xfrm/Kconfig
@@ -38,7 +38,7 @@ config XFRM_MIGRATE
config XFRM_STATISTICS
bool "Transformation statistics (EXPERIMENTAL)"
- depends on XFRM && PROC_FS && EXPERIMENTAL
+ depends on INET && XFRM && PROC_FS && EXPERIMENTAL
---help---
This statistics is not a SNMP/MIB specification but shows
statistics about transformation error (or almost error) factor
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 4d6ebc633a9..62188c6a06d 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -109,7 +109,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
if (encap_type < 0) {
async = 1;
x = xfrm_input_state(skb);
- seq = XFRM_SKB_CB(skb)->seq;
+ seq = XFRM_SKB_CB(skb)->seq.input;
goto resume;
}
@@ -175,7 +175,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
spin_unlock(&x->lock);
- XFRM_SKB_CB(skb)->seq = seq;
+ XFRM_SKB_CB(skb)->seq.input = seq;
nexthdr = x->type->input(x, skb);
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index fc690368325..569d377932c 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -62,7 +62,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
}
if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
- XFRM_SKB_CB(skb)->seq = ++x->replay.oseq;
+ XFRM_SKB_CB(skb)->seq.output = ++x->replay.oseq;
if (unlikely(x->replay.oseq == 0)) {
XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATESEQERROR);
x->replay.oseq--;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 47219f98053..9fc4c315f6c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -331,15 +331,31 @@ static void xfrm_dst_hash_transfer(struct hlist_head *list,
struct hlist_head *ndsttable,
unsigned int nhashmask)
{
- struct hlist_node *entry, *tmp;
+ struct hlist_node *entry, *tmp, *entry0 = NULL;
struct xfrm_policy *pol;
+ unsigned int h0 = 0;
+redo:
hlist_for_each_entry_safe(pol, entry, tmp, list, bydst) {
unsigned int h;
h = __addr_hash(&pol->selector.daddr, &pol->selector.saddr,
pol->family, nhashmask);
- hlist_add_head(&pol->bydst, ndsttable+h);
+ if (!entry0) {
+ hlist_del(entry);
+ hlist_add_head(&pol->bydst, ndsttable+h);
+ h0 = h;
+ } else {
+ if (h != h0)
+ continue;
+ hlist_del(entry);
+ hlist_add_after(entry0, &pol->bydst);
+ }
+ entry0 = entry;
+ }
+ if (!hlist_empty(list)) {
+ entry0 = NULL;
+ goto redo;
}
}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 78338079b7f..f971ca5645f 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1105,6 +1105,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
return xp;
error:
*errp = err;
+ xp->dead = 1;
xfrm_policy_destroy(xp);
return NULL;
}
diff --git a/samples/Kconfig b/samples/Kconfig
index 74d97cc2478..e1fb471cc50 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -22,5 +22,16 @@ config SAMPLE_KOBJECT
If in doubt, say "N" here.
+config SAMPLE_KPROBES
+ tristate "Build kprobes examples -- loadable modules only"
+ depends on KPROBES && m
+ help
+ This build several kprobes example modules.
+
+config SAMPLE_KRETPROBES
+ tristate "Build kretprobes example -- loadable modules only"
+ default m
+ depends on SAMPLE_KPROBES && KRETPROBES
+
endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index 8652d0f268a..2e02575f779 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,3 +1,3 @@
# Makefile for Linux samples code
-obj-$(CONFIG_SAMPLES) += markers/ kobject/
+obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/
diff --git a/samples/kprobes/Makefile b/samples/kprobes/Makefile
new file mode 100644
index 00000000000..68739bc4fc6
--- /dev/null
+++ b/samples/kprobes/Makefile
@@ -0,0 +1,5 @@
+# builds the kprobes example kernel modules;
+# then to use one (as root): insmod <module_name.ko>
+
+obj-$(CONFIG_SAMPLE_KPROBES) += kprobe_example.o jprobe_example.o
+obj-$(CONFIG_SAMPLE_KRETPROBES) += kretprobe_example.o
diff --git a/samples/kprobes/jprobe_example.c b/samples/kprobes/jprobe_example.c
new file mode 100644
index 00000000000..b7541355b92
--- /dev/null
+++ b/samples/kprobes/jprobe_example.c
@@ -0,0 +1,68 @@
+/*
+ * Here's a sample kernel module showing the use of jprobes to dump
+ * the arguments of do_fork().
+ *
+ * For more information on theory of operation of jprobes, see
+ * Documentation/kprobes.txt
+ *
+ * Build and insert the kernel module as done in the kprobe example.
+ * You will see the trace data in /var/log/messages and on the
+ * console whenever do_fork() is invoked to create a new process.
+ * (Some messages may be suppressed if syslogd is configured to
+ * eliminate duplicate messages.)
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+
+/*
+ * Jumper probe for do_fork.
+ * Mirror principle enables access to arguments of the probed routine
+ * from the probe handler.
+ */
+
+/* Proxy routine having the same arguments as actual do_fork() routine */
+static long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
+ struct pt_regs *regs, unsigned long stack_size,
+ int __user *parent_tidptr, int __user *child_tidptr)
+{
+ printk(KERN_INFO "jprobe: clone_flags = 0x%lx, stack_size = 0x%lx,"
+ " regs = 0x%p\n",
+ clone_flags, stack_size, regs);
+
+ /* Always end with a call to jprobe_return(). */
+ jprobe_return();
+ return 0;
+}
+
+static struct jprobe my_jprobe = {
+ .entry = jdo_fork,
+ .kp = {
+ .symbol_name = "do_fork",
+ },
+};
+
+static int __init jprobe_init(void)
+{
+ int ret;
+
+ ret = register_jprobe(&my_jprobe);
+ if (ret < 0) {
+ printk(KERN_INFO "register_jprobe failed, returned %d\n", ret);
+ return -1;
+ }
+ printk(KERN_INFO "Planted jprobe at %p, handler addr %p\n",
+ my_jprobe.kp.addr, my_jprobe.entry);
+ return 0;
+}
+
+static void __exit jprobe_exit(void)
+{
+ unregister_jprobe(&my_jprobe);
+ printk(KERN_INFO "jprobe at %p unregistered\n", my_jprobe.kp.addr);
+}
+
+module_init(jprobe_init)
+module_exit(jprobe_exit)
+MODULE_LICENSE("GPL");
diff --git a/samples/kprobes/kprobe_example.c b/samples/kprobes/kprobe_example.c
new file mode 100644
index 00000000000..a681998a871
--- /dev/null
+++ b/samples/kprobes/kprobe_example.c
@@ -0,0 +1,91 @@
+/*
+ * NOTE: This example is works on x86 and powerpc.
+ * Here's a sample kernel module showing the use of kprobes to dump a
+ * stack trace and selected registers when do_fork() is called.
+ *
+ * For more information on theory of operation of kprobes, see
+ * Documentation/kprobes.txt
+ *
+ * You will see the trace data in /var/log/messages and on the console
+ * whenever do_fork() is invoked to create a new process.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+
+/* For each probe you need to allocate a kprobe structure */
+static struct kprobe kp = {
+ .symbol_name = "do_fork",
+};
+
+/* kprobe pre_handler: called just before the probed instruction is executed */
+static int handler_pre(struct kprobe *p, struct pt_regs *regs)
+{
+#ifdef CONFIG_X86
+ printk(KERN_INFO "pre_handler: p->addr = 0x%p, ip = %lx,"
+ " flags = 0x%lx\n",
+ p->addr, regs->ip, regs->flags);
+#endif
+#ifdef CONFIG_PPC
+ printk(KERN_INFO "pre_handler: p->addr = 0x%p, nip = 0x%lx,"
+ " msr = 0x%lx\n",
+ p->addr, regs->nip, regs->msr);
+#endif
+
+ /* A dump_stack() here will give a stack backtrace */
+ return 0;
+}
+
+/* kprobe post_handler: called after the probed instruction is executed */
+static void handler_post(struct kprobe *p, struct pt_regs *regs,
+ unsigned long flags)
+{
+#ifdef CONFIG_X86
+ printk(KERN_INFO "post_handler: p->addr = 0x%p, flags = 0x%lx\n",
+ p->addr, regs->flags);
+#endif
+#ifdef CONFIG_PPC
+ printk(KERN_INFO "post_handler: p->addr = 0x%p, msr = 0x%lx\n",
+ p->addr, regs->msr);
+#endif
+}
+
+/*
+ * fault_handler: this is called if an exception is generated for any
+ * instruction within the pre- or post-handler, or when Kprobes
+ * single-steps the probed instruction.
+ */
+static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
+{
+ printk(KERN_INFO "fault_handler: p->addr = 0x%p, trap #%dn",
+ p->addr, trapnr);
+ /* Return 0 because we don't handle the fault. */
+ return 0;
+}
+
+static int __init kprobe_init(void)
+{
+ int ret;
+ kp.pre_handler = handler_pre;
+ kp.post_handler = handler_post;
+ kp.fault_handler = handler_fault;
+
+ ret = register_kprobe(&kp);
+ if (ret < 0) {
+ printk(KERN_INFO "register_kprobe failed, returned %d\n", ret);
+ return ret;
+ }
+ printk(KERN_INFO "Planted kprobe at %p\n", kp.addr);
+ return 0;
+}
+
+static void __exit kprobe_exit(void)
+{
+ unregister_kprobe(&kp);
+ printk(KERN_INFO "kprobe at %p unregistered\n", kp.addr);
+}
+
+module_init(kprobe_init)
+module_exit(kprobe_exit)
+MODULE_LICENSE("GPL");
diff --git a/samples/kprobes/kretprobe_example.c b/samples/kprobes/kretprobe_example.c
new file mode 100644
index 00000000000..4e764b317d6
--- /dev/null
+++ b/samples/kprobes/kretprobe_example.c
@@ -0,0 +1,106 @@
+/*
+ * kretprobe_example.c
+ *
+ * Here's a sample kernel module showing the use of return probes to
+ * report the return value and total time taken for probed function
+ * to run.
+ *
+ * usage: insmod kretprobe_example.ko func=<func_name>
+ *
+ * If no func_name is specified, do_fork is instrumented
+ *
+ * For more information on theory of operation of kretprobes, see
+ * Documentation/kprobes.txt
+ *
+ * Build and insert the kernel module as done in the kprobe example.
+ * You will see the trace data in /var/log/messages and on the console
+ * whenever the probed function returns. (Some messages may be suppressed
+ * if syslogd is configured to eliminate duplicate messages.)
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/ktime.h>
+#include <linux/limits.h>
+
+static char func_name[NAME_MAX] = "do_fork";
+module_param_string(func, func_name, NAME_MAX, S_IRUGO);
+MODULE_PARM_DESC(func, "Function to kretprobe; this module will report the"
+ " function's execution time");
+
+/* per-instance private data */
+struct my_data {
+ ktime_t entry_stamp;
+};
+
+/* Here we use the entry_hanlder to timestamp function entry */
+static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct my_data *data;
+
+ if (!current->mm)
+ return 1; /* Skip kernel threads */
+
+ data = (struct my_data *)ri->data;
+ data->entry_stamp = ktime_get();
+ return 0;
+}
+
+/*
+ * Return-probe handler: Log the return value and duration. Duration may turn
+ * out to be zero consistently, depending upon the granularity of time
+ * accounting on the platform.
+ */
+static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+ int retval = regs_return_value(regs);
+ struct my_data *data = (struct my_data *)ri->data;
+ s64 delta;
+ ktime_t now;
+
+ now = ktime_get();
+ delta = ktime_to_ns(ktime_sub(now, data->entry_stamp));
+ printk(KERN_INFO "%s returned %d and took %lld ns to execute\n",
+ func_name, retval, (long long)delta);
+ return 0;
+}
+
+static struct kretprobe my_kretprobe = {
+ .handler = ret_handler,
+ .entry_handler = entry_handler,
+ .data_size = sizeof(struct my_data),
+ /* Probe up to 20 instances concurrently. */
+ .maxactive = 20,
+};
+
+static int __init kretprobe_init(void)
+{
+ int ret;
+
+ my_kretprobe.kp.symbol_name = func_name;
+ ret = register_kretprobe(&my_kretprobe);
+ if (ret < 0) {
+ printk(KERN_INFO "register_kretprobe failed, returned %d\n",
+ ret);
+ return -1;
+ }
+ printk(KERN_INFO "Planted return probe at %s: %p\n",
+ my_kretprobe.kp.symbol_name, my_kretprobe.kp.addr);
+ return 0;
+}
+
+static void __exit kretprobe_exit(void)
+{
+ unregister_kretprobe(&my_kretprobe);
+ printk(KERN_INFO "kretprobe at %p unregistered\n",
+ my_kretprobe.kp.addr);
+
+ /* nmissed > 0 suggests that maxactive was set too low. */
+ printk(KERN_INFO "Missed probing %d instances of %s\n",
+ my_kretprobe.nmissed, my_kretprobe.kp.symbol_name);
+}
+
+module_init(kretprobe_init)
+module_exit(kretprobe_exit)
+MODULE_LICENSE("GPL");
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 2086a856400..2a7cef9726e 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -9,7 +9,7 @@ use strict;
my $P = $0;
$P =~ s@.*/@@g;
-my $V = '0.14';
+my $V = '0.15';
use Getopt::Long qw(:config no_auto_abbrev);
@@ -105,8 +105,7 @@ our $Sparse = qr{
__iomem|
__must_check|
__init_refok|
- __kprobes|
- fastcall
+ __kprobes
}x;
our $Attribute = qr{
const|
@@ -158,7 +157,10 @@ sub build_types {
\b
(?:const\s+)?
(?:unsigned\s+)?
- $all
+ (?:
+ $all|
+ (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)
+ )
(?:\s+$Sparse|\s+const)*
\b
}x;
@@ -362,6 +364,7 @@ sub ctx_statement_block {
my $type = '';
my $level = 0;
+ my $p;
my $c;
my $len = 0;
@@ -386,6 +389,7 @@ sub ctx_statement_block {
last;
}
}
+ $p = $c;
$c = substr($blk, $off, 1);
$remainder = substr($blk, $off);
@@ -397,8 +401,9 @@ sub ctx_statement_block {
}
# An else is really a conditional as long as its not else if
- if ($level == 0 && $remainder =~ /(\s+else)(?:\s|{)/ &&
- $remainder !~ /\s+else\s+if\b/) {
+ if ($level == 0 && (!defined($p) || $p =~ /(?:\s|\})/) &&
+ $remainder =~ /(else)(?:\s|{)/ &&
+ $remainder !~ /else\s+if\b/) {
$coff = $off + length($1);
}
@@ -445,21 +450,73 @@ sub ctx_statement_block {
$line, $remain + 1, $off - $loff + 1, $level);
}
+sub statement_lines {
+ my ($stmt) = @_;
+
+ # Strip the diff line prefixes and rip blank lines at start and end.
+ $stmt =~ s/(^|\n)./$1/g;
+ $stmt =~ s/^\s*//;
+ $stmt =~ s/\s*$//;
+
+ my @stmt_lines = ($stmt =~ /\n/g);
+
+ return $#stmt_lines + 2;
+}
+
+sub statement_rawlines {
+ my ($stmt) = @_;
+
+ my @stmt_lines = ($stmt =~ /\n/g);
+
+ return $#stmt_lines + 2;
+}
+
+sub statement_block_size {
+ my ($stmt) = @_;
+
+ $stmt =~ s/(^|\n)./$1/g;
+ $stmt =~ s/^\s*{//;
+ $stmt =~ s/}\s*$//;
+ $stmt =~ s/^\s*//;
+ $stmt =~ s/\s*$//;
+
+ my @stmt_lines = ($stmt =~ /\n/g);
+ my @stmt_statements = ($stmt =~ /;/g);
+
+ my $stmt_lines = $#stmt_lines + 2;
+ my $stmt_statements = $#stmt_statements + 1;
+
+ if ($stmt_lines > $stmt_statements) {
+ return $stmt_lines;
+ } else {
+ return $stmt_statements;
+ }
+}
+
sub ctx_statement_full {
my ($linenr, $remain, $off) = @_;
my ($statement, $condition, $level);
my (@chunks);
+ # Grab the first conditional/block pair.
($statement, $condition, $linenr, $remain, $off, $level) =
ctx_statement_block($linenr, $remain, $off);
#print "F: c<$condition> s<$statement>\n";
+ push(@chunks, [ $condition, $statement ]);
+ if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
+ return ($level, $linenr, @chunks);
+ }
+
+ # Pull in the following conditional/block pairs and see if they
+ # could continue the statement.
for (;;) {
- push(@chunks, [ $condition, $statement ]);
- last if (!($remain > 0 && $condition =~ /^.\s*(?:if|else|do)/));
($statement, $condition, $linenr, $remain, $off, $level) =
ctx_statement_block($linenr, $remain, $off);
- #print "C: c<$condition> s<$statement>\n";
+ #print "C: c<$condition> s<$statement> remain<$remain>\n";
+ last if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:else|do)\b/s));
+ #print "C: push\n";
+ push(@chunks, [ $condition, $statement ]);
}
return ($level, $linenr, @chunks);
@@ -593,13 +650,13 @@ sub cat_vet {
}
my $av_preprocessor = 0;
-my $av_paren = 0;
+my $av_pending;
my @av_paren_type;
sub annotate_reset {
$av_preprocessor = 0;
- $av_paren = 0;
- @av_paren_type = ();
+ $av_pending = '_';
+ @av_paren_type = ('E');
}
sub annotate_values {
@@ -611,12 +668,13 @@ sub annotate_values {
print "$stream\n" if ($dbg_values > 1);
while (length($cur)) {
- print " <$type> " if ($dbg_values > 1);
+ print " <" . join('', @av_paren_type) .
+ "> <$type> " if ($dbg_values > 1);
if ($cur =~ /^(\s+)/o) {
print "WS($1)\n" if ($dbg_values > 1);
if ($1 =~ /\n/ && $av_preprocessor) {
+ $type = pop(@av_paren_type);
$av_preprocessor = 0;
- $type = 'N';
}
} elsif ($cur =~ /^($Type)/) {
@@ -626,11 +684,33 @@ sub annotate_values {
} elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) {
print "DEFINE($1)\n" if ($dbg_values > 1);
$av_preprocessor = 1;
- $av_paren_type[$av_paren] = 'N';
+ $av_pending = 'N';
- } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|elif|endif))/o) {
- print "PRE($1)\n" if ($dbg_values > 1);
+ } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if))/o) {
+ print "PRE_START($1)\n" if ($dbg_values > 1);
$av_preprocessor = 1;
+
+ push(@av_paren_type, $type);
+ push(@av_paren_type, $type);
+ $type = 'N';
+
+ } elsif ($cur =~ /^(#\s*(?:else|elif))/o) {
+ print "PRE_RESTART($1)\n" if ($dbg_values > 1);
+ $av_preprocessor = 1;
+
+ push(@av_paren_type, $av_paren_type[$#av_paren_type]);
+
+ $type = 'N';
+
+ } elsif ($cur =~ /^(#\s*(?:endif))/o) {
+ print "PRE_END($1)\n" if ($dbg_values > 1);
+
+ $av_preprocessor = 1;
+
+ # Assume all arms of the conditional end as this
+ # one does, and continue as if the #endif was not here.
+ pop(@av_paren_type);
+ push(@av_paren_type, $type);
$type = 'N';
} elsif ($cur =~ /^(\\\n)/o) {
@@ -639,13 +719,13 @@ sub annotate_values {
} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
print "SIZEOF($1)\n" if ($dbg_values > 1);
if (defined $2) {
- $av_paren_type[$av_paren] = 'V';
+ $av_pending = 'V';
}
$type = 'N';
} elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) {
print "COND($1)\n" if ($dbg_values > 1);
- $av_paren_type[$av_paren] = 'N';
+ $av_pending = 'N';
$type = 'N';
} elsif ($cur =~/^(return|case|else)/o) {
@@ -654,14 +734,14 @@ sub annotate_values {
} elsif ($cur =~ /^(\()/o) {
print "PAREN('$1')\n" if ($dbg_values > 1);
- $av_paren++;
+ push(@av_paren_type, $av_pending);
+ $av_pending = '_';
$type = 'N';
} elsif ($cur =~ /^(\))/o) {
- $av_paren-- if ($av_paren > 0);
- if (defined $av_paren_type[$av_paren]) {
- $type = $av_paren_type[$av_paren];
- undef $av_paren_type[$av_paren];
+ my $new_type = pop(@av_paren_type);
+ if ($new_type ne '_') {
+ $type = $new_type;
print "PAREN('$1') -> $type\n"
if ($dbg_values > 1);
} else {
@@ -670,7 +750,7 @@ sub annotate_values {
} elsif ($cur =~ /^($Ident)\(/o) {
print "FUNC($1)\n" if ($dbg_values > 1);
- $av_paren_type[$av_paren] = 'V';
+ $av_pending = 'V';
} elsif ($cur =~ /^($Ident|$Constant)/o) {
print "IDENT($1)\n" if ($dbg_values > 1);
@@ -680,11 +760,11 @@ sub annotate_values {
print "ASSIGN($1)\n" if ($dbg_values > 1);
$type = 'N';
- } elsif ($cur =~/^(;)/) {
+ } elsif ($cur =~/^(;|{|})/) {
print "END($1)\n" if ($dbg_values > 1);
$type = 'E';
- } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) {
+ } elsif ($cur =~ /^(;|\?|:|\[)/o) {
print "CLOSE($1)\n" if ($dbg_values > 1);
$type = 'N';
@@ -988,7 +1068,7 @@ sub process {
}
# check for RCS/CVS revision markers
- if ($rawline =~ /\$(Revision|Log|Id)(?:\$|)/) {
+ if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
}
@@ -999,41 +1079,44 @@ sub process {
# Check for potential 'bare' types
if ($realcnt) {
+ my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
+ $s =~ s/\n./ /g;
+ $s =~ s/{.*$//;
+
# Ignore goto labels.
- if ($line =~ /$Ident:\*$/) {
+ if ($s =~ /$Ident:\*$/) {
# Ignore functions being called
- } elsif ($line =~ /^.\s*$Ident\s*\(/) {
+ } elsif ($s =~ /^.\s*$Ident\s*\(/) {
# definitions in global scope can only start with types
- } elsif ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) {
- possible($1, $line);
+ } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) {
+ possible($1, $s);
# declarations always start with types
- } elsif ($prev_values eq 'E' && $line =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/) {
- possible($1);
+ } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/) {
+ possible($1, $s);
}
# any (foo ... *) is a pointer cast, and foo is a type
- while ($line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) {
- possible($1, $line);
+ while ($s =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) {
+ possible($1, $s);
}
# Check for any sort of function declaration.
# int foo(something bar, other baz);
# void (*store_gdt)(x86_descr_ptr *);
- if ($prev_values eq 'E' && $line =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) {
+ if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) {
my ($name_len) = length($1);
- my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, $name_len);
- my $ctx = join("\n", @ctx);
- $ctx =~ s/\n.//;
+ my $ctx = $s;
substr($ctx, 0, $name_len + 1) = '';
$ctx =~ s/\)[^\)]*$//;
+
for my $arg (split(/\s*,\s*/, $ctx)) {
if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) {
- possible($1, $line);
+ possible($1, $s);
}
}
}
@@ -1100,8 +1183,8 @@ sub process {
$curr_values = $prev_values . $curr_values;
if ($dbg_values) {
my $outline = $opline; $outline =~ s/\t/ /g;
- warn "--> .$outline\n";
- warn "--> $curr_values\n";
+ print "$linenr > .$outline\n";
+ print "$linenr > $curr_values\n";
}
$prev_values = substr($curr_values, -1);
@@ -1148,7 +1231,9 @@ sub process {
if (($prevline !~ /^}/) &&
($prevline !~ /^\+}/) &&
($prevline !~ /^ }/) &&
- ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=)/)) {
+ ($prevline !~ /^.DECLARE_$Ident\(\Q$name\E\)/) &&
+ ($prevline !~ /^.LIST_HEAD\(\Q$name\E\)/) &&
+ ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)/)) {
WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
}
}
@@ -1266,7 +1351,7 @@ sub process {
=>|->|<<|>>|<|>|=|!|~|
&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%
}x;
- my @elements = split(/($;+|$ops|;)/, $opline);
+ my @elements = split(/($ops|;)/, $opline);
my $off = 0;
my $blank = copy_spacing($opline);
@@ -1277,6 +1362,7 @@ sub process {
my $a = '';
$a = 'V' if ($elements[$n] ne '');
$a = 'W' if ($elements[$n] =~ /\s$/);
+ $a = 'C' if ($elements[$n] =~ /$;$/);
$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
$a = 'O' if ($elements[$n] eq '');
$a = 'E' if ($elements[$n] eq '' && $n == 0);
@@ -1287,6 +1373,7 @@ sub process {
if (defined $elements[$n + 2]) {
$c = 'V' if ($elements[$n + 2] ne '');
$c = 'W' if ($elements[$n + 2] =~ /^\s/);
+ $c = 'C' if ($elements[$n + 2] =~ /^$;/);
$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
$c = 'O' if ($elements[$n + 2] eq '');
$c = 'E' if ($elements[$n + 2] =~ /\s*\\$/);
@@ -1330,13 +1417,13 @@ sub process {
if ($op_type ne 'V' &&
$ca =~ /\s$/ && $cc =~ /^\s*,/) {
- # Ignore comments
- } elsif ($op =~ /^$;+$/) {
+# # Ignore comments
+# } elsif ($op =~ /^$;+$/) {
# ; should have either the end of line or a space or \ after it
} elsif ($op eq ';') {
- if ($ctx !~ /.x[WEB]/ && $cc !~ /^\\/ &&
- $cc !~ /^;/) {
+ if ($ctx !~ /.x[WEBC]/ &&
+ $cc !~ /^\\/ && $cc !~ /^;/) {
ERROR("need space after that '$op' $at\n" . $hereptr);
}
@@ -1351,7 +1438,7 @@ sub process {
# , must have a space on the right.
} elsif ($op eq ',') {
- if ($ctx !~ /.xW|.xE/ && $cc !~ /^}/) {
+ if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
ERROR("need space after that '$op' $at\n" . $hereptr);
}
@@ -1364,7 +1451,7 @@ sub process {
# unary operator, or a cast
} elsif ($op eq '!' || $op eq '~' ||
($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) {
- if ($ctx !~ /[WEB]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
+ if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
ERROR("need space before that '$op' $at\n" . $hereptr);
}
if ($ctx =~ /.xW/) {
@@ -1373,7 +1460,7 @@ sub process {
# unary ++ and unary -- are allowed no space on one side.
} elsif ($op eq '++' or $op eq '--') {
- if ($ctx !~ /[WOB]x[^W]/ && $ctx !~ /[^W]x[WOBE]/) {
+ if ($ctx !~ /[WOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
ERROR("need space one side of that '$op' $at\n" . $hereptr);
}
if ($ctx =~ /WxB/ || ($ctx =~ /Wx./ && $cc =~ /^;/)) {
@@ -1387,13 +1474,13 @@ sub process {
$op eq '*' or $op eq '/' or
$op eq '%')
{
- if ($ctx !~ /VxV|WxW|VxE|WxE|VxO/) {
+ if ($ctx !~ /VxV|WxW|VxE|WxE|VxO|Cx.|.xC/) {
ERROR("need consistent spacing around '$op' $at\n" .
$hereptr);
}
# All the others need spaces both sides.
- } elsif ($ctx !~ /[EW]x[WE]/) {
+ } elsif ($ctx !~ /[EWC]x[CWE]/) {
# Ignore email addresses <foo@bar>
if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) &&
!($op eq '>' && $cb =~ /<\S+\@\S+$;/)) {
@@ -1551,7 +1638,7 @@ sub process {
# multi-statement macros should be enclosed in a do while loop, grab the
# first statement and ensure its the whole macro if its not enclosed
-# in a known goot container
+# in a known good container
if ($prevline =~ /\#define.*\\/ &&
$prevline !~/(?:do\s+{|\(\{|\{)/ &&
$line !~ /(?:do\s+{|\(\{|\{)/ &&
@@ -1599,84 +1686,95 @@ sub process {
# check for redundant bracing round if etc
if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
my ($level, $endln, @chunks) =
- ctx_statement_full($linenr, $realcnt, 0);
+ ctx_statement_full($linenr, $realcnt, 1);
#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
- if ($#chunks > 1 && $level == 0) {
+ #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
+ if ($#chunks > 0 && $level == 0) {
my $allowed = 0;
my $seen = 0;
+ my $herectx = $here . "\n";;
+ my $ln = $linenr - 1;
for my $chunk (@chunks) {
my ($cond, $block) = @{$chunk};
+ $herectx .= "$rawlines[$ln]\n[...]\n";
+ $ln += statement_rawlines($block) - 1;
+
substr($block, 0, length($cond)) = '';
$seen++ if ($block =~ /^\s*{/);
- $block =~ s/(^|\n)./$1/g;
- $block =~ s/^\s*{//;
- $block =~ s/}\s*$//;
- $block =~ s/^\s*//;
- $block =~ s/\s*$//;
-
- my @lines = ($block =~ /\n/g);
- my @statements = ($block =~ /;/g);
-
- #print "cond<$cond> block<$block> lines<" . scalar(@lines) . "> statements<" . scalar(@statements) . "> seen<$seen> allowed<$allowed>\n";
- if (scalar(@lines) != 0) {
+ #print "cond<$cond> block<$block> allowed<$allowed>\n";
+ if (statement_lines($cond) > 1) {
+ #print "APW: ALLOWED: cond<$cond>\n";
$allowed = 1;
}
if ($block =~/\b(?:if|for|while)\b/) {
+ #print "APW: ALLOWED: block<$block>\n";
$allowed = 1;
}
- if (scalar(@statements) > 1) {
+ if (statement_block_size($block) > 1) {
+ #print "APW: ALLOWED: lines block<$block>\n";
$allowed = 1;
}
}
if ($seen && !$allowed) {
- WARN("braces {} are not necessary for any arm of this statement\n" . $herecurr);
- $suppress_ifbraces = $endln;
+ WARN("braces {} are not necessary for any arm of this statement\n" . $herectx);
}
+ # Either way we have looked over this whole
+ # statement and said what needs to be said.
+ $suppress_ifbraces = $endln;
}
}
if ($linenr > $suppress_ifbraces &&
$line =~ /\b(if|while|for|else)\b/) {
- # Locate the end of the opening statement.
- my @control = ctx_statement($linenr, $realcnt, 0);
- my $nr = $linenr + (scalar(@control) - 1);
- my $cnt = $realcnt - (scalar(@control) - 1);
-
- my $off = $realcnt - $cnt;
- #print "$off: line<$line>end<" . $lines[$nr - 1] . ">\n";
-
- # If this is is a braced statement group check it
- if ($lines[$nr - 1] =~ /{\s*$/) {
- my ($lvl, @block) = ctx_block_level($nr, $cnt);
-
- my $stmt = join("\n", @block);
- # Drop the diff line leader.
- $stmt =~ s/\n./\n/g;
- # Drop the code outside the block.
- $stmt =~ s/(^[^{]*){\s*//;
- my $before = $1;
- $stmt =~ s/\s*}([^}]*$)//;
- my $after = $1;
-
- #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n";
- #print "before<$before> stmt<$stmt> after<$after>\n\n";
-
- # Count the newlines, if there is only one
- # then the block should not have {}'s.
- my @lines = ($stmt =~ /\n/g);
- my @statements = ($stmt =~ /;/g);
- #print "lines<" . scalar(@lines) . ">\n";
- #print "statements<" . scalar(@statements) . ">\n";
- if ($lvl == 0 && scalar(@lines) == 0 &&
- scalar(@statements) < 2 &&
- $stmt !~ /{/ && $stmt !~ /\bif\b/ &&
- $before !~ /}/ && $after !~ /{/) {
- my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n";
- shift(@block);
- WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
+ my ($level, $endln, @chunks) =
+ ctx_statement_full($linenr, $realcnt, $-[0]);
+
+ my $allowed = 0;
+
+ # Check the pre-context.
+ if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
+ #print "APW: ALLOWED: pre<$1>\n";
+ $allowed = 1;
+ }
+ # Check the condition.
+ my ($cond, $block) = @{$chunks[0]};
+ if (defined $cond) {
+ substr($block, 0, length($cond)) = '';
+ }
+ if (statement_lines($cond) > 1) {
+ #print "APW: ALLOWED: cond<$cond>\n";
+ $allowed = 1;
+ }
+ if ($block =~/\b(?:if|for|while)\b/) {
+ #print "APW: ALLOWED: block<$block>\n";
+ $allowed = 1;
+ }
+ if (statement_block_size($block) > 1) {
+ #print "APW: ALLOWED: lines block<$block>\n";
+ $allowed = 1;
+ }
+ # Check the post-context.
+ if (defined $chunks[1]) {
+ my ($cond, $block) = @{$chunks[1]};
+ if (defined $cond) {
+ substr($block, 0, length($cond)) = '';
+ }
+ if ($block =~ /^\s*\{/) {
+ #print "APW: ALLOWED: chunk-1 block<$block>\n";
+ $allowed = 1;
+ }
+ }
+ if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
+ my $herectx = $here . "\n";;
+ my $end = $linenr + statement_rawlines($block) - 1;
+
+ for (my $ln = $linenr - 1; $ln < $end; $ln++) {
+ $herectx .= $rawlines[$ln] . "\n";;
}
+
+ WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
}
}
@@ -1828,15 +1926,6 @@ sub process {
print "are false positives report them to the maintainer, see\n";
print "CHECKPATCH in MAINTAINERS.\n";
}
- print <<EOL if ($file == 1 && $quiet == 0);
-
-WARNING: Using --file mode. Please do not send patches to linux-kernel
-that change whole existing files if you did not significantly change most
-of the the file for other reasons anyways or just wrote the file newly
-from scratch. Pure code style patches have a significant cost in a
-quickly changing code base like Linux because they cause rejects
-with other changes.
-EOL
return $clean;
}
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 3929e5b35e7..4a03191ad17 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -298,22 +298,30 @@ void sym_calc_value(struct symbol *sym)
if (sym_is_choice_value(sym) && sym->visible == yes) {
prop = sym_get_choice_prop(sym);
newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
- } else if (EXPR_OR(sym->visible, sym->rev_dep.tri) != no) {
- sym->flags |= SYMBOL_WRITE;
- if (sym_has_value(sym))
- newval.tri = sym->def[S_DEF_USER].tri;
- else if (!sym_is_choice(sym)) {
- prop = sym_get_default_prop(sym);
- if (prop)
- newval.tri = expr_calc_value(prop->expr);
+ } else {
+ if (sym->visible != no) {
+ /* if the symbol is visible use the user value
+ * if available, otherwise try the default value
+ */
+ sym->flags |= SYMBOL_WRITE;
+ if (sym_has_value(sym)) {
+ newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
+ sym->visible);
+ goto calc_newval;
+ }
}
- newval.tri = EXPR_OR(EXPR_AND(newval.tri, sym->visible), sym->rev_dep.tri);
- } else if (!sym_is_choice(sym)) {
- prop = sym_get_default_prop(sym);
- if (prop) {
+ if (sym->rev_dep.tri != no)
sym->flags |= SYMBOL_WRITE;
- newval.tri = expr_calc_value(prop->expr);
+ if (!sym_is_choice(sym)) {
+ prop = sym_get_default_prop(sym);
+ if (prop) {
+ sym->flags |= SYMBOL_WRITE;
+ newval.tri = EXPR_AND(expr_calc_value(prop->expr),
+ prop->visible.tri);
+ }
}
+ calc_newval:
+ newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
}
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
newval.tri = yes;
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 26146cbaa50..74c2f9db2aa 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1512,13 +1512,13 @@ sub create_parameterlist($$$) {
# corresponding data structures "correctly". Catch it later in
# output_* subs.
push_parameter($arg, "", $file);
- } elsif ($arg =~ m/\(.*\*/) {
+ } elsif ($arg =~ m/\(.+\)\s*\(/) {
# pointer-to-function
$arg =~ tr/#/,/;
- $arg =~ m/[^\(]+\(\*\s*([^\)]+)\)/;
+ $arg =~ m/[^\(]+\(\*?\s*(\w*)\s*\)/;
$param = $1;
$type = $arg;
- $type =~ s/([^\(]+\(\*)$param/$1/;
+ $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
push_parameter($param, $type, $file);
} elsif ($arg) {
$arg =~ s/\s*:\s*/:/g;
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 61742771c65..695b5d657cf 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1200,7 +1200,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
"annotate %s with a matching annotation.\n",
from, sec2annotation(fromsec), fromsym, from_p,
to, sec2annotation(tosec), tosym, to_p,
- fromsym, tosym, fromsym);
+ tosym, fromsym, tosym);
break;
case INIT_TO_EXIT:
fprintf(stderr,
diff --git a/security/commoncap.c b/security/commoncap.c
index 5aba82679a0..bb0c095f576 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -552,7 +552,7 @@ int cap_task_kill(struct task_struct *p, struct siginfo *info,
* allowed.
* We must preserve legacy signal behavior in this case.
*/
- if (p->euid == 0 && p->uid == current->uid)
+ if (p->uid == current->uid)
return 0;
/* sigcont is permitted within same session */
diff --git a/security/dummy.c b/security/dummy.c
index 649326bf64e..78d8f92310a 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -181,8 +181,7 @@ static void dummy_sb_free_security (struct super_block *sb)
return;
}
-static int dummy_sb_copy_data (struct file_system_type *type,
- void *orig, void *copy)
+static int dummy_sb_copy_data (char *orig, char *copy)
{
return 0;
}
@@ -245,19 +244,17 @@ static void dummy_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata
return;
}
-static int dummy_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options,
- int **flags, int *num_opts)
+static int dummy_sb_get_mnt_opts(const struct super_block *sb,
+ struct security_mnt_opts *opts)
{
- *mount_options = NULL;
- *flags = NULL;
- *num_opts = 0;
+ security_init_mnt_opts(opts);
return 0;
}
-static int dummy_sb_set_mnt_opts(struct super_block *sb, char **mount_options,
- int *flags, int num_opts)
+static int dummy_sb_set_mnt_opts(struct super_block *sb,
+ struct security_mnt_opts *opts)
{
- if (unlikely(num_opts))
+ if (unlikely(opts->num_mnt_opts))
return -EOPNOTSUPP;
return 0;
}
@@ -268,6 +265,11 @@ static void dummy_sb_clone_mnt_opts(const struct super_block *oldsb,
return;
}
+static int dummy_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
+{
+ return 0;
+}
+
static int dummy_inode_alloc_security (struct inode *inode)
{
return 0;
@@ -1028,6 +1030,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, sb_get_mnt_opts);
set_to_dummy_if_null(ops, sb_set_mnt_opts);
set_to_dummy_if_null(ops, sb_clone_mnt_opts);
+ set_to_dummy_if_null(ops, sb_parse_opts_str);
set_to_dummy_if_null(ops, inode_alloc_security);
set_to_dummy_if_null(ops, inode_free_security);
set_to_dummy_if_null(ops, inode_init_security);
diff --git a/security/security.c b/security/security.c
index d15e56cbaad..b1387a6b416 100644
--- a/security/security.c
+++ b/security/security.c
@@ -244,10 +244,11 @@ void security_sb_free(struct super_block *sb)
security_ops->sb_free_security(sb);
}
-int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy)
+int security_sb_copy_data(char *orig, char *copy)
{
- return security_ops->sb_copy_data(type, orig, copy);
+ return security_ops->sb_copy_data(orig, copy);
}
+EXPORT_SYMBOL(security_sb_copy_data);
int security_sb_kern_mount(struct super_block *sb, void *data)
{
@@ -306,24 +307,30 @@ void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_
}
int security_sb_get_mnt_opts(const struct super_block *sb,
- char ***mount_options,
- int **flags, int *num_opts)
+ struct security_mnt_opts *opts)
{
- return security_ops->sb_get_mnt_opts(sb, mount_options, flags, num_opts);
+ return security_ops->sb_get_mnt_opts(sb, opts);
}
int security_sb_set_mnt_opts(struct super_block *sb,
- char **mount_options,
- int *flags, int num_opts)
+ struct security_mnt_opts *opts)
{
- return security_ops->sb_set_mnt_opts(sb, mount_options, flags, num_opts);
+ return security_ops->sb_set_mnt_opts(sb, opts);
}
+EXPORT_SYMBOL(security_sb_set_mnt_opts);
void security_sb_clone_mnt_opts(const struct super_block *oldsb,
struct super_block *newsb)
{
security_ops->sb_clone_mnt_opts(oldsb, newsb);
}
+EXPORT_SYMBOL(security_sb_clone_mnt_opts);
+
+int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
+{
+ return security_ops->sb_parse_opts_str(options, opts);
+}
+EXPORT_SYMBOL(security_sb_parse_opts_str);
int security_inode_alloc(struct inode *inode)
{
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 75c2e99bfb8..4bf4807f2d4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -443,8 +443,7 @@ out:
* mount options, or whatever.
*/
static int selinux_get_mnt_opts(const struct super_block *sb,
- char ***mount_options, int **mnt_opts_flags,
- int *num_opts)
+ struct security_mnt_opts *opts)
{
int rc = 0, i;
struct superblock_security_struct *sbsec = sb->s_security;
@@ -452,9 +451,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
u32 len;
char tmp;
- *num_opts = 0;
- *mount_options = NULL;
- *mnt_opts_flags = NULL;
+ security_init_mnt_opts(opts);
if (!sbsec->initialized)
return -EINVAL;
@@ -470,18 +467,18 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
/* count the number of mount options for this sb */
for (i = 0; i < 8; i++) {
if (tmp & 0x01)
- (*num_opts)++;
+ opts->num_mnt_opts++;
tmp >>= 1;
}
- *mount_options = kcalloc(*num_opts, sizeof(char *), GFP_ATOMIC);
- if (!*mount_options) {
+ opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC);
+ if (!opts->mnt_opts) {
rc = -ENOMEM;
goto out_free;
}
- *mnt_opts_flags = kcalloc(*num_opts, sizeof(int), GFP_ATOMIC);
- if (!*mnt_opts_flags) {
+ opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC);
+ if (!opts->mnt_opts_flags) {
rc = -ENOMEM;
goto out_free;
}
@@ -491,22 +488,22 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
rc = security_sid_to_context(sbsec->sid, &context, &len);
if (rc)
goto out_free;
- (*mount_options)[i] = context;
- (*mnt_opts_flags)[i++] = FSCONTEXT_MNT;
+ opts->mnt_opts[i] = context;
+ opts->mnt_opts_flags[i++] = FSCONTEXT_MNT;
}
if (sbsec->flags & CONTEXT_MNT) {
rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len);
if (rc)
goto out_free;
- (*mount_options)[i] = context;
- (*mnt_opts_flags)[i++] = CONTEXT_MNT;
+ opts->mnt_opts[i] = context;
+ opts->mnt_opts_flags[i++] = CONTEXT_MNT;
}
if (sbsec->flags & DEFCONTEXT_MNT) {
rc = security_sid_to_context(sbsec->def_sid, &context, &len);
if (rc)
goto out_free;
- (*mount_options)[i] = context;
- (*mnt_opts_flags)[i++] = DEFCONTEXT_MNT;
+ opts->mnt_opts[i] = context;
+ opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT;
}
if (sbsec->flags & ROOTCONTEXT_MNT) {
struct inode *root = sbsec->sb->s_root->d_inode;
@@ -515,24 +512,16 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
rc = security_sid_to_context(isec->sid, &context, &len);
if (rc)
goto out_free;
- (*mount_options)[i] = context;
- (*mnt_opts_flags)[i++] = ROOTCONTEXT_MNT;
+ opts->mnt_opts[i] = context;
+ opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
}
- BUG_ON(i != *num_opts);
+ BUG_ON(i != opts->num_mnt_opts);
return 0;
out_free:
- /* don't leak context string if security_sid_to_context had an error */
- if (*mount_options && i)
- for (; i > 0; i--)
- kfree((*mount_options)[i-1]);
- kfree(*mount_options);
- *mount_options = NULL;
- kfree(*mnt_opts_flags);
- *mnt_opts_flags = NULL;
- *num_opts = 0;
+ security_free_mnt_opts(opts);
return rc;
}
@@ -553,12 +542,13 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
return 1;
return 0;
}
+
/*
* Allow filesystems with binary mount data to explicitly set mount point
* labeling information.
*/
-static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options,
- int *flags, int num_opts)
+static int selinux_set_mnt_opts(struct super_block *sb,
+ struct security_mnt_opts *opts)
{
int rc = 0, i;
struct task_security_struct *tsec = current->security;
@@ -568,6 +558,9 @@ static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options,
struct inode_security_struct *root_isec = inode->i_security;
u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
u32 defcontext_sid = 0;
+ char **mount_options = opts->mnt_opts;
+ int *flags = opts->mnt_opts_flags;
+ int num_opts = opts->num_mnt_opts;
mutex_lock(&sbsec->lock);
@@ -589,6 +582,21 @@ static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options,
}
/*
+ * Binary mount data FS will come through this function twice. Once
+ * from an explicit call and once from the generic calls from the vfs.
+ * Since the generic VFS calls will not contain any security mount data
+ * we need to skip the double mount verification.
+ *
+ * This does open a hole in which we will not notice if the first
+ * mount using this sb set explict options and a second mount using
+ * this sb does not set any security options. (The first options
+ * will be used for both mounts)
+ */
+ if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
+ && (num_opts == 0))
+ goto out;
+
+ /*
* parse the mount options, check if they are valid sids.
* also check if someone is trying to mount the same sb more
* than once with different security options.
@@ -792,43 +800,14 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
mutex_unlock(&newsbsec->lock);
}
-/*
- * string mount options parsing and call set the sbsec
- */
-static int superblock_doinit(struct super_block *sb, void *data)
+int selinux_parse_opts_str(char *options, struct security_mnt_opts *opts)
{
+ char *p;
char *context = NULL, *defcontext = NULL;
char *fscontext = NULL, *rootcontext = NULL;
- int rc = 0;
- char *p, *options = data;
- /* selinux only know about a fixed number of mount options */
- char *mnt_opts[NUM_SEL_MNT_OPTS];
- int mnt_opts_flags[NUM_SEL_MNT_OPTS], num_mnt_opts = 0;
-
- if (!data)
- goto out;
+ int rc, num_mnt_opts = 0;
- /* with the nfs patch this will become a goto out; */
- if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) {
- const char *name = sb->s_type->name;
- /* NFS we understand. */
- if (!strcmp(name, "nfs")) {
- struct nfs_mount_data *d = data;
-
- if (d->version != NFS_MOUNT_VERSION)
- goto out;
-
- if (d->context[0]) {
- context = kstrdup(d->context, GFP_KERNEL);
- if (!context) {
- rc = -ENOMEM;
- goto out;
- }
- }
- goto build_flags;
- } else
- goto out;
- }
+ opts->num_mnt_opts = 0;
/* Standard string-based options. */
while ((p = strsep(&options, "|")) != NULL) {
@@ -901,26 +880,37 @@ static int superblock_doinit(struct super_block *sb, void *data)
}
}
-build_flags:
+ rc = -ENOMEM;
+ opts->mnt_opts = kcalloc(NUM_SEL_MNT_OPTS, sizeof(char *), GFP_ATOMIC);
+ if (!opts->mnt_opts)
+ goto out_err;
+
+ opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int), GFP_ATOMIC);
+ if (!opts->mnt_opts_flags) {
+ kfree(opts->mnt_opts);
+ goto out_err;
+ }
+
if (fscontext) {
- mnt_opts[num_mnt_opts] = fscontext;
- mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT;
+ opts->mnt_opts[num_mnt_opts] = fscontext;
+ opts->mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT;
}
if (context) {
- mnt_opts[num_mnt_opts] = context;
- mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT;
+ opts->mnt_opts[num_mnt_opts] = context;
+ opts->mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT;
}
if (rootcontext) {
- mnt_opts[num_mnt_opts] = rootcontext;
- mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT;
+ opts->mnt_opts[num_mnt_opts] = rootcontext;
+ opts->mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT;
}
if (defcontext) {
- mnt_opts[num_mnt_opts] = defcontext;
- mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT;
+ opts->mnt_opts[num_mnt_opts] = defcontext;
+ opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT;
}
-out:
- rc = selinux_set_mnt_opts(sb, mnt_opts, mnt_opts_flags, num_mnt_opts);
+ opts->num_mnt_opts = num_mnt_opts;
+ return 0;
+
out_err:
kfree(context);
kfree(defcontext);
@@ -928,6 +918,33 @@ out_err:
kfree(rootcontext);
return rc;
}
+/*
+ * string mount options parsing and call set the sbsec
+ */
+static int superblock_doinit(struct super_block *sb, void *data)
+{
+ int rc = 0;
+ char *options = data;
+ struct security_mnt_opts opts;
+
+ security_init_mnt_opts(&opts);
+
+ if (!data)
+ goto out;
+
+ BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA);
+
+ rc = selinux_parse_opts_str(options, &opts);
+ if (rc)
+ goto out_err;
+
+out:
+ rc = selinux_set_mnt_opts(sb, &opts);
+
+out_err:
+ security_free_mnt_opts(&opts);
+ return rc;
+}
static inline u16 inode_mode_to_security_class(umode_t mode)
{
@@ -2253,7 +2270,7 @@ static inline void take_selinux_option(char **to, char *from, int *first,
}
}
-static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy)
+static int selinux_sb_copy_data(char *orig, char *copy)
{
int fnosec, fsec, rc = 0;
char *in_save, *in_curr, *in_end;
@@ -2263,12 +2280,6 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void
in_curr = orig;
sec_curr = copy;
- /* Binary mount data: just copy */
- if (type->fs_flags & FS_BINARY_MOUNTDATA) {
- copy_page(sec_curr, in_curr);
- goto out;
- }
-
nosec = (char *)get_zeroed_page(GFP_KERNEL);
if (!nosec) {
rc = -ENOMEM;
@@ -5251,6 +5262,8 @@ static struct security_operations selinux_ops = {
.sb_get_mnt_opts = selinux_get_mnt_opts,
.sb_set_mnt_opts = selinux_set_mnt_opts,
.sb_clone_mnt_opts = selinux_sb_clone_mnt_opts,
+ .sb_parse_opts_str = selinux_parse_opts_str,
+
.inode_alloc_security = selinux_inode_alloc_security,
.inode_free_security = selinux_inode_free_security,
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 837ce420d2f..f7d2f03781f 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -35,6 +35,11 @@
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP
#endif
+#define CONTEXT_MNT 0x01
+#define FSCONTEXT_MNT 0x02
+#define ROOTCONTEXT_MNT 0x04
+#define DEFCONTEXT_MNT 0x08
+
struct netlbl_lsm_secattr;
extern int selinux_enabled;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 2b5d6f72f67..0241fd35967 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -189,17 +189,10 @@ static void smack_sb_free_security(struct super_block *sb)
* Copy the Smack specific mount options out of the mount
* options list.
*/
-static int smack_sb_copy_data(struct file_system_type *type, void *orig,
- void *smackopts)
+static int smack_sb_copy_data(char *orig, char *smackopts)
{
char *cp, *commap, *otheropts, *dp;
- /* Binary mount data: just copy */
- if (type->fs_flags & FS_BINARY_MOUNTDATA) {
- copy_page(smackopts, orig);
- return 0;
- }
-
otheropts = (char *)get_zeroed_page(GFP_KERNEL);
if (otheropts == NULL)
return -ENOMEM;
@@ -584,14 +577,20 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
static int smack_inode_setxattr(struct dentry *dentry, char *name,
void *value, size_t size, int flags)
{
- if (!capable(CAP_MAC_ADMIN)) {
- if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
- strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
- strcmp(name, XATTR_NAME_SMACKIPOUT) == 0)
- return -EPERM;
- }
+ int rc = 0;
- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
+ if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
+ strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
+ strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
+ if (!capable(CAP_MAC_ADMIN))
+ rc = -EPERM;
+ } else
+ rc = cap_inode_setxattr(dentry, name, value, size, flags);
+
+ if (rc == 0)
+ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
+
+ return rc;
}
/**
@@ -658,10 +657,20 @@ static int smack_inode_getxattr(struct dentry *dentry, char *name)
*/
static int smack_inode_removexattr(struct dentry *dentry, char *name)
{
- if (strcmp(name, XATTR_NAME_SMACK) == 0 && !capable(CAP_MAC_ADMIN))
- return -EPERM;
+ int rc = 0;
- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
+ if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
+ strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
+ strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
+ if (!capable(CAP_MAC_ADMIN))
+ rc = -EPERM;
+ } else
+ rc = cap_inode_removexattr(dentry, name);
+
+ if (rc == 0)
+ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
+
+ return rc;
}
/**
@@ -1016,7 +1025,12 @@ static void smack_task_getsecid(struct task_struct *p, u32 *secid)
*/
static int smack_task_setnice(struct task_struct *p, int nice)
{
- return smk_curacc(p->security, MAY_WRITE);
+ int rc;
+
+ rc = cap_task_setnice(p, nice);
+ if (rc == 0)
+ rc = smk_curacc(p->security, MAY_WRITE);
+ return rc;
}
/**
@@ -1028,7 +1042,12 @@ static int smack_task_setnice(struct task_struct *p, int nice)
*/
static int smack_task_setioprio(struct task_struct *p, int ioprio)
{
- return smk_curacc(p->security, MAY_WRITE);
+ int rc;
+
+ rc = cap_task_setioprio(p, ioprio);
+ if (rc == 0)
+ rc = smk_curacc(p->security, MAY_WRITE);
+ return rc;
}
/**
@@ -1053,7 +1072,12 @@ static int smack_task_getioprio(struct task_struct *p)
static int smack_task_setscheduler(struct task_struct *p, int policy,
struct sched_param *lp)
{
- return smk_curacc(p->security, MAY_WRITE);
+ int rc;
+
+ rc = cap_task_setscheduler(p, policy, lp);
+ if (rc == 0)
+ rc = smk_curacc(p->security, MAY_WRITE);
+ return rc;
}
/**
@@ -1093,6 +1117,11 @@ static int smack_task_movememory(struct task_struct *p)
static int smack_task_kill(struct task_struct *p, struct siginfo *info,
int sig, u32 secid)
{
+ int rc;
+
+ rc = cap_task_kill(p, info, sig, secid);
+ if (rc != 0)
+ return rc;
/*
* Special cases where signals really ought to go through
* in spite of policy. Stephen Smalley suggests it may
@@ -1251,9 +1280,8 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp)
switch (smack_net_nltype) {
case NETLBL_NLTYPE_CIPSOV4:
- nlsp->domain = NULL;
- nlsp->flags = NETLBL_SECATTR_DOMAIN;
- nlsp->flags |= NETLBL_SECATTR_MLS_LVL;
+ nlsp->domain = kstrdup(smack, GFP_ATOMIC);
+ nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
rc = smack_to_cipso(smack, &cipso);
if (rc == 0) {
@@ -1282,15 +1310,14 @@ static int smack_netlabel(struct sock *sk)
{
struct socket_smack *ssp;
struct netlbl_lsm_secattr secattr;
- int rc = 0;
+ int rc;
ssp = sk->sk_security;
netlbl_secattr_init(&secattr);
smack_to_secattr(ssp->smk_out, &secattr);
- if (secattr.flags != NETLBL_SECATTR_NONE)
- rc = netlbl_sock_setattr(sk, &secattr);
-
+ rc = netlbl_sock_setattr(sk, &secattr);
netlbl_secattr_destroy(&secattr);
+
return rc;
}
@@ -1313,6 +1340,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
struct inode_smack *nsp = inode->i_security;
struct socket_smack *ssp;
struct socket *sock;
+ int rc = 0;
if (value == NULL || size > SMK_LABELLEN)
return -EACCES;
@@ -1341,7 +1369,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
ssp->smk_in = sp;
else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
ssp->smk_out = sp;
- return smack_netlabel(sock->sk);
+ rc = smack_netlabel(sock->sk);
+ if (rc != 0)
+ printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n",
+ __func__, -rc);
} else
return -EOPNOTSUPP;
@@ -1776,6 +1807,27 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
return smk_curacc(isp, may);
}
+/* module stacking operations */
+
+/**
+ * smack_register_security - stack capability module
+ * @name: module name
+ * @ops: module operations - ignored
+ *
+ * Allow the capability module to register.
+ */
+static int smack_register_security(const char *name,
+ struct security_operations *ops)
+{
+ if (strcmp(name, "capability") != 0)
+ return -EINVAL;
+
+ printk(KERN_INFO "%s: Registering secondary module %s\n",
+ __func__, name);
+
+ return 0;
+}
+
/**
* smack_d_instantiate - Make sure the blob is correct on an inode
* @opt_dentry: unused
@@ -2214,6 +2266,9 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
ssp->smk_packet[0] = '\0';
rc = smack_netlabel(sk);
+ if (rc != 0)
+ printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n",
+ __func__, -rc);
}
/**
@@ -2346,6 +2401,20 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
}
/*
+ * smack_secctx_to_secid - return the secid for a smack label
+ * @secdata: smack label
+ * @seclen: how long result is
+ * @secid: outgoing integer
+ *
+ * Exists for audit and networking code.
+ */
+static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+ *secid = smack_to_secid(secdata);
+ return 0;
+}
+
+/*
* smack_release_secctx - don't do anything.
* @key_ref: unused
* @context: unused
@@ -2393,6 +2462,8 @@ static struct security_operations smack_ops = {
.inode_post_setxattr = smack_inode_post_setxattr,
.inode_getxattr = smack_inode_getxattr,
.inode_removexattr = smack_inode_removexattr,
+ .inode_need_killpriv = cap_inode_need_killpriv,
+ .inode_killpriv = cap_inode_killpriv,
.inode_getsecurity = smack_inode_getsecurity,
.inode_setsecurity = smack_inode_setsecurity,
.inode_listsecurity = smack_inode_listsecurity,
@@ -2452,6 +2523,8 @@ static struct security_operations smack_ops = {
.netlink_send = cap_netlink_send,
.netlink_recv = cap_netlink_recv,
+ .register_security = smack_register_security,
+
.d_instantiate = smack_d_instantiate,
.getprocattr = smack_getprocattr,
@@ -2475,6 +2548,7 @@ static struct security_operations smack_ops = {
.key_permission = smack_key_permission,
#endif /* CONFIG_KEYS */
.secid_to_secctx = smack_secid_to_secctx,
+ .secctx_to_secid = smack_secctx_to_secid,
.release_secctx = smack_release_secctx,
};
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 15aa37f65b3..358c92c1a15 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -24,6 +24,7 @@
#include <net/cipso_ipv4.h>
#include <linux/seq_file.h>
#include <linux/ctype.h>
+#include <linux/audit.h>
#include "smack.h"
/*
@@ -45,6 +46,7 @@ enum smk_inos {
*/
static DEFINE_MUTEX(smack_list_lock);
static DEFINE_MUTEX(smack_cipso_lock);
+static DEFINE_MUTEX(smack_ambient_lock);
/*
* This is the "ambient" label for network traffic.
@@ -342,6 +344,9 @@ void smk_cipso_doi(void)
struct cipso_v4_doi *doip;
struct netlbl_audit audit_info;
+ audit_info.loginuid = audit_get_loginuid(current);
+ audit_info.secid = smack_to_secid(current->security);
+
rc = netlbl_cfg_map_del(NULL, &audit_info);
if (rc != 0)
printk(KERN_WARNING "%s:%d remove rc = %d\n",
@@ -363,6 +368,30 @@ void smk_cipso_doi(void)
__func__, __LINE__, rc);
}
+/**
+ * smk_unlbl_ambient - initialize the unlabeled domain
+ */
+void smk_unlbl_ambient(char *oldambient)
+{
+ int rc;
+ struct netlbl_audit audit_info;
+
+ audit_info.loginuid = audit_get_loginuid(current);
+ audit_info.secid = smack_to_secid(current->security);
+
+ if (oldambient != NULL) {
+ rc = netlbl_cfg_map_del(oldambient, &audit_info);
+ if (rc != 0)
+ printk(KERN_WARNING "%s:%d remove rc = %d\n",
+ __func__, __LINE__, rc);
+ }
+
+ rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info);
+ if (rc != 0)
+ printk(KERN_WARNING "%s:%d add rc = %d\n",
+ __func__, __LINE__, rc);
+}
+
/*
* Seq_file read operations for /smack/cipso
*/
@@ -709,7 +738,6 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
size_t cn, loff_t *ppos)
{
ssize_t rc;
- char out[SMK_LABELLEN];
int asize;
if (*ppos != 0)
@@ -717,23 +745,18 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
/*
* Being careful to avoid a problem in the case where
* smack_net_ambient gets changed in midstream.
- * Since smack_net_ambient is always set with a value
- * from the label list, including initially, and those
- * never get freed, the worst case is that the pointer
- * gets changed just after this strncpy, in which case
- * the value passed up is incorrect. Locking around
- * smack_net_ambient wouldn't be any better than this
- * copy scheme as by the time the caller got to look
- * at the ambient value it would have cleared the lock
- * and been changed.
*/
- strncpy(out, smack_net_ambient, SMK_LABELLEN);
- asize = strlen(out) + 1;
+ mutex_lock(&smack_ambient_lock);
- if (cn < asize)
- return -EINVAL;
+ asize = strlen(smack_net_ambient) + 1;
+
+ if (cn >= asize)
+ rc = simple_read_from_buffer(buf, cn, ppos,
+ smack_net_ambient, asize);
+ else
+ rc = -EINVAL;
- rc = simple_read_from_buffer(buf, cn, ppos, out, asize);
+ mutex_unlock(&smack_ambient_lock);
return rc;
}
@@ -751,6 +774,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
char in[SMK_LABELLEN];
+ char *oldambient;
char *smack;
if (!capable(CAP_MAC_ADMIN))
@@ -766,7 +790,13 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
if (smack == NULL)
return -EINVAL;
+ mutex_lock(&smack_ambient_lock);
+
+ oldambient = smack_net_ambient;
smack_net_ambient = smack;
+ smk_unlbl_ambient(oldambient);
+
+ mutex_unlock(&smack_ambient_lock);
return count;
}
@@ -974,6 +1004,7 @@ static int __init init_smk_fs(void)
sema_init(&smack_write_sem, 1);
smk_cipso_doi();
+ smk_unlbl_ambient(NULL);
return err;
}
diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c
index a7bf7a4b1f8..fb64c890109 100644
--- a/sound/drivers/opl3/opl3_synth.c
+++ b/sound/drivers/opl3/opl3_synth.c
@@ -22,6 +22,10 @@
#include <sound/opl3.h>
#include <sound/asound_fm.h>
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+#define OPL3_SUPPORT_SYNTH
+#endif
+
/*
* There is 18 possible 2 OP voices
* (9 in the left and 9 in the right).
@@ -155,9 +159,11 @@ int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
#endif
return snd_opl3_set_connection(opl3, (int) arg);
+#ifdef OPL3_SUPPORT_SYNTH
case SNDRV_DM_FM_IOCTL_CLEAR_PATCHES:
snd_opl3_clear_patches(opl3);
return 0;
+#endif
#ifdef CONFIG_SND_DEBUG
default:
@@ -178,6 +184,7 @@ int snd_opl3_release(struct snd_hwdep * hw, struct file *file)
return 0;
}
+#ifdef OPL3_SUPPORT_SYNTH
/*
* write the device - load patches
*/
@@ -341,6 +348,7 @@ void snd_opl3_clear_patches(struct snd_opl3 *opl3)
}
memset(opl3->patch_table, 0, sizeof(opl3->patch_table));
}
+#endif /* OPL3_SUPPORT_SYNTH */
/* ------------------------------ */
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index 6304c3a89ba..fe03bb82053 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -277,7 +277,7 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
} else {
snd_sbdsp_command(chip, 256 - runtime->rate_den);
}
- if (chip->capture_format != SB_DSP_OUTPUT) {
+ if (chip->capture_format != SB_DSP_INPUT) {
count--;
snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
snd_sbdsp_command(chip, count & 0xff);
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index c9a2421cf6f..4ecdd635ed1 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -681,15 +681,12 @@ static struct snd_kcontrol_new snd_bt87x_capture_source = {
static int snd_bt87x_free(struct snd_bt87x *chip)
{
- if (chip->mmio) {
+ if (chip->mmio)
snd_bt87x_stop(chip);
- if (chip->irq >= 0)
- synchronize_irq(chip->irq);
-
- iounmap(chip->mmio);
- }
if (chip->irq >= 0)
free_irq(chip->irq, chip);
+ if (chip->mmio)
+ iounmap(chip->mmio);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 26812dc2b7f..37c413923db 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1055,6 +1055,12 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
const char **s;
int err;
+ for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++)
+ ;
+ if (!*s) {
+ snd_printdd("No slave found for %s\n", name);
+ return 0;
+ }
kctl = snd_ctl_make_virtual_master(name, tlv);
if (!kctl)
return -ENOMEM;
@@ -1197,8 +1203,8 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
struct hda_bind_ctls *c;
int err;
- c = (struct hda_bind_ctls *)kcontrol->private_value;
mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ c = (struct hda_bind_ctls *)kcontrol->private_value;
kcontrol->private_value = *c->values;
err = c->ops->info(kcontrol, uinfo);
kcontrol->private_value = (long)c;
@@ -1213,8 +1219,8 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
struct hda_bind_ctls *c;
int err;
- c = (struct hda_bind_ctls *)kcontrol->private_value;
mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ c = (struct hda_bind_ctls *)kcontrol->private_value;
kcontrol->private_value = *c->values;
err = c->ops->get(kcontrol, ucontrol);
kcontrol->private_value = (long)c;
@@ -1230,8 +1236,8 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
unsigned long *vals;
int err = 0, change = 0;
- c = (struct hda_bind_ctls *)kcontrol->private_value;
mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ c = (struct hda_bind_ctls *)kcontrol->private_value;
for (vals = c->values; *vals; vals++) {
kcontrol->private_value = *vals;
err = c->ops->put(kcontrol, ucontrol);
@@ -1251,8 +1257,8 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
struct hda_bind_ctls *c;
int err;
- c = (struct hda_bind_ctls *)kcontrol->private_value;
mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ c = (struct hda_bind_ctls *)kcontrol->private_value;
kcontrol->private_value = *c->values;
err = c->ops->tlv(kcontrol, op_flag, size, tlv);
kcontrol->private_value = (long)c;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 56f8a305075..4be36c84b36 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -275,6 +275,11 @@ enum {
#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
+/* Defines for Intel SCH HDA snoop control */
+#define INTEL_SCH_HDA_DEVC 0x78
+#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11)
+
+
/*
*/
@@ -868,6 +873,8 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg,
static void azx_init_pci(struct azx *chip)
{
+ unsigned short snoop;
+
/* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
* TCSEL == Traffic Class Select Register, which sets PCI express QOS
* Ensuring these bits are 0 clears playback static on some HD Audio
@@ -888,6 +895,19 @@ static void azx_init_pci(struct azx *chip)
NVIDIA_HDA_TRANSREG_ADDR,
0x0f, NVIDIA_HDA_ENABLE_COHBITS);
break;
+ case AZX_DRIVER_SCH:
+ pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
+ if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
+ pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, \
+ snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP));
+ pci_read_config_word(chip->pci,
+ INTEL_SCH_HDA_DEVC, &snoop);
+ snd_printdd("HDA snoop disabled, enabling ... %s\n",\
+ (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) \
+ ? "Failed" : "OK");
+ }
+ break;
+
}
}
@@ -1040,6 +1060,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
static unsigned int azx_max_codecs[] __devinitdata = {
[AZX_DRIVER_ICH] = 3,
+ [AZX_DRIVER_SCH] = 3,
[AZX_DRIVER_ATI] = 4,
[AZX_DRIVER_ATIHDMI] = 4,
[AZX_DRIVER_VIA] = 3, /* FIXME: correct? */
@@ -1797,7 +1818,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
*/
chip->playback_streams = (gcap & (0xF << 12)) >> 12;
chip->capture_streams = (gcap & (0xF << 8)) >> 8;
- chip->playback_index_offset = (gcap & (0xF << 12)) >> 12;
+ chip->playback_index_offset = chip->capture_streams;
chip->capture_index_offset = 0;
} else {
/* gcap didn't give any info, switching to old method */
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 35a630d1770..5633f77f8f3 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -584,7 +584,8 @@ static void print_codec_info(struct snd_info_entry *entry,
print_amp_caps(buffer, codec, nid, HDA_INPUT);
snd_iprintf(buffer, " Amp-In vals: ");
print_amp_vals(buffer, codec, nid, HDA_INPUT,
- wid_caps & AC_WCAP_STEREO, conn_len);
+ wid_caps & AC_WCAP_STEREO,
+ wid_type == AC_WID_PIN ? 1 : conn_len);
}
if (wid_caps & AC_WCAP_OUT_AMP) {
snd_iprintf(buffer, " Amp-Out caps: ");
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 19f08846d6f..c8649282c2c 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1778,9 +1778,9 @@ static hda_nid_t ad1988_capsrc_nids[3] = {
static struct hda_input_mux ad1988_6stack_capture_source = {
.num_items = 5,
.items = {
- { "Front Mic", 0x0 },
- { "Line", 0x1 },
- { "Mic", 0x4 },
+ { "Front Mic", 0x1 }, /* port-B */
+ { "Line", 0x2 }, /* port-C */
+ { "Mic", 0x4 }, /* port-E */
{ "CD", 0x5 },
{ "Mix", 0x9 },
},
@@ -1789,7 +1789,7 @@ static struct hda_input_mux ad1988_6stack_capture_source = {
static struct hda_input_mux ad1988_laptop_capture_source = {
.num_items = 3,
.items = {
- { "Mic/Line", 0x0 },
+ { "Mic/Line", 0x1 }, /* port-B */
{ "CD", 0x5 },
{ "Mix", 0x9 },
},
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index f6dd51cda7b..7206b30cbf9 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -488,7 +488,7 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
static hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
static hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
-#define CXT5045_SPDIF_OUT 0x13
+#define CXT5045_SPDIF_OUT 0x18
static struct hda_channel_mode cxt5045_modes[1] = {
{ 2, NULL },
@@ -658,6 +658,7 @@ static struct hda_verb cxt5045_init_verbs[] = {
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
/* SPDIF route: PCM */
+ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{ 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
/* EAPD */
{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */
@@ -683,6 +684,7 @@ static struct hda_verb cxt5045_benq_init_verbs[] = {
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
/* SPDIF route: PCM */
+ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
/* EAPD */
{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -781,7 +783,8 @@ static struct hda_verb cxt5045_test_init_verbs[] = {
* PCM format, copyright asserted, no pre-emphasis and no validity
* control.
*/
- {0x13, AC_VERB_SET_DIGI_CONVERT_1, 0},
+ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
/* Start with output sum widgets muted and their output gains at min */
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -1227,6 +1230,11 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = {
static struct hda_verb cxt5047_hp_init_verbs[] = {
/* pin sensing on HP jack */
{0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
+ /* 0x13 is actually shared by both HP and speaker;
+ * setting the connection to 0 (=0x19) makes the master volume control
+ * working mysteriouslly...
+ */
+ {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
/* Record selector: Ext Mic */
{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 586d98f1b63..33282f9c01c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -3973,8 +3973,8 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
{ } /* end */
};
@@ -4005,9 +4005,9 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = {
HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
- HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
+ HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
+ HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
@@ -5227,10 +5227,14 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
const struct hda_input_mux *imux = spec->input_mux;
unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
- hda_nid_t nid = capture_mixers[adc_idx];
+ hda_nid_t nid;
unsigned int *cur_val = &spec->cur_mux[adc_idx];
unsigned int i, idx;
+ if (spec->num_adc_nids < 3)
+ nid = capture_mixers[adc_idx + 1];
+ else
+ nid = capture_mixers[adc_idx];
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
@@ -6457,7 +6461,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
struct alc_spec *spec = codec->spec;
const struct hda_input_mux *imux = spec->input_mux;
unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
+ static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
hda_nid_t nid = capture_mixers[adc_idx];
unsigned int *cur_val = &spec->cur_mux[adc_idx];
unsigned int i, idx;
@@ -7635,6 +7639,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
+ SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
{}
@@ -8098,7 +8103,7 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
+ HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
@@ -8120,7 +8125,7 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
+ HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
{ } /* end */
@@ -9234,6 +9239,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
+ SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
@@ -12989,8 +12995,8 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -13003,8 +13009,8 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
};
static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
- HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index 9ab4a9f383c..5a158b73dca 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -51,7 +51,7 @@
struct phase28_spec {
unsigned short master[2];
unsigned short vol[8];
-} phase28;
+};
/* WM8770 registers */
#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index ddd5fc8d4fe..301bf929acd 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -36,7 +36,7 @@
struct revo51_spec {
struct snd_i2c_device *dev;
struct snd_pt2258 *pt2258;
-} revo51;
+};
static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
{
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 061072c7db0..c52abd0bf22 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1708,6 +1708,12 @@ static struct ac97_pcm ac97_pcm_defs[] __devinitdata = {
};
static struct ac97_quirk ac97_quirks[] __devinitdata = {
+ {
+ .subvendor = 0x0e11,
+ .subdevice = 0x000e,
+ .name = "Compaq Deskpro EN", /* AD1885 */
+ .type = AC97_TUNE_HP_ONLY
+ },
{
.subvendor = 0x0e11,
.subdevice = 0x008a,
@@ -1740,6 +1746,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
},
{
.subvendor = 0x1025,
+ .subdevice = 0x0082,
+ .name = "Acer Travelmate 2310",
+ .type = AC97_TUNE_HP_ONLY
+ },
+ {
+ .subvendor = 0x1025,
.subdevice = 0x0083,
.name = "Acer Aspire 3003LCi",
.type = AC97_TUNE_HP_ONLY
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index 3ea1f05228a..666f69a3312 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -150,6 +150,7 @@ static const struct oxygen_model model_hifier = {
.shortname = "C-Media CMI8787",
.longname = "C-Media Oxygen HD Audio",
.chip = "CMI8788",
+ .owner = THIS_MODULE,
.init = hifier_init,
.control_filter = hifier_control_filter,
.mixer_init = hifier_mixer_init,
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index f31a0eb409b..9a9941bb046 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -28,7 +28,9 @@
* GPIO 1 -> DFS1 of AK5385
*/
+#include <linux/mutex.h>
#include <linux/pci.h>
+#include <sound/ac97_codec.h>
#include <sound/control.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -37,6 +39,7 @@
#include <sound/tlv.h>
#include "oxygen.h"
#include "ak4396.h"
+#include "cm9780.h"
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_DESCRIPTION("C-Media CMI8788 driver");
@@ -75,6 +78,8 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
#define GPIO_AK5385_DFS_DOUBLE 0x0001
#define GPIO_AK5385_DFS_QUAD 0x0002
+#define GPIO_LINE_MUTE CM9780_GPO0
+
#define WM8785_R0 0
#define WM8785_R1 1
#define WM8785_R2 2
@@ -180,16 +185,23 @@ static void wm8785_init(struct oxygen *chip)
snd_component_add(chip->card, "WM8785");
}
+static void cmi9780_init(struct oxygen *chip)
+{
+ oxygen_ac97_clear_bits(chip, 0, CM9780_GPIO_STATUS, GPIO_LINE_MUTE);
+}
+
static void generic_init(struct oxygen *chip)
{
ak4396_init(chip);
wm8785_init(chip);
+ cmi9780_init(chip);
}
static void meridian_init(struct oxygen *chip)
{
ak4396_init(chip);
ak5385_init(chip);
+ cmi9780_init(chip);
}
static void generic_cleanup(struct oxygen *chip)
@@ -285,6 +297,27 @@ static void set_ak5385_params(struct oxygen *chip,
value, GPIO_AK5385_DFS_MASK);
}
+static void cmi9780_switch_hook(struct oxygen *chip, unsigned int codec,
+ unsigned int reg, int mute)
+{
+ if (codec != 0)
+ return;
+ switch (reg) {
+ case AC97_LINE:
+ oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
+ mute ? GPIO_LINE_MUTE : 0,
+ GPIO_LINE_MUTE);
+ break;
+ case AC97_MIC:
+ case AC97_CD:
+ case AC97_AUX:
+ if (!mute)
+ oxygen_ac97_set_bits(chip, 0, CM9780_GPIO_STATUS,
+ GPIO_LINE_MUTE);
+ break;
+ }
+}
+
static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
static int ak4396_control_filter(struct snd_kcontrol_new *template)
@@ -308,6 +341,7 @@ static const struct oxygen_model model_generic = {
.set_adc_params = set_wm8785_params,
.update_dac_volume = update_ak4396_volume,
.update_dac_mute = update_ak4396_mute,
+ .ac97_switch_hook = cmi9780_switch_hook,
.model_data_size = sizeof(struct generic_data),
.dac_channels = 8,
.used_channels = OXYGEN_CHANNEL_A |
@@ -331,6 +365,7 @@ static const struct oxygen_model model_meridian = {
.set_adc_params = set_ak5385_params,
.update_dac_volume = update_ak4396_volume,
.update_dac_mute = update_ak4396_mute,
+ .ac97_switch_hook = cmi9780_switch_hook,
.model_data_size = sizeof(struct generic_data),
.dac_channels = 8,
.used_channels = OXYGEN_CHANNEL_B |
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 6eb36dd1147..78c21155218 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -204,7 +204,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
mutex_unlock(&chip->mutex);
}
-static void __devinit oxygen_proc_init(struct oxygen *chip)
+static void oxygen_proc_init(struct oxygen *chip)
{
struct snd_info_entry *entry;
@@ -215,7 +215,7 @@ static void __devinit oxygen_proc_init(struct oxygen *chip)
#define oxygen_proc_init(chip)
#endif
-static void __devinit oxygen_init(struct oxygen *chip)
+static void oxygen_init(struct oxygen *chip)
{
unsigned int i;
@@ -399,8 +399,8 @@ static void oxygen_card_free(struct snd_card *card)
pci_disable_device(chip->pci);
}
-int __devinit oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
- int midi, const struct oxygen_model *model)
+int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
+ int midi, const struct oxygen_model *model)
{
struct snd_card *card;
struct oxygen *chip;
@@ -507,7 +507,7 @@ err_card:
}
EXPORT_SYMBOL(oxygen_pci_probe);
-void __devexit oxygen_pci_remove(struct pci_dev *pci)
+void oxygen_pci_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
pci_set_drvdata(pci, NULL);
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index dfad3db35c8..b70046aca65 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -634,7 +634,7 @@ static void oxygen_pcm_free(struct snd_pcm *pcm)
snd_pcm_lib_preallocate_free_for_all(pcm);
}
-int __devinit oxygen_pcm_init(struct oxygen *chip)
+int oxygen_pcm_init(struct oxygen *chip)
{
struct snd_pcm *pcm;
int outs, ins;
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 40e92f5cd69..d163397b85c 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -389,6 +389,7 @@ static const struct oxygen_model model_xonar = {
.shortname = "Asus AV200",
.longname = "Asus Virtuoso 200",
.chip = "AV200",
+ .owner = THIS_MODULE,
.init = xonar_init,
.control_filter = xonar_control_filter,
.mixer_init = xonar_mixer_init,
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index c2bd4384316..1be84f22d0d 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -745,7 +745,7 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
#ifdef HDSP_FW_LOADER
-static int __devinit hdsp_request_fw_loader(struct hdsp *hdsp);
+static int hdsp_request_fw_loader(struct hdsp *hdsp);
#endif
static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand)
@@ -4688,8 +4688,7 @@ static struct snd_pcm_ops snd_hdsp_capture_ops = {
.copy = snd_hdsp_capture_copy,
};
-static int __devinit snd_hdsp_create_hwdep(struct snd_card *card,
- struct hdsp *hdsp)
+static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp)
{
struct snd_hwdep *hw;
int err;
@@ -4857,7 +4856,7 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp
#ifdef HDSP_FW_LOADER
/* load firmware via hotplug fw loader */
-static int __devinit hdsp_request_fw_loader(struct hdsp *hdsp)
+static int hdsp_request_fw_loader(struct hdsp *hdsp)
{
const char *fwfile;
const struct firmware *fw;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 710e0287ef8..569ecaca0e8 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -681,8 +681,8 @@ static const struct aic3x_rate_divs aic3x_divs[] = {
{22579200, 48000, 48000, 0x0, 8, 7075},
{33868800, 48000, 48000, 0x0, 5, 8049},
/* 64k */
- {22579200, 96000, 96000, 0x1, 8, 7075},
- {33868800, 96000, 96000, 0x1, 5, 8049},
+ {22579200, 64000, 96000, 0x1, 8, 7075},
+ {33868800, 64000, 96000, 0x1, 5, 8049},
/* 88.2k */
{22579200, 88200, 88200, 0x0, 8, 0},
{33868800, 88200, 88200, 0x0, 5, 3333},
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 590baea3c4c..524f7450804 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -176,7 +176,8 @@ static int wm9712_add_controls(struct snd_soc_codec *codec)
* the codec only has a single control that is shared by both channels.
* This makes it impossible to determine the audio path.
*/
-static int mixer_event (struct snd_soc_dapm_widget *w, int event)
+static int mixer_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
{
u16 l, r, beep, line, phone, mic, pcm, aux;
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index f26c4b2e8b6..a00aac7a71f 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -315,7 +315,7 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J;
machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "rj-master") == 0) {
+ } else if (strcasecmp(sprop, "rj-slave") == 0) {
machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J;
machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 3f34e531beb..1a70a6ac98c 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -215,7 +215,8 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol,
return 1;
}
-static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
+static int corgi_amp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
{
if (SND_SOC_DAPM_EVENT_ON(event))
set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
@@ -225,7 +226,8 @@ static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
return 0;
}
-static int corgi_mic_event(struct snd_soc_dapm_widget *w, int event)
+static int corgi_mic_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
{
if (SND_SOC_DAPM_EVENT_ON(event))
set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 5ae59bd309a..4fbf8bba962 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -196,7 +196,8 @@ static int poodle_set_spk(struct snd_kcontrol *kcontrol,
return 1;
}
-static int poodle_amp_event(struct snd_soc_dapm_widget *w, int event)
+static int poodle_amp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
{
if (SND_SOC_DAPM_EVENT_ON(event))
locomo_gpio_write(&poodle_locomo_device.dev,
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index d56709e1543..ecca39033fc 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -215,7 +215,8 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol,
return 1;
}
-static int spitz_mic_bias(struct snd_soc_dapm_widget *w, int event)
+static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
{
if (machine_is_borzoi() || machine_is_spitz()) {
if (SND_SOC_DAPM_EVENT_ON(event))
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index e4d40b528ca..7346d7e5d06 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -135,7 +135,8 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol,
}
/* tosa dapm event handlers */
-static int tosa_hp_event(struct snd_soc_dapm_widget *w, int event)
+static int tosa_hp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
{
if (SND_SOC_DAPM_EVENT_ON(event))
set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE);
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
index 58d25e4e7d6..7c44a2c7f96 100644
--- a/sound/usb/caiaq/caiaq-device.c
+++ b/sound/usb/caiaq/caiaq-device.c
@@ -245,7 +245,7 @@ int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev,
tmp, sizeof(tmp));
}
-static void setup_card(struct snd_usb_caiaqdev *dev)
+static void __devinit setup_card(struct snd_usb_caiaqdev *dev)
{
int ret;
char val[4];
@@ -359,7 +359,7 @@ static struct snd_card* create_card(struct usb_device* usb_dev)
return card;
}
-static int init_card(struct snd_usb_caiaqdev *dev)
+static int __devinit init_card(struct snd_usb_caiaqdev *dev)
{
char *c;
struct usb_device *usb_dev = dev->chip.dev;
@@ -428,7 +428,7 @@ static int init_card(struct snd_usb_caiaqdev *dev)
return 0;
}
-static int snd_probe(struct usb_interface *intf,
+static int __devinit snd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
int ret;
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 8fa93566570..675672f313b 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -479,6 +479,33 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
return 0;
}
+/*
+ * process after E-Mu 0202/0404 high speed playback sync complete
+ *
+ * These devices return the number of samples per packet instead of the number
+ * of samples per microframe.
+ */
+static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs,
+ struct snd_pcm_runtime *runtime,
+ struct urb *urb)
+{
+ unsigned int f;
+ unsigned long flags;
+
+ if (urb->iso_frame_desc[0].status == 0 &&
+ urb->iso_frame_desc[0].actual_length == 4) {
+ f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
+ f >>= subs->datainterval;
+ if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
+ spin_lock_irqsave(&subs->lock, flags);
+ subs->freqm = f;
+ spin_unlock_irqrestore(&subs->lock, flags);
+ }
+ }
+
+ return 0;
+}
+
/* determine the number of frames in the next packet */
static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
{
@@ -2219,10 +2246,17 @@ static void init_substream(struct snd_usb_stream *as, int stream, struct audiofo
subs->stream = as;
subs->direction = stream;
subs->dev = as->chip->dev;
- if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
+ if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
subs->ops = audio_urb_ops[stream];
- else
+ } else {
subs->ops = audio_urb_ops_high_speed[stream];
+ switch (as->chip->usb_id) {
+ case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
+ case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
+ subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
+ break;
+ }
+ }
snd_pcm_set_ops(as->pcm, stream,
stream == SNDRV_PCM_STREAM_PLAYBACK ?
&snd_usb_playback_ops : &snd_usb_capture_ops);
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 750e929d587..6676a177c99 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -104,12 +104,14 @@ struct snd_usb_midi {
struct usb_protocol_ops* usb_protocol_ops;
struct list_head list;
struct timer_list error_timer;
+ spinlock_t disc_lock;
struct snd_usb_midi_endpoint {
struct snd_usb_midi_out_endpoint *out;
struct snd_usb_midi_in_endpoint *in;
} endpoints[MIDI_MAX_ENDPOINTS];
unsigned long input_triggered;
+ unsigned char disconnected;
};
struct snd_usb_midi_out_endpoint {
@@ -306,6 +308,11 @@ static void snd_usbmidi_error_timer(unsigned long data)
struct snd_usb_midi *umidi = (struct snd_usb_midi *)data;
int i;
+ spin_lock(&umidi->disc_lock);
+ if (umidi->disconnected) {
+ spin_unlock(&umidi->disc_lock);
+ return;
+ }
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
struct snd_usb_midi_in_endpoint *in = umidi->endpoints[i].in;
if (in && in->error_resubmit) {
@@ -316,6 +323,7 @@ static void snd_usbmidi_error_timer(unsigned long data)
if (umidi->endpoints[i].out)
snd_usbmidi_do_output(umidi->endpoints[i].out);
}
+ spin_unlock(&umidi->disc_lock);
}
/* helper function to send static data that may not DMA-able */
@@ -1049,7 +1057,14 @@ void snd_usbmidi_disconnect(struct list_head* p)
int i;
umidi = list_entry(p, struct snd_usb_midi, list);
- del_timer_sync(&umidi->error_timer);
+ /*
+ * an URB's completion handler may start the timer and
+ * a timer may submit an URB. To reliably break the cycle
+ * a flag under lock must be used
+ */
+ spin_lock_irq(&umidi->disc_lock);
+ umidi->disconnected = 1;
+ spin_unlock_irq(&umidi->disc_lock);
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
if (ep->out)
@@ -1062,6 +1077,7 @@ void snd_usbmidi_disconnect(struct list_head* p)
if (ep->in)
usb_kill_urb(ep->in->urb);
}
+ del_timer_sync(&umidi->error_timer);
}
static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi)
@@ -1685,6 +1701,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
umidi->quirk = quirk;
umidi->usb_protocol_ops = &snd_usbmidi_standard_ops;
init_timer(&umidi->error_timer);
+ spin_lock_init(&umidi->disc_lock);
umidi->error_timer.function = snd_usbmidi_error_timer;
umidi->error_timer.data = (unsigned long)umidi;
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 317f8e211cd..4232fd75dd2 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -211,6 +211,10 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
case IOAPIC_LOWEST_PRIORITY:
vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, vector,
deliver_bitmask);
+#ifdef CONFIG_X86
+ if (irq == 0)
+ vcpu = ioapic->kvm->vcpus[0];
+#endif
if (vcpu != NULL)
ioapic_inj_irq(ioapic, vcpu, vector,
trig_mode, delivery_mode);
@@ -220,6 +224,10 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
deliver_bitmask, vector, IOAPIC_LOWEST_PRIORITY);
break;
case IOAPIC_FIXED:
+#ifdef CONFIG_X86
+ if (irq == 0)
+ deliver_bitmask = 1;
+#endif
for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) {
if (!(deliver_bitmask & (1 << vcpu_id)))
continue;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 32fbf800696..b2e12893e3f 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -169,6 +169,7 @@ static struct kvm *kvm_create_vm(void)
kvm_io_bus_init(&kvm->pio_bus);
mutex_init(&kvm->lock);
kvm_io_bus_init(&kvm->mmio_bus);
+ init_rwsem(&kvm->slots_lock);
spin_lock(&kvm_lock);
list_add(&kvm->vm_list, &vm_list);
spin_unlock(&kvm_lock);
@@ -339,9 +340,9 @@ int kvm_set_memory_region(struct kvm *kvm,
{
int r;
- down_write(&current->mm->mmap_sem);
+ down_write(&kvm->slots_lock);
r = __kvm_set_memory_region(kvm, mem, user_alloc);
- up_write(&current->mm->mmap_sem);
+ up_write(&kvm->slots_lock);
return r;
}
EXPORT_SYMBOL_GPL(kvm_set_memory_region);